diff --git a/.github/dev_bug_report.md b/.github/dev_bug_report.md
new file mode 100755
index 0000000..ef93e56
--- /dev/null
+++ b/.github/dev_bug_report.md
@@ -0,0 +1,35 @@
+---
+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.
diff --git a/.github/dev_feature_request.md b/.github/dev_feature_request.md
new file mode 100755
index 0000000..9573c35
--- /dev/null
+++ b/.github/dev_feature_request.md
@@ -0,0 +1,18 @@
+---
+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.
diff --git a/.github/user_bug_report.md b/.github/user_bug_report.md
new file mode 100755
index 0000000..df09513
--- /dev/null
+++ b/.github/user_bug_report.md
@@ -0,0 +1,34 @@
+---
+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]
+ - Orange Management Version [e.g. 22]
+
+# Additional Information
+Add any other context about the problem here.
diff --git a/.github/user_feature_request.md b/.github/user_feature_request.md
new file mode 100755
index 0000000..6eb8ddc
--- /dev/null
+++ b/.github/user_feature_request.md
@@ -0,0 +1,18 @@
+---
+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.
diff --git a/.github/workflows/greetings.yml b/.github/workflows/greetings.yml
new file mode 100755
index 0000000..adb8716
--- /dev/null
+++ b/.github/workflows/greetings.yml
@@ -0,0 +1,13 @@
+name: Greetings
+
+on: [pull_request, issues]
+
+jobs:
+ greeting:
+ runs-on: ubuntu-latest
+ steps:
+ - uses: actions/first-interaction@v1
+ with:
+ repo-token: ${{ secrets.GITHUB_TOKEN }}
+ issue-message: 'Thank you for createing this issue. We will check it as soon as possible.'
+ pr-message: 'Thank you for your pull request. We will check it as soon as possible.'
diff --git a/.github/workflows/image.yml b/.github/workflows/image.yml
new file mode 100755
index 0000000..d2fb2d4
--- /dev/null
+++ b/.github/workflows/image.yml
@@ -0,0 +1,24 @@
+name: Compress images
+on:
+ push:
+ paths:
+ - '**.jpg'
+ - '**.png'
+ - '**.webp'
+ pull_request:
+ paths:
+ - '**.jpg'
+ - '**.png'
+ - '**.webp'
+jobs:
+ build:
+ name: calibreapp/image-actions
+ runs-on: ubuntu-latest
+ steps:
+ - name: Checkout Repo
+ uses: actions/checkout@master
+
+ - name: Compress Images
+ uses: calibreapp/image-actions@master
+ with:
+ githubToken: ${{ secrets.GITHUB_TOKEN }}
\ No newline at end of file
diff --git a/.github/workflows/main.yml b/.github/workflows/main.yml
new file mode 100755
index 0000000..295f795
--- /dev/null
+++ b/.github/workflows/main.yml
@@ -0,0 +1,172 @@
+name: CI/CD
+
+on: [push]
+
+jobs:
+ autoformat:
+ runs-on: ubuntu-latest
+ if: "!contains(github.event.head_commit.message, 'NO_CI')"
+ strategy:
+ fail-fast: false
+ max-parallel: 3
+ steps:
+ - name: Checkout Repository
+ uses: actions/checkout@master
+ with:
+ fetch-depth: 1
+ - name: Get Composer Cache Directory
+ id: composer-cache
+ run: echo "::set-output name=dir::$(composer config cache-files-dir)"
+ - name: Cache dependencies
+ uses: actions/cache@v1
+ with:
+ path: ${{ steps.composer-cache.outputs.dir }}
+ key: ${{ runner.os }}-composer-${{ hashFiles('**/composer.lock') }}
+ restore-keys: ${{ runner.os }}-composer-
+ - name: Setup Composer
+ run: composer install
+ - name: Autoformat
+ run: 'vendor/bin/php-cs-fixer fix ./ --rules=''{"array_syntax": {"syntax": "short"}, "blank_line_after_namespace": true, "binary_operator_spaces": {"operators": {"=": "align", ".=": "align", "+=": "align", "-=": "align", "*=": "align", "/=": "align", "|=": "align", "&=": "align", "=>": "align", "??=": "align"}}, "cast_spaces": {"space": "single"}, "class_attributes_separation": { "elements": ["const", "method", "property"] }, "combine_consecutive_issets": true, "compact_nullable_typehint": true, "declare_strict_types": true, "declare_equal_normalize": {"space": "none"}, "elseif": true, "encoding": true, "explicit_indirect_variable": true, "explicit_string_variable": true, "function_to_constant": true, "implode_call": true, "increment_style": {"style": "pre"}, "is_null": {"use_yoda_style": false}, "line_ending": true, "logical_operators": true, "lowercase_cast": true, "lowercase_constants": true, "lowercase_keywords": true, "modernize_types_casting": true, "native_constant_invocation": true, "native_function_casing": true, "native_function_invocation": true, "new_with_braces": true, "no_extra_blank_lines": ["break", "case", "continue", "curly_brace_block", "extra", "return", "switch", "throw", "use"], "no_spaces_after_function_name": true, "no_alias_functions": true, "no_closing_tag": true, "no_empty_comment": true, "no_empty_phpdoc": true, "no_empty_statement": true, "no_homoglyph_names": true, "no_mixed_echo_print": {"use": "echo"}, "no_php4_constructor": true, "no_singleline_whitespace_before_semicolons": true, "no_spaces_inside_parenthesis": true, "no_trailing_whitespace": true, "no_unneeded_final_method": true, "no_unused_imports": true, "no_useless_return": true, "no_whitespace_before_comma_in_array": true, "no_whitespace_in_blank_line": true, "non_printable_character": true, "normalize_index_brace": true, "ordered_imports": {"sort_algorithm": "alpha"}, "ordered_interfaces": {"order": "alpha"}, "php_unit_construct": true, "php_unit_internal_class": true, "php_unit_ordered_covers": true, "php_unit_set_up_tear_down_visibility": true, "phpdoc_indent": true, "phpdoc_align": {"align": "vertical"}, "phpdoc_annotation_without_dot": true, "phpdoc_scalar": true, "phpdoc_return_self_reference": {"this": "self"}, "phpdoc_trim": true, "phpdoc_trim_consecutive_blank_line_separation": true, "random_api_migration": true, "self_accessor": true, "return_type_declaration": {"space_before": "one"}, "semicolon_after_instruction": true, "set_type_to_cast": true, "short_scalar_cast": true, "single_blank_line_at_eof": true, "single_line_after_imports": true, "standardize_increment": true, "trailing_comma_in_multiline_array": true, "trim_array_spaces": true, "visibility_required": true, "void_return": true}'' --allow-risky=yes'
+ - name: Check for modified files
+ id: git-check
+ run: echo ::set-output name=modified::$(if git diff-index --quiet HEAD --; then echo "false"; else echo "true"; fi)
+ - name: Push changes
+ if: steps.git-check.outputs.modified == 'true'
+ run: |
+ git config --global user.name 'Formatter Bot'
+ git config --global user.email 'formatter.bot@orange-management.email'
+ git remote set-url origin https://x-access-token:${{ secrets.GITHUB_TOKEN }}@github.com/${{ github.repository }}
+ git commit -am "Automated formatting changes"
+ git push
+ code-tests:
+ runs-on: ubuntu-latest
+ if: "!contains(github.event.head_commit.message, 'NO_CI')"
+ services:
+ mysql:
+ image: mysql:5.7
+ env:
+ MYSQL_ALLOW_EMPTY_PASSWORD: false
+ MYSQL_ROOT_PASSWORD: root
+ MYSQL_DATABASE: oms
+ ports:
+ - 3306:3306
+ options: --health-cmd="mysqladmin ping" --health-interval=10s --health-timeout=5s --health-retries=3
+ postgres:
+ image: postgres:10.8
+ env:
+ POSTGRES_USER: postgres
+ POSTGRES_PASSWORD: root
+ POSTGRES_DB: oms
+ ports:
+ - 5432:5432
+ options: --health-cmd pg_isready --health-interval 10s --health-timeout 5s --health-retries 3
+ redis:
+ image: redis
+ ports:
+ - 6379:6379
+ options: --entrypoint redis-server
+ memcached:
+ image: memcached
+ ports:
+ - 11211:11211
+ strategy:
+ fail-fast: false
+ max-parallel: 3
+ matrix:
+ php-versions: ['8.0']
+ steps:
+ - name: Checkout Repository
+ uses: actions/checkout@master
+ with:
+ fetch-depth: 1
+ - name: Checkout Build Repository
+ uses: actions/checkout@master
+ with:
+ fetch-depth: 1
+ ref: develop
+ repository: Orange-Management/Build
+ path: Build
+ - name: Checkout Resource Repository
+ uses: actions/checkout@master
+ with:
+ fetch-depth: 1
+ ref: develop
+ repository: Orange-Management/Resources
+ path: Resources
+ - name: Checkout phpOMS Repository
+ uses: actions/checkout@master
+ with:
+ fetch-depth: 1
+ ref: develop
+ repository: Orange-Management/phpOMS
+ path: phpOMS
+ - name: Checkout Orange-Management Repository
+ uses: actions/checkout@master
+ with:
+ fetch-depth: 1
+ ref: develop
+ repository: Orange-Management/Orange-Management
+ path: Orange-Management
+ - name: Setup PHP, with composer and extensions
+ uses: shivammathur/setup-php@master
+ with:
+ php-version: ${{ matrix.php-versions }}
+ extensions: mbstring, gd, zip, dom, mysql, pgsql, sqlite, imap, bcmath, redis, memcached
+ ini-values: opcache.jit_buffer_size=256M, opcache.jit=1235, pcre.jit=1
+ coverage: pcov
+ - name: Get Composer Cache Directory
+ id: composer-cache
+ run: echo "::set-output name=dir::$(composer config cache-files-dir)"
+ - name: Cache dependencies
+ uses: actions/cache@v1
+ with:
+ path: ${{ steps.composer-cache.outputs.dir }}
+ key: ${{ runner.os }}-composer-${{ hashFiles('**/composer.lock') }}
+ restore-keys: ${{ runner.os }}-composer-
+ - name: Setup Composer
+ run: composer install
+ - name: phpunit
+ run: vendor/bin/phpunit --coverage-clover tests/coverage.xml --configuration tests/phpunit_default.xml
+ - name: codecov
+ env:
+ CODECOV_TOKEN: "${{ secrets.CODECOV_TOKEN }}"
+ run: "bash <(curl -s https://codecov.io/bash) -f tests/coverage.xml"
+ custom:
+ runs-on: ubuntu-latest
+ if: "!contains(github.event.head_commit.message, 'NO_CI')"
+ strategy:
+ fail-fast: false
+ max-parallel: 3
+ matrix:
+ php-versions: ['8.0']
+ steps:
+ - name: Checkout Repository
+ uses: actions/checkout@master
+ with:
+ fetch-depth: 1
+ - name: Checkout Build Repository
+ uses: actions/checkout@master
+ with:
+ fetch-depth: 1
+ ref: develop
+ repository: Orange-Management/Build
+ path: Build
+ - name: Setup PHP, with composer and extensions
+ uses: shivammathur/setup-php@master
+ with:
+ php-version: ${{ matrix.php-versions }}
+ extensions: mbstring, gd, zip, dom, mysql, pgsql, sqlite, imap, bcmath, redis, memcached
+ ini-values: opcache.jit_buffer_size=256M, opcache.jit=1235, pcre.jit=1
+ - name: PHP linting
+ run: find ./ -type f -name '*.php' -print0 | xargs -0 -n1 -P4 php -l -n | (! grep -v "No syntax errors detected" )
+ - name: Php strict
+ run: if [[ $(grep -r -L "declare(strict_types=1);" --include=*.php --exclude={*.tpl.php,*Hooks.php,*Routes.php,*SearchCommands.php} ./) -ne "" ]]; then exit 1; fi
+ - name: Html inspection
+ run: |
+ if [[ $(find ./ -name "*tpl.php" | xargs grep -E '=\"[\#\$\%\^\&\*\(\)\\/\ ]*\"') -ne "" ]]; then exit 1; fi
+ if [[ $(find ./ -name "*tpl.php" | xargs grep -P '(\
)') -ne "" ]]; then exit 1; fi
+ - name: Js strict
+ run: if [[ $(grep -r -L "\"use strict\";" --include=*.js ./) -ne "" ]]; then exit 1; fi
+ - name: Js inspection
+ run: |
+ if [[ $(grep -rlni "onafterprint=\|onbeforeprint=\|onbeforeunload=\|onerror=\|onhaschange=\|onload=\|onmessage=\|onoffline=\|ononline=\|onpagehide=\|onpageshow=\|onpopstate=\|onredo=\|onresize=\|onstorage=\|onund=o\|onunload=\|onblur=\|onchage=\|oncontextmenu=\|onfocus=\|onformchange=\|onforminput=\|oninput=\|oninvalid=\|onreset=\|onselect=\|onsubmit=\|onkeydown=\|onkeypress=\|onkeyup=\|onclick=\|ondblclic=k\|ondrag=\|ondragend=\|ondragenter=\|ondragleave=\|ondragover=\|ondragstart=\|ondrop=\|onmousedown=\|onmousemove=\|onmouseout=\|onmouseover=\|onmouseup=\|onmousewheel=\|onscroll=\|onabor=t\|oncanplay=\|oncanplaythrough=\|ondurationchange=\|onemptied=\|onended=\|onerror=\|onloadeddata=\|onloadedmetadata=\|onloadstart=\|onpause=\|onplay=\|onplaying=\|onprogress=\|onratechange=\|onreadystatechange=\|onseeked=\|onseeking=\|onstalled=\|onsuspend=\|ontimeupdate=\|onvolumechange=" --include=*.js ./) -ne "" ]]; then exit 1; fi
diff --git a/.gitignore b/.gitignore
new file mode 100644
index 0000000..22d0d82
--- /dev/null
+++ b/.gitignore
@@ -0,0 +1 @@
+vendor
diff --git a/Admin/Install/db.json b/Admin/Install/db.json
new file mode 100644
index 0000000..e683232
--- /dev/null
+++ b/Admin/Install/db.json
@@ -0,0 +1,360 @@
+{
+ "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": "VARCHAR(255)",
+ "null": false
+ },
+ "warehousemgmt_item_track_type": {
+ "name": "warehousemgmt_item_track_type",
+ "type": "TINYINT",
+ "null": false
+ },
+ "warehousemgmt_item_negative": {
+ "name": "warehousemgmt_item_negative",
+ "type": "TINYINT",
+ "null": false
+ },
+ "warehousemgmt_item_": {
+ "name": "warehousemgmt_item_",
+ "type": "TINYINT",
+ "null": false
+ }
+ }
+ },
+ "warehousemgmt_stock": {
+ "name": "warehousemgmt_stock",
+ "fields": {
+ "warehousemgmt_stock_id": {
+ "name": "warehousemgmt_stock_id",
+ "type": "INT",
+ "null": false,
+ "primary": true,
+ "autoincrement": true
+ },
+ "warehousemgmt_stock_name": {
+ "name": "warehousemgmt_stock_name",
+ "type": "VARCHAR(255)",
+ "null": false
+ },
+ "warehousemgmt_stock_type": {
+ "description": "???",
+ "name": "warehousemgmt_stock_type",
+ "type": "TINYINT",
+ "null": false
+ }
+ }
+ },
+ "warehousemgmt_stocklocation": {
+ "name": "warehousemgmt_stocklocation",
+ "fields": {
+ "warehousemgmt_stocklocation_id": {
+ "name": "warehousemgmt_stocklocation_id",
+ "type": "INT",
+ "null": false,
+ "primary": true,
+ "autoincrement": true
+ },
+ "warehousemgmt_stocklocation_name": {
+ "name": "warehousemgmt_stocklocation_name",
+ "type": "VARCHAR(255)",
+ "null": false
+ },
+ "warehousemgmt_stocklocation_stock": {
+ "name": "warehousemgmt_stocklocation_stock",
+ "type": "INT",
+ "null": false,
+ "foreignTable": "warehousemgmt_stock",
+ "foreignKey": "warehousemgmt_stock_id"
+ },
+ "warehousemgmt_stocklocation_x": {
+ "name": "warehousemgmt_stocklocation_x",
+ "type": "INT",
+ "null": false
+ },
+ "warehousemgmt_stocklocation_y": {
+ "name": "warehousemgmt_stocklocation_y",
+ "type": "INT",
+ "null": false
+ },
+ "warehousemgmt_stocklocation_z": {
+ "description": "Height",
+ "name": "warehousemgmt_stocklocation_z",
+ "type": "INT",
+ "null": false
+ }
+ }
+ },
+ "warehousemgmt_lot": {
+ "name": "warehousemgmt_lot",
+ "fields": {
+ "warehousemgmt_lot_id": {
+ "name": "warehousemgmt_lot_id",
+ "type": "INT",
+ "null": false,
+ "primary": true,
+ "autoincrement": true
+ },
+ "warehousemgmt_lot_item": {
+ "name": "warehousemgmt_lot_item",
+ "type": "INT",
+ "null": false,
+ "foreignTable": "itemmgmt_item",
+ "foreignKey": "itemmgmt_item_id"
+ },
+ "warehousemgmt_lot_purchase_price": {
+ "name": "warehousemgmt_lot_purchase_price",
+ "type": "INT",
+ "null": false
+ },
+ "warehousemgmt_lot_internal": {
+ "name": "warehousemgmt_lot_internal",
+ "type": "VARCHAR(255)",
+ "null": false
+ },
+ "warehousemgmt_lot_external": {
+ "name": "warehousemgmt_lot_external",
+ "type": "VARCHAR(255)",
+ "null": true,
+ "default": null
+ },
+ "warehousemgmt_lot_type": {
+ "name": "warehousemgmt_lot_type",
+ "type": "TINYINT",
+ "null": false
+ },
+ "warehousemgmt_lot_expiration": {
+ "name": "warehousemgmt_lot_expiration",
+ "type": "DATETIME",
+ "null": true,
+ "default": null
+ }
+ }
+ },
+ "warehousemgmt_lot_media": {
+ "name": "warehousemgmt_lot_media",
+ "fields": {
+ "warehousemgmt_lot_media_id": {
+ "name": "warehousemgmt_lot_media_id",
+ "type": "INT",
+ "null": false,
+ "primary": true,
+ "autoincrement": true
+ },
+ "warehousemgmt_lot_media_lot": {
+ "name": "warehousemgmt_lot_media_lot",
+ "type": "INT",
+ "null": false,
+ "foreignTable": "warehousemgmt_lot",
+ "foreignKey": "warehousemgmt_lot_id"
+ },
+ "warehousemgmt_lot_media_media": {
+ "name": "warehousemgmt_lot_media_media",
+ "type": "INT",
+ "null": false,
+ "foreignTable": "media",
+ "foreignKey": "media_id"
+ }
+ }
+ },
+ "warehousemgmt_lot_status": {
+ "name": "warehousemgmt_lot_status",
+ "fields": {
+ "warehousemgmt_lot_status_id": {
+ "name": "warehousemgmt_lot_status_id",
+ "type": "INT",
+ "null": false,
+ "primary": true,
+ "autoincrement": true
+ },
+ "warehousemgmt_lot_status_name": {
+ "name": "warehousemgmt_lot_status_lot",
+ "type": "VARCHAR(255)",
+ "null": false
+ }
+ }
+ },
+ "warehousemgmt_lot_status_lot": {
+ "name": "warehousemgmt_lot_status_lot",
+ "fields": {
+ "warehousemgmt_lot_status_lot_id": {
+ "name": "warehousemgmt_lot_status_lot_id",
+ "type": "INT",
+ "null": false,
+ "primary": true,
+ "autoincrement": true
+ },
+ "warehousemgmt_lot_status_lot_lot": {
+ "name": "warehousemgmt_lot_status_lot_lot",
+ "type": "VARCHAR(255)",
+ "null": false
+ },
+ "warehousemgmt_lot_status_lot_status": {
+ "name": "warehousemgmt_lot_status_lot_status",
+ "type": "INT",
+ "null": false,
+ "foreignTable": "warehousemgmt_lot_status",
+ "foreignKey": "warehousemgmt_lot_status_id"
+ },
+ "warehousemgmt_lot_status_lot_comment": {
+ "name": "warehousemgmt_lot_status_lot_comment",
+ "type": "VARCHAR(255)",
+ "null": false
+ },
+ "warehousemgmt_lot_status_lot_comment_raw": {
+ "name": "warehousemgmt_lot_status_lot_comment_raw",
+ "type": "VARCHAR(255)",
+ "null": false
+ },
+ "warehousemgmt_lot_status_lot_created_by": {
+ "name": "warehousemgmt_lot_status_lot_created_by",
+ "type": "VARCHAR(255)",
+ "null": false
+ },
+ "warehousemgmt_lot_status_lot_created_at": {
+ "name": "warehousemgmt_lot_status_created_at",
+ "type": "DATETIME",
+ "null": false
+ }
+ }
+ },
+ "warehousemgmt_movement_subtype": {
+ "name": "warehousemgmt_movement_subtype",
+ "fields": {
+ "warehousemgmt_movement_subtype_id": {
+ "name": "warehousemgmt_movement_subtype_id",
+ "type": "INT",
+ "null": false,
+ "primary": true,
+ "autoincrement": true
+ },
+ "warehousemgmt_movement_subtype_name": {
+ "name": "warehousemgmt_movement_subtype_name",
+ "type": "VARCHAR(255)",
+ "null": false
+ },
+ "warehousemgmt_movement_subtype_type": {
+ "name": "warehousemgmt_movement_subtype_type",
+ "type": "INT",
+ "null": false
+ }
+ }
+ },
+ "warehousemgmt_movement": {
+ "name": "warehousemgmt_movement",
+ "fields": {
+ "warehousemgmt_movement_id": {
+ "name": "warehousemgmt_movement_id",
+ "type": "INT",
+ "null": false,
+ "primary": true,
+ "autoincrement": true
+ },
+ "warehousemgmt_movement_quantity": {
+ "name": "warehousemgmt_movement_quantity",
+ "type": "INT",
+ "null": false
+ },
+ "warehousemgmt_movement_lot": {
+ "name": "warehousemgmt_movement_lot",
+ "type": "INT",
+ "null": false,
+ "foreignTable": "warehousemgmt_lot",
+ "foreignKey": "warehousemgmt_lot_id"
+ },
+ "warehousemgmt_movement_from": {
+ "name": "warehousemgmt_movement_from",
+ "type": "INT",
+ "null": true,
+ "default": null,
+ "foreignTable": "warehousemgmt_stocklocation",
+ "foreignKey": "warehousemgmt_stocklocation_id"
+ },
+ "warehousemgmt_movement_to": {
+ "name": "warehousemgmt_movement_to",
+ "type": "INT",
+ "null": true,
+ "default": null,
+ "foreignTable": "warehousemgmt_stocklocation",
+ "foreignKey": "warehousemgmt_stocklocation_id"
+ },
+ "warehousemgmt_movement_type": {
+ "name": "warehousemgmt_movement_type",
+ "type": "INT",
+ "null": false
+ },
+ "warehousemgmt_movement_subtype": {
+ "name": "warehousemgmt_movement_subtype",
+ "type": "INT",
+ "null": false,
+ "foreignTable": "warehousemgmt_movement_subtype",
+ "foreignKey": "warehousemgmt_movement_subtype_id"
+ },
+ "warehousemgmt_movement_reference": {
+ "name": "warehousemgmt_movement_reference",
+ "type": "VARCHAR(255)",
+ "null": false
+ },
+ "warehousemgmt_movement_bill_element": {
+ "name": "warehousemgmt_movement_bill_element",
+ "type": "INT",
+ "null": false,
+ "foreignTable": "billing_bill_element",
+ "foreignKey": "billing_bill_element_id"
+ },
+ "warehousemgmt_movement_created_by": {
+ "name": "warehousemgmt_movement_created_by",
+ "type": "INT",
+ "null": false,
+ "foreignTable": "account",
+ "foreignKey": "account_id"
+ },
+ "warehousemgmt_movement_created_at": {
+ "name": "warehousemgmt_movement_created_at",
+ "type": "DATETIME",
+ "null": false
+ }
+ }
+ },
+ "warehousemgmt_lot_quantity": {
+ "name": "warehousemgmt_lot_quantity",
+ "description": "Stores the quantity per lot per stocklocation. For every? (maybe only for transfers?) stock movement there are 2 item stock entries (from/to) where the last element per item (see movement_item) shows the current stock per lot and location. Consider to create even one more un-normalized table which shows quantity per item per stock for faster results?",
+ "fields": {
+ "warehousemgmt_lot_quantity_id": {
+ "name": "warehousemgmt_lot_quantity_id",
+ "type": "INT",
+ "null": false,
+ "primary": true,
+ "autoincrement": true
+ },
+ "warehousemgmt_lot_quantity_quantity": {
+ "name": "warehousemgmt_lot_quantity_quantity",
+ "type": "INT",
+ "null": false
+ },
+ "warehousemgmt_lot_quantity_stocklocation": {
+ "name": "warehousemgmt_lot_quantity_stocklocation",
+ "type": "INT",
+ "null": false,
+ "foreignTable": "warehousemgmt_stocklocation",
+ "foreignKey": "warehousemgmt_stocklocation_id"
+ },
+ "warehousemgmt_lot_quantity_movement": {
+ "name": "warehousemgmt_lot_quantity_movement",
+ "type": "INT",
+ "null": false,
+ "foreignTable": "warehousemgmt_movement",
+ "foreignKey": "warehousemgmt_movement_id"
+ }
+ }
+ }
+}
\ No newline at end of file
diff --git a/Docs/Dev/en/SUMMARY.md b/Docs/Dev/en/SUMMARY.md
new file mode 100644
index 0000000..e69de29
diff --git a/Docs/Dev/en/structure.md b/Docs/Dev/en/structure.md
new file mode 100644
index 0000000..e69de29
diff --git a/Docs/Help/en/SUMMARY.md b/Docs/Help/en/SUMMARY.md
new file mode 100644
index 0000000..e69de29
diff --git a/Docs/Help/en/introduction.md b/Docs/Help/en/introduction.md
new file mode 100644
index 0000000..e69de29
diff --git a/Models/StockMovementType.php b/Models/StockMovementType.php
new file mode 100644
index 0000000..0739bd3
--- /dev/null
+++ b/Models/StockMovementType.php
@@ -0,0 +1,46 @@
+ [
+ 'core' => [
+ 'masters' => [
+ 'admin' => [
+ 'db' => 'mysql', /* db type */
+ 'host' => '127.0.0.1', /* db host address */
+ 'port' => '3306', /* db host port */
+ 'login' => 'root', /* db login name */
+ 'password' => 'root', /* db login password */
+ 'database' => 'oms', /* db name */
+ 'weight' => 1000, /* db table prefix */
+ ],
+ 'insert' => [
+ 'db' => 'mysql', /* db type */
+ 'host' => '127.0.0.1', /* db host address */
+ 'port' => '3306', /* db host port */
+ 'login' => 'root', /* db login name */
+ 'password' => 'root', /* db login password */
+ 'database' => 'oms', /* db name */
+ 'weight' => 1000, /* db table prefix */
+ ],
+ 'select' => [
+ 'db' => 'mysql', /* db type */
+ 'host' => '127.0.0.1', /* db host address */
+ 'port' => '3306', /* db host port */
+ 'login' => 'root', /* db login name */
+ 'password' => 'root', /* db login password */
+ 'database' => 'oms', /* db name */
+ 'weight' => 1000, /* db table prefix */
+ ],
+ 'update' => [
+ 'db' => 'mysql', /* db type */
+ 'host' => '127.0.0.1', /* db host address */
+ 'port' => '3306', /* db host port */
+ 'login' => 'root', /* db login name */
+ 'password' => 'root', /* db login password */
+ 'database' => 'oms', /* db name */
+ 'weight' => 1000, /* db table prefix */
+ ],
+ 'delete' => [
+ 'db' => 'mysql', /* db type */
+ 'host' => '127.0.0.1', /* db host address */
+ 'port' => '3306', /* db host port */
+ 'login' => 'root', /* db login name */
+ 'password' => 'root', /* db login password */
+ 'database' => 'oms', /* db name */
+ 'weight' => 1000, /* db table prefix */
+ ],
+ 'schema' => [
+ 'db' => 'mysql', /* db type */
+ 'host' => '127.0.0.1', /* db host address */
+ 'port' => '3306', /* db host port */
+ 'login' => 'root', /* db login name */
+ 'password' => 'root', /* db login password */
+ 'database' => 'oms', /* db name */
+ 'weight' => 1000, /* db table prefix */
+ ],
+ ],
+ 'postgresql' => [
+ 'admin' => [
+ 'db' => 'pgsql', /* db type */
+ 'host' => '127.0.0.1', /* db host address */
+ 'port' => '5432', /* db host port */
+ 'login' => 'postgres', /* db login name */
+ 'password' => 'root', /* db login password */
+ 'database' => 'oms', /* db name */
+ 'weight' => 1000, /* db table prefix */
+ ],
+ 'insert' => [
+ 'db' => 'pgsql', /* db type */
+ 'host' => '127.0.0.1', /* db host address */
+ 'port' => '5432', /* db host port */
+ 'login' => 'postgres', /* db login name */
+ 'password' => 'root', /* db login password */
+ 'database' => 'oms', /* db name */
+ 'weight' => 1000, /* db table prefix */
+ ],
+ 'select' => [
+ 'db' => 'pgsql', /* db type */
+ 'host' => '127.0.0.1', /* db host address */
+ 'port' => '5432', /* db host port */
+ 'login' => 'postgres', /* db login name */
+ 'password' => 'root', /* db login password */
+ 'database' => 'oms', /* db name */
+ 'weight' => 1000, /* db table prefix */
+ ],
+ 'update' => [
+ 'db' => 'pgsql', /* db type */
+ 'host' => '127.0.0.1', /* db host address */
+ 'port' => '5432', /* db host port */
+ 'login' => 'postgres', /* db login name */
+ 'password' => 'root', /* db login password */
+ 'database' => 'oms', /* db name */
+ 'weight' => 1000, /* db table prefix */
+ ],
+ 'delete' => [
+ 'db' => 'pgsql', /* db type */
+ 'host' => '127.0.0.1', /* db host address */
+ 'port' => '5432', /* db host port */
+ 'login' => 'postgres', /* db login name */
+ 'password' => 'root', /* db login password */
+ 'database' => 'oms', /* db name */
+ 'weight' => 1000, /* db table prefix */
+ ],
+ 'schema' => [
+ 'db' => 'pgsql', /* db type */
+ 'host' => '127.0.0.1', /* db host address */
+ 'port' => '5432', /* db host port */
+ 'login' => 'postgres', /* db login name */
+ 'password' => 'root', /* db login password */
+ 'database' => 'oms', /* db name */
+ 'weight' => 1000, /* db table prefix */
+ ],
+ ],
+ 'sqlite' => [
+ 'admin' => [
+ 'db' => 'sqlite', /* db type */
+ 'database' => __DIR__ . '/test.sqlite', /* db name */
+ 'weight' => 1000, /* db table prefix */
+ ],
+ 'insert' => [
+ 'db' => 'sqlite', /* db type */
+ 'database' => __DIR__ . '/test.sqlite', /* db name */
+ 'weight' => 1000, /* db table prefix */
+ ],
+ 'select' => [
+ 'db' => 'sqlite', /* db type */
+ 'database' => __DIR__ . '/test.sqlite', /* db name */
+ 'weight' => 1000, /* db table prefix */
+ ],
+ 'update' => [
+ 'db' => 'sqlite', /* db type */
+ 'database' => __DIR__ . '/test.sqlite', /* db name */
+ 'weight' => 1000, /* db table prefix */
+ ],
+ 'delete' => [
+ 'db' => 'sqlite', /* db type */
+ 'database' => __DIR__ . '/test.sqlite', /* db name */
+ 'weight' => 1000, /* db table prefix */
+ ],
+ 'schema' => [
+ 'db' => 'sqlite', /* db type */
+ 'database' => __DIR__ . '/test.sqlite', /* db name */
+ 'weight' => 1000, /* db table prefix */
+ ],
+ ],
+ 'mssql' => [
+ 'admin' => [
+ 'db' => 'mssql', /* db type */
+ 'host' => '127.0.0.1', /* db host address */
+ 'port' => '1433', /* db host port */
+ 'login' => 'sa', /* db login name */
+ 'password' => 'R00troot', /* db login password */
+ 'database' => 'oms', /* db name */
+ 'weight' => 1000, /* db table prefix */
+ ],
+ 'insert' => [
+ 'db' => 'mssql', /* db type */
+ 'host' => '127.0.0.1', /* db host address */
+ 'port' => '1433', /* db host port */
+ 'login' => 'sa', /* db login name */
+ 'password' => 'R00troot', /* db login password */
+ 'database' => 'oms', /* db name */
+ 'weight' => 1000, /* db table prefix */
+ ],
+ 'select' => [
+ 'db' => 'mssql', /* db type */
+ 'host' => '127.0.0.1', /* db host address */
+ 'port' => '1433', /* db host port */
+ 'login' => 'sa', /* db login name */
+ 'password' => 'R00troot', /* db login password */
+ 'database' => 'oms', /* db name */
+ 'weight' => 1000, /* db table prefix */
+ ],
+ 'update' => [
+ 'db' => 'mssql', /* db type */
+ 'host' => '127.0.0.1', /* db host address */
+ 'port' => '1433', /* db host port */
+ 'login' => 'sa', /* db login name */
+ 'password' => 'R00troot', /* db login password */
+ 'database' => 'oms', /* db name */
+ 'weight' => 1000, /* db table prefix */
+ ],
+ 'delete' => [
+ 'db' => 'mssql', /* db type */
+ 'host' => '127.0.0.1', /* db host address */
+ 'port' => '1433', /* db host port */
+ 'login' => 'sa', /* db login name */
+ 'password' => 'R00troot', /* db login password */
+ 'database' => 'oms', /* db name */
+ 'weight' => 1000, /* db table prefix */
+ ],
+ 'schema' => [
+ 'db' => 'mssql', /* db type */
+ 'host' => '127.0.0.1', /* db host address */
+ 'port' => '1433', /* db host port */
+ 'login' => 'sa', /* db login name */
+ 'password' => 'R00troot', /* db login password */
+ 'database' => 'oms', /* db name */
+ 'weight' => 1000, /* db table prefix */
+ ],
+ ],
+ ],
+ ],
+ 'cache' => [
+ 'redis' => [
+ 'db' => 1,
+ 'host' => '127.0.0.1',
+ 'port' => 6379,
+ ],
+ 'memcached' => [
+ 'host' => '127.0.0.1',
+ 'port' => 11211,
+ ],
+ ],
+ 'mail' => [
+ 'imap' => [
+ 'host' => '127.0.0.1',
+ 'port' => 143,
+ 'ssl' => false,
+ 'user' => 'test',
+ 'password' => '123456',
+ ],
+ 'pop3' => [
+ 'host' => '127.0.0.1',
+ 'port' => 25,
+ 'ssl' => false,
+ 'user' => 'test',
+ 'password' => '123456',
+ ],
+ ],
+ 'log' => [
+ 'file' => [
+ 'path' => __DIR__ . '/Logs',
+ ],
+ ],
+ 'page' => [
+ 'root' => '/',
+ 'https' => false,
+ ],
+ 'socket' => [
+ 'master' => [
+ 'host' => '127.0.0.1',
+ 'limit' => 300,
+ 'port' => 4310,
+ ],
+ ],
+ 'language' => [
+ 'en',
+ ],
+ 'apis' => [
+ ],
+];
+
+// Reset database
+if (\defined('RESET') && RESET === '1') {
+ if (\extension_loaded('pdo_mysql')) {
+ try {
+ $db = new \PDO('mysql:host=' .
+ $CONFIG['db']['core']['masters']['admin']['host'],
+ $CONFIG['db']['core']['masters']['admin']['login'],
+ $CONFIG['db']['core']['masters']['admin']['password']
+ );
+ $db->exec('DROP DATABASE IF EXISTS ' . $CONFIG['db']['core']['masters']['admin']['database']);
+ $db->exec('CREATE DATABASE IF NOT EXISTS ' . $CONFIG['db']['core']['masters']['admin']['database']);
+ $db = null;
+ } catch (\Throwable $t) {
+ echo "\nCouldn't connect to MYSQL DB\n";
+ }
+ }
+
+ if (\extension_loaded('pdo_pgsql')) {
+ try {
+ $db = new \PDO('pgsql:host=' .
+ $CONFIG['db']['core']['postgresql']['admin']['host'],
+ $CONFIG['db']['core']['postgresql']['admin']['login'],
+ $CONFIG['db']['core']['postgresql']['admin']['password']
+ );
+ $db->exec('DROP DATABASE IF EXISTS ' . $CONFIG['db']['core']['postgresql']['admin']['database']);
+ $db->exec('CREATE DATABASE ' . $CONFIG['db']['core']['postgresql']['admin']['database']);
+ $db = null;
+ } catch (\Throwable $t) {
+ echo "\nCouldn't connect to POSTGRESQL DB\n";
+ }
+ }
+
+ if (\extension_loaded('pdo_sqlsrv')) {
+ try {
+ $db = new \PDO('sqlsrv:Server=' .
+ $CONFIG['db']['core']['mssql']['admin']['host'],
+ $CONFIG['db']['core']['mssql']['admin']['login'],
+ $CONFIG['db']['core']['mssql']['admin']['password']
+ );
+ $db->exec('DROP DATABASE IF EXISTS ' . $CONFIG['db']['core']['mssql']['admin']['database']);
+ $db->exec('CREATE DATABASE ' . $CONFIG['db']['core']['mssql']['admin']['database']);
+ $db = null;
+ } catch (\Throwable $t) {
+ echo "\nCouldn't connect to MSSQL DB\n";
+ }
+ }
+}
+
+$httpSession = new HttpSession();
+$GLOBALS['session'] = $httpSession;
+
+$GLOBALS['dbpool'] = new DatabasePool();
+$GLOBALS['dbpool']->create('admin', $CONFIG['db']['core']['masters']['admin']);
+$GLOBALS['dbpool']->create('select', $CONFIG['db']['core']['masters']['select']);
+$GLOBALS['dbpool']->create('update', $CONFIG['db']['core']['masters']['update']);
+$GLOBALS['dbpool']->create('delete', $CONFIG['db']['core']['masters']['delete']);
+$GLOBALS['dbpool']->create('insert', $CONFIG['db']['core']['masters']['insert']);
+$GLOBALS['dbpool']->create('schema', $CONFIG['db']['core']['masters']['schema']);
+
+DataMapperAbstract::setConnection($GLOBALS['dbpool']->get());
+
+$GLOBALS['frameworkpath'] = '/phpOMS/';
+
+function phpServe() : void
+{
+ // OS detection
+ $isWindows = \stristr(\php_uname('s'), 'Windows') !== false;
+
+ // Command that starts the built-in web server
+ if ($isWindows) {
+ $command = \sprintf(
+ 'wmic process call create "php -S %s:%d -t %s" | find "ProcessId"',
+ WEB_SERVER_HOST,
+ WEB_SERVER_PORT,
+ __DIR__ . '/../' . WEB_SERVER_DOCROOT
+ );
+
+ $killCommand = 'taskkill /f /pid ';
+ } else {
+ $command = \sprintf(
+ 'php -S %s:%d -t %s >/dev/null 2>&1 & echo $!',
+ WEB_SERVER_HOST,
+ WEB_SERVER_PORT,
+ WEB_SERVER_DOCROOT
+ );
+
+ $killCommand = 'kill ';
+ }
+
+ // Execute the command and store the process ID
+ $output = [];
+ echo \sprintf('Starting server...') . \PHP_EOL;
+ echo \sprintf(' Current directory: %s', \getcwd()) . \PHP_EOL;
+ echo \sprintf(' %s', $command);
+ \exec($command, $output);
+
+ // Get PID
+ if ($isWindows) {
+ $pid = \explode('=', $output[0]);
+ $pid = \str_replace(' ', '', $pid[1]);
+ $pid = \str_replace(';', '', $pid);
+ } else {
+ $pid = (int) $output[0];
+ }
+
+ // Log
+ echo \sprintf(
+ ' %s - Web server started on %s:%d with PID %d',
+ \date('r'),
+ WEB_SERVER_HOST,
+ WEB_SERVER_PORT,
+ $pid
+ ) . \PHP_EOL;
+
+ // Kill the web server when the process ends
+ \register_shutdown_function(function() use ($killCommand, $pid) : void {
+ echo \PHP_EOL . \sprintf('Stopping server...') . \PHP_EOL;
+ echo \sprintf(' %s - Killing process with ID %d', \date('r'), $pid) . \PHP_EOL;
+ \exec($killCommand . $pid);
+ });
+}
+
+phpServe();
diff --git a/tests/phpunit_default.xml b/tests/phpunit_default.xml
new file mode 100755
index 0000000..0419dd8
--- /dev/null
+++ b/tests/phpunit_default.xml
@@ -0,0 +1,56 @@
+
+
+
+
+ *vendor*
+ vendor
+ ../vendor
+ ../phpOMS
+ ../phpOMS*
+ ../phpOMS/*
+ ../tests*
+ ../*/tests*
+ ../**/tests*
+ */tests*
+ ../*
+ ../*
+ ../*
+ ../*
+ ../*
+ ../**/test*
+ ../**/Theme*
+ ../**/Admin/Routes*
+ ../**/Admin/Install*
+ ../Media/Files*
+
+
+
+
+
+
+
+
+ ../Orange-Management/Install/tests*
+
+
+ ../tests*
+
+
+
+
+ volume
+ maybe
+
+
+
+
+
+
+
+
+
+
+
+
+
+