Compare commits
353 Commits
v8.3.7
...
viclou-patch-1
| Author | SHA1 | Date | |
|---|---|---|---|
| aba3a0733d | |||
| 929132ba07 | |||
| 2a1a4a1c72 | |||
| 4d73894cd2 | |||
| e49e805b2b | |||
| 05f3bf633e | |||
| 4d5b3548d6 | |||
| 00408f0103 | |||
| 548cceee18 | |||
| 76d1a20e21 | |||
| 30970cc7f2 | |||
| 985c027b04 | |||
| d1c4b055a9 | |||
| 3f2f508e49 | |||
| 07513cb559 | |||
| 66022902b7 | |||
| 613efe963a | |||
| 5a0affcd8e | |||
| 79150edb92 | |||
| 6cca24be8e | |||
| c2ca51e8ef | |||
| b9908d5665 | |||
| cbca420217 | |||
| 017183e3fe | |||
| 0236527f05 | |||
| e946c4bf8c | |||
| 8a0414cef6 | |||
| ee1ad692a4 | |||
| fdd5f6b0e1 | |||
| dca6df3244 | |||
| 0874b853a0 | |||
| 3393916b5e | |||
| b2728b4eb1 | |||
| f3cc3ed682 | |||
| f8cfb8833f | |||
| c2c2332e83 | |||
| 9f69c36426 | |||
| ea9de35a3b | |||
| a50a16fb01 | |||
| f27c0206de | |||
| 6791ddd911 | |||
| ce95060d60 | |||
| 6d9bbe1ddf | |||
| 5b1507f4b7 | |||
| 53e985aaab | |||
| f5c2119122 | |||
| 5fd6918948 | |||
| 7423d13bdd | |||
| fb8586f186 | |||
| 8b9ebf736b | |||
| 5abcdb8c5a | |||
| e549f67fcc | |||
| d68576c2fa | |||
| a6042b6a03 | |||
| d1a3afd992 | |||
| 34b00f7dba | |||
| 14b6c6861f | |||
| fe4bb4209c | |||
| e997eb2012 | |||
| 8337473f5a | |||
| 1f50eada6d | |||
| 38e1114dad | |||
| 11be73a578 | |||
| 13a00df73c | |||
| 7739690bf5 | |||
| 389eb9e05d | |||
| 98fe94aa24 | |||
| 4ee378bf8e | |||
| a8c268760b | |||
| c684b8ab1e | |||
| 333d0e2391 | |||
| c22c5993fc | |||
| 1c239cc7cf | |||
| 6ee5aa3e12 | |||
| 0d5ceb1e90 | |||
| 166a241761 | |||
| f6f5e806e4 | |||
| f0f42240f3 | |||
| 686afc0974 | |||
| 7e5fb3c9ae | |||
| 65e4c0b8d1 | |||
| b1301237f1 | |||
| cf82c12708 | |||
| 52f8697d91 | |||
| 3169c5b503 | |||
| 741f0d69ab | |||
| 53b283eac5 | |||
| 1234b6297e | |||
| 8ff34baafa | |||
| eeae534a37 | |||
| 8b71049a3d | |||
| 373361dab0 | |||
| 60a1141b9d | |||
| a38c8a0235 | |||
| c39d165a3d | |||
| 2238f8e8ad | |||
| e0c53c3ead | |||
| 1074bc2d3b | |||
| 4b22b1c115 | |||
| 141794caf7 | |||
| d5997e2394 | |||
| 429ca8dd34 | |||
| c2ad0defe0 | |||
| b4658f2696 | |||
| 11b7dfc9b0 | |||
| f7b7ef850d | |||
| bb9b145519 | |||
| d75f5b8fd3 | |||
| 34fe64b27c | |||
| 2151595b45 | |||
| b2c94386b3 | |||
| b99ae9be88 | |||
| ffbc831071 | |||
| 302a60fbe7 | |||
| 3ec8ba01d0 | |||
| 2048eb7d5a | |||
| 4d605927f3 | |||
| b7ee3a2f1d | |||
| 44fa9e2d1e | |||
| a5e818f970 | |||
| 066cf81233 | |||
| 1b4552cf30 | |||
| 0ba8ee1c5f | |||
| 5c4f3a5aec | |||
| c963c0b25b | |||
| b3a4fb2676 | |||
| 0b82902248 | |||
| e7f70ccd1f | |||
| 683395599f | |||
| 755d7c2351 | |||
| 17d91bcd8e | |||
| 2633ec10dc | |||
| c4f772c8d9 | |||
| 18addf2a87 | |||
| eee826248d | |||
| 96a817753c | |||
| 600b06e66b | |||
| cd680daa4c | |||
| 315b716e87 | |||
| b2f1966a78 | |||
| 6305f87037 | |||
| ab02b67d3c | |||
| 0f4086eaf0 | |||
| e7c5329e57 | |||
| ad82ea86c8 | |||
| c310e1e3b7 | |||
| aaf9372474 | |||
| 2cf169359e | |||
| 7f67f8c20d | |||
| 5607dfcecb | |||
| ca99f525c9 | |||
| 7e92517d13 | |||
| 1ebb67b2e7 | |||
| d9ef7b43b0 | |||
| c074fae885 | |||
| c5ada0fc2f | |||
| 5268b0f67f | |||
| 7e10089c13 | |||
| 1dab36da2d | |||
| fab50e53b8 | |||
| 10cfe6d37a | |||
| 3718ce9749 | |||
| fd39c8bf11 | |||
| 2e122fa8d8 | |||
| 66d85d17d9 | |||
| 61bc570d59 | |||
| 62dbd400a4 | |||
| 74af52d29d | |||
| 59f377b058 | |||
| 949f65b210 | |||
| 4046fbae89 | |||
| da8776c2f1 | |||
| 4043df1d02 | |||
| 3bc5ab593a | |||
| 6dad0d669f | |||
| 39f581a826 | |||
| 2034b25b25 | |||
| 468a7aa911 | |||
| ec50643d96 | |||
| 3b98fb666f | |||
| f17eeed579 | |||
| 452d0b6f6e | |||
| 41450b6e1b | |||
| 30029462b1 | |||
| e109879cac | |||
| 90ad4e9abf | |||
| fd0e2b1a96 | |||
| 19d637efea | |||
| 6c18b35276 | |||
| 184eddb5cf | |||
| 1d577b0171 | |||
| 05c998227a | |||
| 53ed810d86 | |||
| 7c136b6f57 | |||
| 4e510d9d8c | |||
| e1f30f96c9 | |||
| 146d0cefc0 | |||
| 0103bd58e1 | |||
| dbc1e7d6ab | |||
| ea706863b5 | |||
| 04f4f5b57c | |||
| 98b9246c10 | |||
| 1e158721ee | |||
| ab4eefcac2 | |||
| cf3b36f124 | |||
| 8da01b8569 | |||
| c90afaa312 | |||
| 9f20bb89c1 | |||
| dfe664b779 | |||
| 88bd1fd6ef | |||
| 33f8823edb | |||
| 06d5c0a86c | |||
| e12a5eda01 | |||
| b3c59b2cc3 | |||
| 24d5969ce8 | |||
| 6ad42a02ad | |||
| 90b1ee4805 | |||
| 0c9d5ca9da | |||
| e05ecd0c3e | |||
| 441657cbfb | |||
| 0fb6b02fc4 | |||
| f83df0d651 | |||
| e667cd20a8 | |||
| d06c56367f | |||
| 039b4cf19f | |||
| ca0961bd49 | |||
| 79528fa87b | |||
| d96d0b1bcb | |||
| 02c237404e | |||
| c56f5282ff | |||
| d62f10cb46 | |||
| 4c6f123cda | |||
| b0b1829426 | |||
| 68b590c263 | |||
| b45efddd9a | |||
| d8f5d8c6ec | |||
| 56baa8ac9f | |||
| 15aa64ed28 | |||
| 6d0bfeb420 | |||
| ceff334420 | |||
| 4ee2db68fc | |||
| 1f04d0023b | |||
| 4427fdcaec | |||
| 4de642c6a4 | |||
| d3eb89a97c | |||
| d7362a3785 | |||
| 26347ac41e | |||
| b396da3f33 | |||
| 306a0bf6de | |||
| 8000e274c6 | |||
| e48c40e5af | |||
| df51318fb9 | |||
| 0327d01287 | |||
| 0ab206ca13 | |||
| 542cdef0bd | |||
| f5955e14ff | |||
| a0df7adbd1 | |||
| 82a4398ef6 | |||
| 9271930ba8 | |||
| f149f0d994 | |||
| 14ff325608 | |||
| 8e37fcc71e | |||
| bf910bc708 | |||
| 1136ea0779 | |||
| 9ad94b6562 | |||
| 5ddb0b4a55 | |||
| 990858ba41 | |||
| 406951fc84 | |||
| 41c7bf4aaa | |||
| 1543634cb0 | |||
| b935752ec0 | |||
| 2a60b7b7b2 | |||
| cef78687b3 | |||
| 2f29edc01f | |||
| 134491b59e | |||
| 812ff0bfd2 | |||
| 201c4fa0d9 | |||
| ced83b9bfc | |||
| e67c5273d7 | |||
| b4b9339065 | |||
| f3cd68eb3f | |||
| ad57dea0e5 | |||
| 1e0a348b8e | |||
| 9c06a2126d | |||
| dab030e95d | |||
| 4995bc0d0d | |||
| d2369893c8 | |||
| e48adf6443 | |||
| 505bca8386 | |||
| 31ca93a259 | |||
| 71523b7038 | |||
| 9885dc9c8a | |||
| 00d9d9f132 | |||
| 320dc3fac6 | |||
| 6e68e43a25 | |||
| a19c391aa1 | |||
| 32f0101c1b | |||
| 12b9fdced5 | |||
| 0af45a53a9 | |||
| 37773d35f2 | |||
| fca3eb4b7b | |||
| 5e9e0b70db | |||
| 5242ffc04b | |||
| f0c9a5b2dc | |||
| b3902e82fc | |||
| d70eff6fc4 | |||
| 5b5695ffe1 | |||
| deb44cad30 | |||
| 35fdca3607 | |||
| 93080523d0 | |||
| b7b8f5a7e7 | |||
| 59ee55a6b2 | |||
| d85b25d683 | |||
| 0108006fab | |||
| 755bb8f189 | |||
| f53dcbc64f | |||
| 0f215bbcf8 | |||
| 9770775770 | |||
| 0b63bcc056 | |||
| 03116f5ece | |||
| 5c091d8690 | |||
| da1ca24190 | |||
| fa7382851f | |||
| ab363596fd | |||
| b05970acf4 | |||
| aa6b70c296 | |||
| 00171e6d16 | |||
| 061e0ded72 | |||
| 81bdd86fb7 | |||
| 60ff06bcf0 | |||
| a3e3f48d47 | |||
| a3a79a696f | |||
| 6947672046 | |||
| 6f77e96998 | |||
| 8a595aa269 | |||
| 1ccf38221f | |||
| 18c639e6c0 | |||
| 06224371b3 | |||
| d06105f410 | |||
| 3226340b08 | |||
| 25ef5d64b4 | |||
| f286558065 | |||
| 9586c50cb5 | |||
| 4658bf38c5 | |||
| 951a4e37f3 | |||
| 6ad3154035 | |||
| d7fa4a0df2 | |||
| 1112a40f0f | |||
| e908838376 | |||
| 4b1339a11c | |||
| c978be5cab | |||
| 242201ca91 | |||
| a3a49e47b7 |
@@ -40,12 +40,26 @@ DB_SANITIZE_BY_DEFAULT=false
|
||||
# --------------------------------------------
|
||||
# OPTIONAL: SSL DATABASE SETTINGS
|
||||
# --------------------------------------------
|
||||
# Enable SSL connection to database (true/false)
|
||||
DB_SSL=false
|
||||
|
||||
# Set to true for cloud databases like AWS RDS, Azure Database, Google Cloud SQL
|
||||
# Set to false for self-hosted databases with client certificates
|
||||
DB_SSL_IS_PAAS=false
|
||||
|
||||
# Required when DB_SSL_IS_PAAS=false (client certificate authentication)
|
||||
DB_SSL_KEY_PATH=null
|
||||
DB_SSL_CERT_PATH=null
|
||||
|
||||
# Path to CA certificate bundle (required for SSL connections)
|
||||
# For AWS RDS, download from: https://truststore.pki.rds.amazonaws.com/global/global-bundle.pem
|
||||
DB_SSL_CA_PATH=null
|
||||
|
||||
# SSL cipher (optional, leave null for default)
|
||||
DB_SSL_CIPHER=null
|
||||
|
||||
# Verify server certificate (true/false, defaults to false if not set)
|
||||
# Set to false for development or when using self-signed certificates
|
||||
DB_SSL_VERIFY_SERVER=null
|
||||
|
||||
# --------------------------------------------
|
||||
|
||||
@@ -1,10 +1,11 @@
|
||||
frontend: ["*.js", "*.css", "*.vue", "*.scss", "*.less", "*.blade.*", "resources/views/livewire/*"]
|
||||
frontend: ["*.js", "*.css", "*.scss", "*.less", "*.blade.*", "resources/views/livewire/*","resources/views/layouts/default.blade.php"]
|
||||
skins: ["*.js", "*.css", "*.scss", "*.less"]
|
||||
css: ["*.css","*.scss", "*.less"]
|
||||
javascript: ["*.js", "package.json", "package.lock"]
|
||||
backend: ["/app/*", "composer.json", "composer.lock"]
|
||||
translations: ["/resources/lang"]
|
||||
translations: ["/resources/lang/*"]
|
||||
livewire: ["/app/Http/Livewire/*", "resources/views/livewire/*"]
|
||||
blade-components: ["resources/views/blade/*"]
|
||||
backups: ["*backup*"]
|
||||
restore: ["*restore*"]
|
||||
saml: ["*saml*"]
|
||||
@@ -16,7 +17,7 @@ api: ["/app/Http/Controllers/Api/*"]
|
||||
notifications: ["/app/Notifications/*"]
|
||||
importer: ["/app/Importer/*","/app/Http/Livewire/Importer.php", "resources/views/livewire/importer.php"]
|
||||
cli / artisan: ["/app/Console/*"]
|
||||
LDAP: ["*Ldap*", "/app/Console/Commands/Ldap*","/app/Models/Ldap.php"]
|
||||
LDAP: ["*Ldap*", "/app/Console/Commands/Ldap*","/app/Models/Ldap.php", "/resources/views/users/ldap.blade.php","/resources/views/settings/ldap.blade.php"]
|
||||
docker: ["*docker/*", "Dockerfile", "Dockerfile.alpine", "Dockerfile.fpm-alpine", ".dockerignore", ".env.docker"]
|
||||
tests: ["/tests/*", "/database/factories/*", "/stubs"]
|
||||
config: .github
|
||||
|
||||
@@ -43,7 +43,7 @@ jobs:
|
||||
id: composer-cache
|
||||
run: |
|
||||
echo "dir=$(composer config cache-files-dir)" >> $GITHUB_OUTPUT
|
||||
- uses: actions/cache@v4
|
||||
- uses: actions/cache@v5
|
||||
with:
|
||||
path: ${{ steps.composer-cache.outputs.dir }}
|
||||
key: ${{ runner.os }}-${{ matrix.php-version }}-composer-${{ hashFiles('**/composer.lock') }}
|
||||
@@ -82,7 +82,7 @@ jobs:
|
||||
|
||||
- name: Upload Laravel logs as artifacts
|
||||
if: always()
|
||||
uses: actions/upload-artifact@v5
|
||||
uses: actions/upload-artifact@v6
|
||||
with:
|
||||
name: laravel-logs-php-${{ matrix.php-version }}-run-${{ github.run_attempt }}
|
||||
path: |
|
||||
|
||||
@@ -40,7 +40,7 @@ jobs:
|
||||
id: composer-cache
|
||||
run: |
|
||||
echo "dir=$(composer config cache-files-dir)" >> $GITHUB_OUTPUT
|
||||
- uses: actions/cache@v4
|
||||
- uses: actions/cache@v5
|
||||
with:
|
||||
path: ${{ steps.composer-cache.outputs.dir }}
|
||||
key: ${{ runner.os }}-${{ matrix.php-version }}-composer-${{ hashFiles('**/composer.lock') }}
|
||||
@@ -81,7 +81,7 @@ jobs:
|
||||
|
||||
- name: Upload Laravel logs as artifacts
|
||||
if: always()
|
||||
uses: actions/upload-artifact@v5
|
||||
uses: actions/upload-artifact@v6
|
||||
with:
|
||||
name: laravel-logs-php-${{ matrix.php-version }}-run-${{ github.run_attempt }}
|
||||
path: |
|
||||
|
||||
@@ -31,7 +31,7 @@ jobs:
|
||||
id: composer-cache
|
||||
run: |
|
||||
echo "dir=$(composer config cache-files-dir)" >> $GITHUB_OUTPUT
|
||||
- uses: actions/cache@v4
|
||||
- uses: actions/cache@v5
|
||||
with:
|
||||
path: ${{ steps.composer-cache.outputs.dir }}
|
||||
key: ${{ runner.os }}-${{ matrix.php-version }}-composer-${{ hashFiles('**/composer.lock') }}
|
||||
@@ -67,7 +67,7 @@ jobs:
|
||||
|
||||
- name: Upload Laravel logs as artifacts
|
||||
if: always()
|
||||
uses: actions/upload-artifact@v5
|
||||
uses: actions/upload-artifact@v6
|
||||
with:
|
||||
name: laravel-logs-php-${{ matrix.php-version }}-run-${{ github.run_attempt }}
|
||||
path: |
|
||||
|
||||
+30
-30
@@ -1,35 +1,35 @@
|
||||
FROM alpine:3.19
|
||||
FROM alpine:3.23
|
||||
# Apache + PHP
|
||||
RUN apk add --no-cache \
|
||||
apache2 \
|
||||
php82 \
|
||||
php82-common \
|
||||
php82-apache2 \
|
||||
php82-curl \
|
||||
php82-ldap \
|
||||
php82-mysqli \
|
||||
php82-gd \
|
||||
php82-xml \
|
||||
php82-mbstring \
|
||||
php82-zip \
|
||||
php82-ctype \
|
||||
php82-tokenizer \
|
||||
php82-pdo_mysql \
|
||||
php82-openssl \
|
||||
php82-bcmath \
|
||||
php82-phar \
|
||||
php82-json \
|
||||
php82-iconv \
|
||||
php82-fileinfo \
|
||||
php82-simplexml \
|
||||
php82-session \
|
||||
php82-dom \
|
||||
php82-xmlwriter \
|
||||
php82-xmlreader \
|
||||
php82-sodium \
|
||||
php82-redis \
|
||||
php82-pecl-memcached \
|
||||
php82-exif \
|
||||
php84 \
|
||||
php84-common \
|
||||
php84-apache2 \
|
||||
php84-curl \
|
||||
php84-ldap \
|
||||
php84-mysqli \
|
||||
php84-gd \
|
||||
php84-xml \
|
||||
php84-mbstring \
|
||||
php84-zip \
|
||||
php84-ctype \
|
||||
php84-tokenizer \
|
||||
php84-pdo_mysql \
|
||||
php84-openssl \
|
||||
php84-bcmath \
|
||||
php84-phar \
|
||||
php84-json \
|
||||
php84-iconv \
|
||||
php84-fileinfo \
|
||||
php84-simplexml \
|
||||
php84-session \
|
||||
php84-dom \
|
||||
php84-xmlwriter \
|
||||
php84-xmlreader \
|
||||
php84-sodium \
|
||||
php84-redis \
|
||||
php84-pecl-memcached \
|
||||
php84-exif \
|
||||
curl \
|
||||
wget \
|
||||
vim \
|
||||
@@ -42,7 +42,7 @@ COPY docker/column-statistics.cnf /etc/mysql/conf.d/column-statistics.cnf
|
||||
# Where apache's PID lives
|
||||
RUN mkdir -p /run/apache2 && chown apache:apache /run/apache2
|
||||
|
||||
RUN sed -i 's/variables_order = .*/variables_order = "EGPCS"/' /etc/php82/php.ini
|
||||
RUN sed -i 's/variables_order = .*/variables_order = "EGPCS"/' /etc/php84/php.ini
|
||||
COPY docker/000-default-2.4.conf /etc/apache2/conf.d/default.conf
|
||||
|
||||
# Enable mod_rewrite
|
||||
|
||||
@@ -78,6 +78,8 @@ Since the release of the JSON REST API, several third-party developers have been
|
||||
|
||||
#### Libraries & Modules
|
||||
|
||||
- [SnipeScheduler](https://github.com/JSY-Ben/SnipeScheduler) by [@JSY-Ben](https://github.com/JSY-Ben) - An Asset Reservation/Checkout System for Snipe-IT
|
||||
- [Snipe-IT MCP Server](https://github.com/jameshgordy/snipeit-mcp) by [@jameshgordy](https://github.com/jameshgordy) - A Model Context Protocol (MCP) server for managing Snipe-IT inventory systems
|
||||
- [SnipeSharp - .NET module in C#](https://github.com/barrycarey/SnipeSharp) by [@barrycarey](https://github.com/barrycarey)
|
||||
- [SnipeitPS](https://github.com/snazy2000/SnipeitPS) by [@snazy2000](https://github.com/snazy2000) - Powershell API Wrapper for Snipe-it
|
||||
- [jamf2snipe](https://github.com/grokability/jamf2snipe) - Python script to sync assets between a JAMFPro instance and a Snipe-IT instance
|
||||
|
||||
@@ -245,26 +245,26 @@ class LdapSync extends Command
|
||||
// Assign the mapped LDAP attributes for each user to the Snipe-IT user fields
|
||||
for ($i = 0; $i < $results['count']; $i++) {
|
||||
$item = [];
|
||||
$item['username'] = $results[$i][$ldap_map["username"]][0] ?? '';
|
||||
$item['display_name'] = $results[$i][$ldap_map["display_name"]][0] ?? '';
|
||||
$item['employee_number'] = $results[$i][$ldap_map["emp_num"]][0] ?? '';
|
||||
$item['lastname'] = $results[$i][$ldap_map["last_name"]][0] ?? '';
|
||||
$item['firstname'] = $results[$i][$ldap_map["first_name"]][0] ?? '';
|
||||
$item['email'] = $results[$i][$ldap_map["email"]][0] ?? '';
|
||||
$item['ldap_location_override'] = $results[$i]['ldap_location_override'] ?? '';
|
||||
$item['location_id'] = $results[$i]['location_id'] ?? '';
|
||||
$item['telephone'] = $results[$i][$ldap_map["phone"]][0] ?? '';
|
||||
$item['mobile'] = $results[$i][$ldap_map["mobile"]][0] ?? '';
|
||||
$item['jobtitle'] = $results[$i][$ldap_map["jobtitle"]][0] ?? '';
|
||||
$item['address'] = $results[$i][$ldap_map["address"]][0] ?? '';
|
||||
$item['city'] = $results[$i][$ldap_map["city"]][0] ?? '';
|
||||
$item['state'] = $results[$i][$ldap_map["state"]][0] ?? '';
|
||||
$item['country'] = $results[$i][$ldap_map["country"]][0] ?? '';
|
||||
$item['zip'] = $results[$i][$ldap_map["zip"]][0] ?? '';
|
||||
$item['department'] = $results[$i][$ldap_map["dept"]][0] ?? '';
|
||||
$item['manager'] = $results[$i][$ldap_map["manager"]][0] ?? '';
|
||||
$item['location'] = $results[$i][$ldap_map["location"]][0] ?? '';
|
||||
$location = $default_location; //initially, set '$location' to the default_location (which may just be `null`)
|
||||
$item['username'] = $results[$i][$ldap_map["username"]][0] ?? null;
|
||||
$item['display_name'] = $results[$i][$ldap_map["display_name"]][0] ?? null;
|
||||
$item['employee_number'] = $results[$i][$ldap_map["emp_num"]][0] ?? null;
|
||||
$item['lastname'] = $results[$i][$ldap_map["last_name"]][0] ?? null;
|
||||
$item['firstname'] = $results[$i][$ldap_map["first_name"]][0] ?? null;
|
||||
$item['email'] = $results[$i][$ldap_map["email"]][0] ?? null;
|
||||
$item['ldap_location_override'] = $results[$i]['ldap_location_override'] ?? null;
|
||||
$item['location_id'] = $results[$i]['location_id'] ?? null;
|
||||
$item['telephone'] = $results[$i][$ldap_map["phone"]][0] ?? null;
|
||||
$item['mobile'] = $results[$i][$ldap_map["mobile"]][0] ?? null;
|
||||
$item['jobtitle'] = $results[$i][$ldap_map["jobtitle"]][0] ?? null;
|
||||
$item['address'] = $results[$i][$ldap_map["address"]][0] ?? null;
|
||||
$item['city'] = $results[$i][$ldap_map["city"]][0] ?? null;
|
||||
$item['state'] = $results[$i][$ldap_map["state"]][0] ?? null;
|
||||
$item['country'] = $results[$i][$ldap_map["country"]][0] ?? null;
|
||||
$item['zip'] = $results[$i][$ldap_map["zip"]][0] ?? null;
|
||||
$item['department'] = $results[$i][$ldap_map["dept"]][0] ?? null;
|
||||
$item['manager'] = $results[$i][$ldap_map["manager"]][0] ?? null;
|
||||
$item['location'] = $results[$i][$ldap_map["location"]][0] ?? null;
|
||||
$location = $default_location; //initially, set '$location' to the default_location (which may just be null)
|
||||
|
||||
// ONLY if you are using the "ldap_location" option *AND* you have an actual result
|
||||
if ($ldap_map["location"] && $item['location']) {
|
||||
@@ -464,6 +464,7 @@ class LdapSync extends Command
|
||||
$errors = '';
|
||||
|
||||
if ($user->save()) {
|
||||
$item['id'] = $user->id;
|
||||
$item['note'] = $item['createorupdate'];
|
||||
$item['status'] = 'success';
|
||||
if ($item['createorupdate'] === 'created' && $ldap_default_group) {
|
||||
|
||||
@@ -0,0 +1,74 @@
|
||||
<?php
|
||||
|
||||
namespace App\Console\Commands;
|
||||
|
||||
use App\Enums\ActionType;
|
||||
use Illuminate\Console\Command;
|
||||
use Illuminate\Support\Facades\DB;
|
||||
use Illuminate\Support\Facades\Log;
|
||||
use Illuminate\Support\Str;
|
||||
|
||||
class MigrateLicenseSeatQuantitiesInActionLogs extends Command
|
||||
{
|
||||
/**
|
||||
* The name and signature of the console command.
|
||||
*
|
||||
* @var string
|
||||
*/
|
||||
protected $signature = 'snipeit:migrate-license-seat-quantities-in-action-logs
|
||||
{--no-interaction: Do not ask any interactive question}';
|
||||
|
||||
/**
|
||||
* The console command description.
|
||||
*
|
||||
* @var string
|
||||
*/
|
||||
protected $description = 'Updates quantity field in action_logs table for license seats that were added or deleted.';
|
||||
|
||||
/**
|
||||
* Execute the console command.
|
||||
*/
|
||||
public function handle()
|
||||
{
|
||||
$query = DB::table('action_logs')
|
||||
->whereIn('action_type', [
|
||||
ActionType::AddSeats->value,
|
||||
ActionType::DeleteSeats->value,
|
||||
])
|
||||
->where('quantity', '=', 1)
|
||||
->orderBy('id');
|
||||
|
||||
$count = $query->count();
|
||||
|
||||
if ($count === 0) {
|
||||
$this->info('Nothing to update');
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
$this->info("{$count} logs to update");
|
||||
|
||||
if ($this->option('no-interaction') || $this->confirm('Update quantities in the action log?')) {
|
||||
$query->chunk(50, function ($logs) {
|
||||
$logs->each(function ($log) {
|
||||
$quantityFromNote = Str::between($log->note, "ed ", " seats");
|
||||
|
||||
if (!is_numeric($quantityFromNote)) {
|
||||
$this->error('Could not parse quantity from ID: {id}', ['id' => $log->id]);
|
||||
}
|
||||
|
||||
if ($log->quantity !== (int) $quantityFromNote) {
|
||||
$this->info(vsprintf('Updating id: %s to quantity %s', [
|
||||
'id' => $log->id,
|
||||
'new_quantity' => $quantityFromNote,
|
||||
]));
|
||||
|
||||
DB::table('action_logs')->where('id', $log->id)->update(['quantity' => (int) $quantityFromNote]);
|
||||
}
|
||||
});
|
||||
});
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
@@ -33,6 +33,11 @@ class ObjectImportCommand extends Command
|
||||
*/
|
||||
protected ProgressIndicator $progressIndicator;
|
||||
|
||||
/**
|
||||
* Logger instance with configurable log path
|
||||
*/
|
||||
protected $logger;
|
||||
|
||||
/**
|
||||
* Create a new command instance.
|
||||
*
|
||||
@@ -65,9 +70,11 @@ class ObjectImportCommand extends Command
|
||||
->setShouldNotify($this->option('send-welcome'))
|
||||
->setUsernameFormat($this->option('username_format'));
|
||||
|
||||
// This $logFile/useFiles() bit is currently broken, so commenting it out for now
|
||||
// $logFile = $this->option('logfile');
|
||||
// Log::useFiles($logFile);
|
||||
$this->logger = Log::build([
|
||||
'driver' => 'single',
|
||||
'path' => $this->option('logfile'),
|
||||
]);
|
||||
|
||||
$this->progressIndicator->start('======= Importing Items from '.$filename.' =========');
|
||||
|
||||
$importer->import();
|
||||
@@ -99,10 +106,10 @@ class ObjectImportCommand extends Command
|
||||
public function log($string, $level = 'info')
|
||||
{
|
||||
if ($level === 'warning') {
|
||||
Log::warning($string);
|
||||
$this->logger->warning($string);
|
||||
$this->comment($string);
|
||||
} else {
|
||||
Log::Info($string);
|
||||
$this->logger->Info($string);
|
||||
if ($this->option('verbose')) {
|
||||
$this->comment($string);
|
||||
}
|
||||
|
||||
@@ -0,0 +1,132 @@
|
||||
<?php
|
||||
|
||||
namespace App\Console\Commands;
|
||||
|
||||
use App\Models\CheckoutAcceptance;
|
||||
use Carbon\Carbon;
|
||||
use Illuminate\Console\Command;
|
||||
use Illuminate\Support\Facades\Storage;
|
||||
|
||||
class PurgeEulaPDFs extends Command
|
||||
{
|
||||
/**
|
||||
* The name and signature of the console command.
|
||||
*
|
||||
* @var string
|
||||
*/
|
||||
protected $signature = 'snipeit:purge-eula-pdfs
|
||||
{--older-than-days= : The number of days we should delete before }
|
||||
{--force : Skip the interactive yes/no prompt for confirmation}
|
||||
{--dryrun : Show the records that would be deleted but don\'t update the database or delete files from disk}
|
||||
{--with-output : Display the results in a table in your console}';
|
||||
|
||||
/**
|
||||
* The console command description.
|
||||
*
|
||||
* @var string
|
||||
*/
|
||||
protected $description = 'This purges signature files and EULAs from the system if they are older than the date passed with --older-than-days=.';
|
||||
|
||||
/**
|
||||
* Execute the console command.
|
||||
*/
|
||||
public function handle()
|
||||
{
|
||||
|
||||
$before = $this->option('older-than-days');
|
||||
|
||||
if (($before=='') || (!is_numeric($before))) {
|
||||
return $this->error('ERROR: You must pass a valid number for --older-than-days (example: snipeit:purge-eula-pdfs --older-than-days=365.)');
|
||||
}
|
||||
|
||||
$interval_date = Carbon::now()->subDays($before);
|
||||
$signature_path = 'private_uploads/signatures/';
|
||||
$eula_path = 'private_uploads/eula-pdfs/';
|
||||
|
||||
if (!Storage::exists($eula_path)) {
|
||||
$this->fail('The storage directory "'.$eula_path.'" does not exist. No EULA files will be deleted.');
|
||||
}
|
||||
|
||||
if (!Storage::exists($signature_path)) {
|
||||
$this->fail('The storage directory "'.$signature_path.'" does not exist. No signature files will be deleted.');
|
||||
}
|
||||
|
||||
|
||||
if ($this->option('dryrun')) {
|
||||
$this->info('This script is being run with the --dryrun option. No files or records will be deleted.');
|
||||
|
||||
}
|
||||
$acceptances = CheckoutAcceptance::HasFiles()->where('updated_at','<', $interval_date)->with('assignedTo')->get();
|
||||
|
||||
if (!$this->option('force')) {
|
||||
if ($this->confirm("\n****************************************************\nTHIS WILL DELETE ALL OF THE SIGNATURES AND EULA PDF FILES SINCE $interval_date. \nThere is NO undo! \n****************************************************\n\nDo you wish to continue? No backsies! [y|N]")) {
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
||||
if ($acceptances->count() == 0) {
|
||||
return $this->warn('There are no item acceptances with signatures or EULA PDFs from before '.$interval_date);
|
||||
}
|
||||
|
||||
$this->info(number_format($acceptances->count()) . ' EULA PDFs from before '.$interval_date.' will be purged');
|
||||
|
||||
if (!$this->option('with-output')) {
|
||||
$this->info('Run this command with the --with-output option to see the full list in the console.');
|
||||
} else {
|
||||
$this->table(
|
||||
[
|
||||
trans('general.user'),
|
||||
trans('general.type'),
|
||||
trans('general.item'),
|
||||
trans('general.category'),
|
||||
trans('general.accepted_date'),
|
||||
trans('general.declined_date'),
|
||||
trans('general.signature'),
|
||||
trans('general.filename'),
|
||||
|
||||
],
|
||||
$acceptances->map(fn($acceptance) => [
|
||||
trans('general.user') => $acceptance->assignedTo->display_name,
|
||||
trans('general.type') => $acceptance->display_checkoutable_type,
|
||||
trans('general.item') => $acceptance->checkoutable_type::find($acceptance->checkoutable_id)->display_name,
|
||||
trans('general.category') => $acceptance->checkoutable_category_name,
|
||||
trans('general.accepted_date') => $acceptance->accepted_at,
|
||||
trans('general.declined_date') => $acceptance->declined_at,
|
||||
trans('general.signature') => $acceptance->signature_filename,
|
||||
trans('general.filename') => $acceptance->stored_eula_file,
|
||||
])
|
||||
);
|
||||
}
|
||||
|
||||
|
||||
|
||||
foreach ($acceptances as $acceptance) {
|
||||
|
||||
$signature_file = $signature_path.$acceptance->signature_filename;
|
||||
$eula_file = $eula_path.$acceptance->stored_eula_file;
|
||||
|
||||
if (Storage::exists($signature_file)) {
|
||||
if (!$this->option('dryrun')) {
|
||||
Storage::delete($signature_file);
|
||||
}
|
||||
} else {
|
||||
$this->error('The file "'. $signature_file.'" does not exist.');
|
||||
}
|
||||
|
||||
|
||||
if (Storage::exists($eula_file)) {
|
||||
if (!$this->option('dryrun')) {
|
||||
Storage::delete($eula_file);
|
||||
}
|
||||
} else {
|
||||
$this->error('The file "'.$eula_file.'" does not exist.');
|
||||
}
|
||||
|
||||
if (!$this->option('dryrun')) {
|
||||
$acceptance->delete();
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
@@ -50,8 +50,8 @@ class ResetDemoSettings extends Command
|
||||
$settings->alert_email = 'service@snipe-it.io';
|
||||
$settings->login_note = 'Use `admin` / `password` to login to the demo.';
|
||||
$settings->header_color = '#3c8dbc';
|
||||
$settings->link_dark_color = '#86cbf2';
|
||||
$settings->link_light_color = '#084d73;';
|
||||
$settings->link_dark_color = '#5fa4cc';
|
||||
$settings->link_light_color = '#296282;';
|
||||
$settings->label2_2d_type = 'QRCODE';
|
||||
$settings->default_currency = 'USD';
|
||||
$settings->brand = 2;
|
||||
|
||||
@@ -55,6 +55,8 @@ class SendExpirationAlerts extends Command
|
||||
// Expiring Assets
|
||||
$assets = Asset::getExpiringWarrantyOrEol($alert_interval);
|
||||
|
||||
$assets->load(['assignedTo', 'supplier']);
|
||||
|
||||
if ($assets->count() > 0) {
|
||||
|
||||
Mail::to($recipients)->send(new ExpiringAssetsMail($assets, $alert_interval));
|
||||
|
||||
@@ -15,18 +15,20 @@ class CheckoutableCheckedOut
|
||||
public $checkedOutBy;
|
||||
public $note;
|
||||
public $originalValues;
|
||||
public int $quantity;
|
||||
|
||||
/**
|
||||
* Create a new event instance.
|
||||
*
|
||||
* @return void
|
||||
*/
|
||||
public function __construct($checkoutable, $checkedOutTo, User $checkedOutBy, $note, $originalValues = [])
|
||||
public function __construct($checkoutable, $checkedOutTo, User $checkedOutBy, $note, $originalValues = [], $quantity = 1)
|
||||
{
|
||||
$this->checkoutable = $checkoutable;
|
||||
$this->checkedOutTo = $checkedOutTo;
|
||||
$this->checkedOutBy = $checkedOutBy;
|
||||
$this->note = $note;
|
||||
$this->originalValues = $originalValues;
|
||||
$this->quantity = $quantity;
|
||||
}
|
||||
}
|
||||
|
||||
+97
-5
@@ -2,6 +2,7 @@
|
||||
|
||||
namespace App\Helpers;
|
||||
use App\Models\Accessory;
|
||||
use App\Models\Actionlog;
|
||||
use App\Models\Asset;
|
||||
use App\Models\AssetModel;
|
||||
use App\Models\Component;
|
||||
@@ -13,6 +14,7 @@ use App\Models\Setting;
|
||||
use App\Models\Statuslabel;
|
||||
use App\Models\License;
|
||||
use App\Models\Location;
|
||||
use Illuminate\Database\Eloquent\Collection;
|
||||
use Illuminate\Http\RedirectResponse;
|
||||
use Illuminate\Support\Facades\Crypt;
|
||||
use Illuminate\Contracts\Encryption\DecryptException;
|
||||
@@ -776,7 +778,7 @@ class Helper
|
||||
$consumables = Consumable::withCount('consumableAssignments as consumable_assignments_count')->whereNotNull('min_amt')->get();
|
||||
$accessories = Accessory::withCount('checkouts as checkouts_count')->whereNotNull('min_amt')->get();
|
||||
$components = Component::whereNotNull('min_amt')->get();
|
||||
$asset_models = AssetModel::where('min_amt', '>', 0)->get();
|
||||
$asset_models = AssetModel::where('min_amt', '>', 0)->withCount(['availableAssets', 'assets'])->get();
|
||||
$licenses = License::where('min_amt', '>', 0)->get();
|
||||
|
||||
$items_array = [];
|
||||
@@ -842,8 +844,8 @@ class Helper
|
||||
foreach ($asset_models as $asset_model){
|
||||
|
||||
$asset = new Asset();
|
||||
$total_owned = $asset->where('model_id', '=', $asset_model->id)->count();
|
||||
$avail = $asset->where('model_id', '=', $asset_model->id)->whereNull('assigned_to')->count();
|
||||
$total_owned = $asset_model->assets_count; //requires the withCount() clause in the initial query!
|
||||
$avail = $asset_model->available_assets_count; //requires the withCount() clause in the initial query!
|
||||
|
||||
if ($avail <= ($asset_model->min_amt) + $alert_threshold) {
|
||||
if ($avail > 0) {
|
||||
@@ -1384,7 +1386,19 @@ class Helper
|
||||
* @return string[]
|
||||
*/
|
||||
public static function SettingUrls(){
|
||||
$settings=['#','fields.index', 'statuslabels.index', 'models.index', 'categories.index', 'manufacturers.index', 'suppliers.index', 'departments.index', 'locations.index', 'companies.index', 'depreciations.index'];
|
||||
$settings=[
|
||||
'#',
|
||||
'fields*',
|
||||
'statuslabels*',
|
||||
'models*',
|
||||
'categories*',
|
||||
'manufacturers*',
|
||||
'suppliers*',
|
||||
'departments*',
|
||||
'locations*',
|
||||
'companies*',
|
||||
'depreciations*'
|
||||
];
|
||||
|
||||
return $settings;
|
||||
}
|
||||
@@ -1570,7 +1584,6 @@ class Helper
|
||||
]) ? 'rtl' : 'ltr';
|
||||
}
|
||||
|
||||
|
||||
static public function getRedirectOption($request, $id, $table, $item_id = null) : RedirectResponse
|
||||
{
|
||||
|
||||
@@ -1735,4 +1748,83 @@ class Helper
|
||||
}
|
||||
return $mismatched;
|
||||
}
|
||||
static public function labelFieldLayoutScaling(
|
||||
$pdf,
|
||||
iterable|\Closure $fields,
|
||||
float $currentX,
|
||||
float $usableWidth,
|
||||
float $usableHeight,
|
||||
float $baseLabelSize,
|
||||
float $baseFieldSize,
|
||||
float $baseFieldMargin,
|
||||
?string $title = null,
|
||||
float $baseTitleSize = 0.0,
|
||||
float $baseTitleMargin = 0.0,
|
||||
float $baseLabelPadding = 1.5,
|
||||
float $baseGap = 1.5,
|
||||
float $maxScale = 1.8,
|
||||
string $labelFont = 'freesans',
|
||||
|
||||
) : array
|
||||
{
|
||||
$fieldCount = count($fields);
|
||||
$perFieldHeight = max($baseLabelSize, $baseFieldSize) + $baseFieldMargin;
|
||||
$baseFieldsHeight = $fieldCount * $perFieldHeight;
|
||||
|
||||
$hasTitle = is_string($title) && trim($title) !== '';
|
||||
$baseTitleHeight = $hasTitle ? ($baseTitleSize + $baseTitleMargin) : 0.0;
|
||||
$baseTotalHeight = $baseTitleHeight + $baseFieldsHeight;
|
||||
$scale = 1.0;
|
||||
if ($baseTotalHeight > 0 && $usableHeight > 0) {
|
||||
$scale = $usableHeight / $baseTotalHeight;
|
||||
}
|
||||
|
||||
$scale = min($scale, $maxScale);
|
||||
|
||||
$labelSize = $baseLabelSize;
|
||||
$fieldSize = $baseFieldSize * $scale;
|
||||
$fieldMargin = $baseFieldMargin * $scale;
|
||||
|
||||
$rowAdvance = max($labelSize, $fieldSize) + $fieldMargin;
|
||||
$titleSize = $hasTitle ? ($baseTitleSize * $scale) : 0.0;
|
||||
$titleMargin = $hasTitle ? ($baseTitleMargin * $scale) : 0.0;
|
||||
$titleAdvance = $hasTitle ? ($titleSize + $titleMargin) : 0.0;
|
||||
|
||||
$pdf->SetFont($labelFont, '', $baseLabelSize);
|
||||
|
||||
$maxLabelWidthPerUnit = 0;
|
||||
foreach ($fields as $field) {
|
||||
$rawLabel = $field['label'] ?? null;
|
||||
|
||||
// If no label, do not include it in label-column sizing
|
||||
if (!is_string($rawLabel) || trim($rawLabel) === '') {
|
||||
continue;
|
||||
}
|
||||
$label = rtrim($field['label'], ':') . ':';
|
||||
$width = $pdf->GetStringWidth($label);
|
||||
$maxLabelWidthPerUnit = max($maxLabelWidthPerUnit, $width / $baseLabelSize);
|
||||
}
|
||||
|
||||
$labelPadding = $baseLabelPadding * $scale;
|
||||
$gap = $baseGap * $scale;
|
||||
|
||||
$labelWidth = ($maxLabelWidthPerUnit * $labelSize) + $labelPadding;
|
||||
$valueX = $currentX + $labelWidth + $gap;
|
||||
$valueWidth = $usableWidth - $labelWidth - $gap;
|
||||
|
||||
return compact(
|
||||
'scale',
|
||||
'hasTitle',
|
||||
'titleSize',
|
||||
'titleMargin',
|
||||
'titleAdvance',
|
||||
'labelSize',
|
||||
'fieldSize',
|
||||
'fieldMargin',
|
||||
'rowAdvance',
|
||||
'labelWidth',
|
||||
'valueX',
|
||||
'valueWidth'
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -46,6 +46,8 @@ class IconHelper
|
||||
return 'fa-regular fa-envelope';
|
||||
case 'phone':
|
||||
return 'fa-solid fa-phone';
|
||||
case 'fax':
|
||||
return 'fa-solid fa-fax';
|
||||
case 'mobile':
|
||||
return 'fas fa-mobile-screen-button';
|
||||
case 'long-arrow-right':
|
||||
@@ -53,7 +55,7 @@ class IconHelper
|
||||
case 'download':
|
||||
return 'fas fa-download';
|
||||
case 'checkmark':
|
||||
return 'fas fa-check icon-white';
|
||||
return 'fas fa-check';
|
||||
case 'x':
|
||||
return 'fas fa-times';
|
||||
case 'logout':
|
||||
@@ -129,9 +131,12 @@ class IconHelper
|
||||
return 'fa-regular fa-clipboard';
|
||||
case 'paperclip':
|
||||
return 'fas fa-paperclip';
|
||||
case 'contact-card':
|
||||
return 'fa-regular fa-id-card';
|
||||
case 'files':
|
||||
return 'fa-regular fa-file';
|
||||
case 'more-info':
|
||||
case 'support':
|
||||
return 'far fa-life-ring';
|
||||
case 'calendar':
|
||||
return 'fas fa-calendar';
|
||||
@@ -142,7 +147,7 @@ class IconHelper
|
||||
case 'more-files':
|
||||
return 'fa-solid fa-laptop-file';
|
||||
case 'maintenances':
|
||||
return 'fas fa-wrench';
|
||||
return 'fa-solid fa-screwdriver-wrench';
|
||||
case 'seats':
|
||||
return 'far fa-list-alt';
|
||||
case 'globe-us':
|
||||
@@ -201,6 +206,54 @@ class IconHelper
|
||||
return 'fa-solid fa-lightbulb';
|
||||
case 'highlight':
|
||||
return 'fa-solid fa-highlighter';
|
||||
case 'manager':
|
||||
return 'fa-solid fa-building-user';
|
||||
case 'company':
|
||||
return 'fa-regular fa-building';
|
||||
case 'parent':
|
||||
return 'fa-solid fa-building-flag';
|
||||
case 'number':
|
||||
return 'fa-solid fa-hashtag';
|
||||
case 'depreciation':
|
||||
return 'fa-solid fa-arrows-down-to-line';
|
||||
case 'depreciation-calendar':
|
||||
case 'expiration':
|
||||
case 'terminates':
|
||||
return 'fa-regular fa-calendar-xmark';
|
||||
case 'manufacturer':
|
||||
return 'fa-solid fa-industry';
|
||||
case 'fieldset' :
|
||||
return 'fa-regular fa-rectangle-list';
|
||||
case 'deleted-date':
|
||||
return 'fa-solid fa-calendar-xmark';
|
||||
case 'eol':
|
||||
return 'fa-regular fa-calendar-days';
|
||||
case 'category':
|
||||
return 'fa-solid fa-icons';
|
||||
case 'cost':
|
||||
return 'fa-solid fa-money-bills';
|
||||
case 'available':
|
||||
return 'fa-solid fa-box';
|
||||
case 'checkedout':
|
||||
return 'fa-solid fa-box-open';
|
||||
case 'purchase_order':
|
||||
return 'fa-solid fa-file-invoice-dollar';
|
||||
case 'order':
|
||||
return 'fa-solid fa-file-invoice';
|
||||
case 'checkout-all':
|
||||
return 'fa-solid fa-arrows-down-to-people';
|
||||
case 'square-right':
|
||||
return 'fa-regular fa-square-caret-right';
|
||||
case 'square-left':
|
||||
return 'fa-regular fa-square-caret-left';
|
||||
case 'square':
|
||||
return 'fa-solid fa-square';
|
||||
case 'models':
|
||||
case 'model':
|
||||
return 'fa-solid fa-boxes-stacked';
|
||||
case 'min-qty':
|
||||
return 'fa-solid fa-chart-pie';
|
||||
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -90,10 +90,10 @@ class AccessoriesController extends Controller
|
||||
$accessory = $request->handleImages($accessory);
|
||||
}
|
||||
|
||||
if($request->get('redirect_option') === 'back'){
|
||||
if($request->input('redirect_option') === 'back'){
|
||||
session()->put(['redirect_option' => 'index']);
|
||||
} else {
|
||||
session()->put(['redirect_option' => $request->get('redirect_option')]);
|
||||
session()->put(['redirect_option' => $request->input('redirect_option')]);
|
||||
}
|
||||
|
||||
// Was the accessory created?
|
||||
@@ -182,10 +182,10 @@ class AccessoriesController extends Controller
|
||||
|
||||
$accessory = $request->handleImages($accessory);
|
||||
|
||||
if($request->get('redirect_option') === 'back'){
|
||||
if($request->input('redirect_option') === 'back'){
|
||||
session()->put(['redirect_option' => 'index']);
|
||||
} else {
|
||||
session()->put(['redirect_option' => $request->get('redirect_option')]);
|
||||
session()->put(['redirect_option' => $request->input('redirect_option')]);
|
||||
}
|
||||
|
||||
if ($accessory->save()) {
|
||||
|
||||
@@ -76,7 +76,7 @@ class AccessoryCheckinController extends Controller
|
||||
if ($accessory_checkout->delete()) {
|
||||
event(new CheckoutableCheckedIn($accessory, $accessory_checkout->assignedTo, auth()->user(), $request->input('note'), $checkin_at));
|
||||
|
||||
session()->put(['redirect_option' => $request->get('redirect_option')]);
|
||||
session()->put(['redirect_option' => $request->input('redirect_option')]);
|
||||
|
||||
return Helper::getRedirectOption($request, $accessory->id, 'Accessories')
|
||||
->with('success', trans('admin/accessories/message.checkin.success'));
|
||||
|
||||
@@ -67,7 +67,7 @@ class AccessoryCheckoutController extends Controller
|
||||
*/
|
||||
public function store(AccessoryCheckoutRequest $request, Accessory $accessory) : RedirectResponse
|
||||
{
|
||||
|
||||
|
||||
$this->authorize('checkout', $accessory);
|
||||
|
||||
$target = $this->determineCheckoutTarget();
|
||||
@@ -89,12 +89,19 @@ class AccessoryCheckoutController extends Controller
|
||||
$accessory_checkout->save();
|
||||
}
|
||||
|
||||
event(new CheckoutableCheckedOut($accessory, $target, auth()->user(), $request->input('note')));
|
||||
event(new CheckoutableCheckedOut(
|
||||
$accessory,
|
||||
$target,
|
||||
auth()->user(),
|
||||
$request->input('note'),
|
||||
[],
|
||||
$accessory->checkout_qty,
|
||||
));
|
||||
|
||||
$request->request->add(['checkout_to_type' => request('checkout_to_type')]);
|
||||
$request->request->add(['assigned_to' => $target->id]);
|
||||
|
||||
session()->put(['redirect_option' => $request->get('redirect_option'), 'checkout_to_type' => $request->get('checkout_to_type')]);
|
||||
session()->put(['redirect_option' => $request->input('redirect_option'), 'checkout_to_type' => $request->input('checkout_to_type')]);
|
||||
|
||||
|
||||
// Redirect to the new accessory page
|
||||
|
||||
@@ -325,7 +325,14 @@ class AccessoriesController extends Controller
|
||||
}
|
||||
|
||||
// Set this value to be able to pass the qty through to the event
|
||||
event(new CheckoutableCheckedOut($accessory, $target, auth()->user(), $request->input('note')));
|
||||
event(new CheckoutableCheckedOut(
|
||||
$accessory,
|
||||
$target,
|
||||
auth()->user(),
|
||||
$request->input('note'),
|
||||
[],
|
||||
$accessory->checkout_qty,
|
||||
));
|
||||
|
||||
return response()->json(Helper::formatStandardApiResponse('success', $payload, trans('admin/accessories/message.checkout.success')));
|
||||
|
||||
@@ -389,7 +396,7 @@ class AccessoriesController extends Controller
|
||||
]);
|
||||
|
||||
if ($request->filled('search')) {
|
||||
$accessories = $accessories->where('accessories.name', 'LIKE', '%'.$request->get('search').'%');
|
||||
$accessories = $accessories->where('accessories.name', 'LIKE', '%'.$request->input('search').'%');
|
||||
}
|
||||
|
||||
$accessories = $accessories->orderBy('name', 'ASC')->paginate(50);
|
||||
|
||||
@@ -249,7 +249,7 @@ class AssetModelsController extends Controller
|
||||
* it, but I'll be damned if I can think of one. - snipe
|
||||
*/
|
||||
if ($request->filled('custom_fieldset_id')) {
|
||||
$assetmodel->fieldset_id = $request->get('custom_fieldset_id');
|
||||
$assetmodel->fieldset_id = $request->input('custom_fieldset_id');
|
||||
}
|
||||
|
||||
|
||||
|
||||
@@ -15,6 +15,7 @@ use App\Http\Transformers\ComponentsTransformer;
|
||||
use App\Http\Transformers\LicensesTransformer;
|
||||
use App\Http\Transformers\SelectlistTransformer;
|
||||
use App\Models\AccessoryCheckout;
|
||||
use App\Models\Actionlog;
|
||||
use App\Models\Asset;
|
||||
use App\Models\AssetModel;
|
||||
use App\Models\CheckoutAcceptance;
|
||||
@@ -153,6 +154,15 @@ class AssetsController extends Controller
|
||||
}
|
||||
|
||||
$assets = Asset::select('assets.*')
|
||||
->addSelect([
|
||||
'first_checkout_at' => Actionlog::query()
|
||||
->select('created_at')
|
||||
->whereColumn('item_id', 'assets.id')
|
||||
->where('item_type', Asset::class)
|
||||
->where('action_type', 'checkout')
|
||||
->orderBy('created_at')
|
||||
->limit(1),
|
||||
])
|
||||
->with(
|
||||
'model',
|
||||
'location',
|
||||
@@ -377,7 +387,7 @@ class AssetsController extends Controller
|
||||
}
|
||||
|
||||
if ($request->filled('order_number')) {
|
||||
$assets->where('assets.order_number', '=', strval($request->get('order_number')));
|
||||
$assets->where('assets.order_number', '=', strval($request->input('order_number')));
|
||||
}
|
||||
|
||||
// This is kinda gross, but we need to do this because the Bootstrap Tables
|
||||
@@ -654,7 +664,7 @@ class AssetsController extends Controller
|
||||
public function store(StoreAssetRequest $request): JsonResponse
|
||||
{
|
||||
$asset = new Asset();
|
||||
$asset->model()->associate(AssetModel::find((int) $request->get('model_id')));
|
||||
$asset->model()->associate(AssetModel::find((int) $request->input('model_id')));
|
||||
|
||||
$asset->fill($request->validated());
|
||||
$asset->created_by = auth()->id();
|
||||
@@ -683,8 +693,8 @@ class AssetsController extends Controller
|
||||
// If input value is null, use custom field's default value
|
||||
if ($field_val == null) {
|
||||
Log::debug('Field value for ' . $field->db_column . ' is null');
|
||||
$field_val = $field->defaultValue($request->get('model_id'));
|
||||
Log::debug('Use the default fieldset value of ' . $field->defaultValue($request->get('model_id')));
|
||||
$field_val = $field->defaultValue($request->input('model_id'));
|
||||
Log::debug('Use the default fieldset value of ' . $field->defaultValue($request->input('model_id')));
|
||||
}
|
||||
|
||||
// if the field is set to encrypted, make sure we encrypt the value
|
||||
@@ -695,7 +705,7 @@ class AssetsController extends Controller
|
||||
|
||||
// If input value is null, use custom field's default value
|
||||
if (($field_val == null) && ($request->has('model_id') != '')) {
|
||||
$field_val = Crypt::encrypt($field->defaultValue($request->get('model_id')));
|
||||
$field_val = Crypt::encrypt($field->defaultValue($request->input('model_id')));
|
||||
} else {
|
||||
$field_val = Crypt::encrypt($request->input($field->db_column));
|
||||
}
|
||||
@@ -713,15 +723,15 @@ class AssetsController extends Controller
|
||||
}
|
||||
|
||||
if ($asset->save()) {
|
||||
if ($request->get('assigned_user')) {
|
||||
if ($request->input('assigned_user')) {
|
||||
$target = User::find(request('assigned_user'));
|
||||
} elseif ($request->get('assigned_asset')) {
|
||||
} elseif ($request->input('assigned_asset')) {
|
||||
$target = Asset::find(request('assigned_asset'));
|
||||
} elseif ($request->get('assigned_location')) {
|
||||
} elseif ($request->input('assigned_location')) {
|
||||
$target = Location::find(request('assigned_location'));
|
||||
}
|
||||
if (isset($target)) {
|
||||
$asset->checkOut($target, auth()->user(), date('Y-m-d H:i:s'), '', 'Checked out on asset creation', e($request->get('name')));
|
||||
$asset->checkOut($target, auth()->user(), date('Y-m-d H:i:s'), '', 'Checked out on asset creation', e($request->input('name')));
|
||||
}
|
||||
|
||||
if ($asset->image) {
|
||||
@@ -798,19 +808,22 @@ class AssetsController extends Controller
|
||||
}
|
||||
}
|
||||
if ($asset->save()) {
|
||||
if (($request->filled('assigned_user')) && ($target = User::find($request->get('assigned_user')))) {
|
||||
if (($request->filled('assigned_user')) && ($target = User::find($request->input('assigned_user')))) {
|
||||
$location = $target->location_id;
|
||||
} elseif (($request->filled('assigned_asset')) && ($target = Asset::find($request->get('assigned_asset')))) {
|
||||
} elseif (($request->filled('assigned_asset')) && ($target = Asset::find($request->input('assigned_asset')))) {
|
||||
$location = $target->location_id;
|
||||
|
||||
Asset::where('assigned_type', \App\Models\Asset::class)->where('assigned_to', $asset->id)
|
||||
->update(['location_id' => $target->location_id]);
|
||||
} elseif (($request->filled('assigned_location')) && ($target = Location::find($request->get('assigned_location')))) {
|
||||
} elseif (($request->filled('assigned_location')) && ($target = Location::find($request->input('assigned_location')))) {
|
||||
$location = $target->id;
|
||||
}
|
||||
|
||||
if (isset($target)) {
|
||||
$asset->checkOut($target, auth()->user(), date('Y-m-d H:i:s'), '', 'Checked out on asset update', e($request->get('name')), $location);
|
||||
// Using `->has` preserves the asset name if the name parameter was not included in request.
|
||||
$asset_name = request()->has('name') ? request('name') : $asset->name;
|
||||
|
||||
$asset->checkOut($target, auth()->user(), date('Y-m-d H:i:s'), '', 'Checked out on asset update', $asset_name, $location);
|
||||
}
|
||||
|
||||
if ($asset->image) {
|
||||
@@ -954,7 +967,7 @@ class AssetsController extends Controller
|
||||
}
|
||||
|
||||
if ($request->filled('status_id')) {
|
||||
$asset->status_id = $request->get('status_id');
|
||||
$asset->status_id = $request->input('status_id');
|
||||
}
|
||||
|
||||
if (! isset($target)) {
|
||||
@@ -1034,7 +1047,7 @@ class AssetsController extends Controller
|
||||
$checkin_at = $request->filled('checkin_at') ? $request->input('checkin_at') . ' ' . date('H:i:s') : date('Y-m-d H:i:s');
|
||||
$originalValues = $asset->getRawOriginal();
|
||||
|
||||
if (($request->filled('checkin_at')) && ($request->get('checkin_at') != date('Y-m-d'))) {
|
||||
if (($request->filled('checkin_at')) && ($request->input('checkin_at') != date('Y-m-d'))) {
|
||||
$originalValues['action_date'] = $checkin_at;
|
||||
}
|
||||
|
||||
@@ -1143,7 +1156,7 @@ class AssetsController extends Controller
|
||||
/**
|
||||
* Update custom fields in the database.
|
||||
* Validation for these fields is handled through the AssetRequest form request
|
||||
* $model = AssetModel::find($request->get('model_id'));
|
||||
* $model = AssetModel::find($request->input('model_id'));
|
||||
*/
|
||||
if (($asset->model) && ($asset->model->fieldset)) {
|
||||
$payload['custom_fields'] = [];
|
||||
|
||||
@@ -265,7 +265,7 @@ class CategoriesController extends Controller
|
||||
]);
|
||||
|
||||
if ($request->filled('search')) {
|
||||
$categories = $categories->where('name', 'LIKE', '%'.$request->get('search').'%');
|
||||
$categories = $categories->where('name', 'LIKE', '%'.$request->input('search').'%');
|
||||
}
|
||||
|
||||
$categories = $categories->where('category_type', $category_type)->orderBy('name', 'ASC')->paginate(50);
|
||||
|
||||
@@ -202,7 +202,7 @@ class CompaniesController extends Controller
|
||||
|
||||
|
||||
if ($request->filled('search')) {
|
||||
$companies = $companies->where('companies.name', 'LIKE', '%'.$request->get('search').'%');
|
||||
$companies = $companies->where('companies.name', 'LIKE', '%'.$request->input('search').'%');
|
||||
}
|
||||
|
||||
$companies = $companies->orderBy('name', 'ASC')->paginate(50);
|
||||
|
||||
@@ -59,7 +59,7 @@ class ComponentsController extends Controller
|
||||
|
||||
$components = Component::select('components.*')
|
||||
->with('company', 'location', 'category', 'supplier', 'adminuser', 'manufacturer')
|
||||
->withSum('uncontrainedAssets as sum_unconstrained_assets', 'components_assets.assigned_qty');
|
||||
->withSum('unconstrainedAssets as sum_unconstrained_assets', 'components_assets.assigned_qty');
|
||||
|
||||
$filter = [];
|
||||
|
||||
@@ -303,11 +303,11 @@ class ComponentsController extends Controller
|
||||
}
|
||||
|
||||
// Make sure there is at least one available to checkout
|
||||
if ($component->numRemaining() < $request->get('assigned_qty')) {
|
||||
return response()->json(Helper::formatStandardApiResponse('error', null, trans('admin/components/message.checkout.unavailable', ['remaining' => $component->numRemaining(), 'requested' => $request->get('assigned_qty')])));
|
||||
if ($component->numRemaining() < $request->input('assigned_qty')) {
|
||||
return response()->json(Helper::formatStandardApiResponse('error', null, trans('admin/components/message.checkout.unavailable', ['remaining' => $component->numRemaining(), 'requested' => $request->input('assigned_qty')])));
|
||||
}
|
||||
|
||||
if ($component->numRemaining() >= $request->get('assigned_qty')) {
|
||||
if ($component->numRemaining() >= $request->input('assigned_qty')) {
|
||||
|
||||
$asset = Asset::find($request->input('assigned_to'));
|
||||
$component->assigned_to = $request->input('assigned_to');
|
||||
@@ -315,18 +315,18 @@ class ComponentsController extends Controller
|
||||
$component->assets()->attach($component->id, [
|
||||
'component_id' => $component->id,
|
||||
'created_at' => Carbon::now(),
|
||||
'assigned_qty' => $request->get('assigned_qty', 1),
|
||||
'assigned_qty' => $request->input('assigned_qty', 1),
|
||||
'created_by' => auth()->id(),
|
||||
'asset_id' => $request->get('assigned_to'),
|
||||
'note' => $request->get('note'),
|
||||
'asset_id' => $request->input('assigned_to'),
|
||||
'note' => $request->input('note'),
|
||||
]);
|
||||
|
||||
$component->logCheckout($request->input('note'), $asset);
|
||||
$component->logCheckout($request->input('note'), $asset, null, [], $request->get('assigned_qty', 1));
|
||||
|
||||
return response()->json(Helper::formatStandardApiResponse('success', null, trans('admin/components/message.checkout.success')));
|
||||
}
|
||||
|
||||
return response()->json(Helper::formatStandardApiResponse('error', null, trans('admin/components/message.checkout.unavailable', ['remaining' => $component->numRemaining(), 'requested' => $request->get('assigned_qty')])));
|
||||
return response()->json(Helper::formatStandardApiResponse('error', null, trans('admin/components/message.checkout.unavailable', ['remaining' => $component->numRemaining(), 'requested' => $request->input('assigned_qty')])));
|
||||
}
|
||||
|
||||
/**
|
||||
|
||||
@@ -326,8 +326,14 @@ class ConsumablesController extends Controller
|
||||
);
|
||||
}
|
||||
|
||||
|
||||
event(new CheckoutableCheckedOut($consumable, $user, auth()->user(), $request->input('note')));
|
||||
event(new CheckoutableCheckedOut(
|
||||
$consumable,
|
||||
$user,
|
||||
auth()->user(),
|
||||
$request->input('note'),
|
||||
[],
|
||||
$consumable->checkout_qty,
|
||||
));
|
||||
|
||||
return response()->json(Helper::formatStandardApiResponse('success', null, trans('admin/consumables/message.checkout.success')));
|
||||
|
||||
@@ -346,7 +352,7 @@ class ConsumablesController extends Controller
|
||||
]);
|
||||
|
||||
if ($request->filled('search')) {
|
||||
$consumables = $consumables->where('consumables.name', 'LIKE', '%'.$request->get('search').'%');
|
||||
$consumables = $consumables->where('consumables.name', 'LIKE', '%'.$request->input('search').'%');
|
||||
}
|
||||
|
||||
$consumables = $consumables->orderBy('name', 'ASC')->paginate(50);
|
||||
|
||||
@@ -195,7 +195,7 @@ class DepartmentsController extends Controller
|
||||
]);
|
||||
|
||||
if ($request->filled('search')) {
|
||||
$departments = $departments->where('name', 'LIKE', '%'.$request->get('search').'%');
|
||||
$departments = $departments->where('name', 'LIKE', '%'.$request->input('search').'%');
|
||||
}
|
||||
|
||||
$departments = $departments->orderBy('name', 'ASC')->paginate(50);
|
||||
|
||||
@@ -196,7 +196,7 @@ class ImportController extends Controller
|
||||
$this->authorize('import');
|
||||
|
||||
// Run a backup immediately before processing
|
||||
if ($request->get('run-backup')) {
|
||||
if ($request->input('run-backup')) {
|
||||
Log::debug('Backup manually requested via importer');
|
||||
Artisan::call('snipeit:backup', ['--filename' => 'pre-import-backup-'.date('Y-m-d-H-i-s')]);
|
||||
} else {
|
||||
@@ -212,7 +212,7 @@ class ImportController extends Controller
|
||||
|
||||
$errors = $request->import($import);
|
||||
$redirectTo = 'hardware.index';
|
||||
switch ($request->get('import-type')) {
|
||||
switch ($request->input('import-type')) {
|
||||
case 'asset':
|
||||
$model_perms = 'App\Models\Asset';
|
||||
$redirectTo = 'hardware.index';
|
||||
|
||||
@@ -24,7 +24,7 @@ class LabelsController extends Controller
|
||||
$labels = Label::find();
|
||||
|
||||
if ($request->filled('search')) {
|
||||
$search = $request->get('search');
|
||||
$search = $request->input('search');
|
||||
$labels = $labels->filter(function ($label, $index) use ($search) {
|
||||
return stripos($label->getName(), $search) !== false;
|
||||
});
|
||||
@@ -32,11 +32,11 @@ class LabelsController extends Controller
|
||||
|
||||
$total = $labels->count();
|
||||
|
||||
$offset = $request->get('offset', 0);
|
||||
$offset = $request->input('offset', 0);
|
||||
$offset = ($offset > $total) ? $total : $offset;
|
||||
|
||||
$maxLimit = config('app.max_results');
|
||||
$limit = $request->get('limit', $maxLimit);
|
||||
$limit = $request->input('limit', $maxLimit);
|
||||
$limit = ($limit > $maxLimit) ? $maxLimit : $limit;
|
||||
|
||||
$labels = $labels->skip($offset)->take($limit);
|
||||
|
||||
@@ -265,7 +265,7 @@ class LicensesController extends Controller
|
||||
]);
|
||||
|
||||
if ($request->filled('search')) {
|
||||
$licenses = $licenses->where('licenses.name', 'LIKE', '%'.$request->get('search').'%');
|
||||
$licenses = $licenses->where('licenses.name', 'LIKE', '%'.$request->input('search').'%');
|
||||
}
|
||||
|
||||
$licenses = $licenses->orderBy('name', 'ASC')->paginate(50);
|
||||
|
||||
@@ -200,7 +200,7 @@ class LocationsController extends Controller
|
||||
|
||||
// Only scope location if the setting is enabled
|
||||
if (Setting::getSettings()->scope_locations_fmcs) {
|
||||
$location->company_id = Company::getIdForCurrentUser($request->get('company_id'));
|
||||
$location->company_id = Company::getIdForCurrentUser($request->input('company_id'));
|
||||
// check if parent is set and has a different company
|
||||
if ($location->parent_id && Location::find($location->parent_id)->company_id != $location->company_id) {
|
||||
response()->json(Helper::formatStandardApiResponse('error', null, 'different company than parent'));
|
||||
@@ -278,13 +278,13 @@ class LocationsController extends Controller
|
||||
if ($request->filled('company_id')) {
|
||||
// Only scope location if the setting is enabled
|
||||
if (Setting::getSettings()->scope_locations_fmcs) {
|
||||
$location->company_id = Company::getIdForCurrentUser($request->get('company_id'));
|
||||
$location->company_id = Company::getIdForCurrentUser($request->input('company_id'));
|
||||
// check if there are related objects with different company
|
||||
if (Helper::test_locations_fmcs(false, $id, $location->company_id)) {
|
||||
return response()->json(Helper::formatStandardApiResponse('error', null, 'error scoped locations'));
|
||||
}
|
||||
} else {
|
||||
$location->company_id = $request->get('company_id');
|
||||
$location->company_id = $request->input('company_id');
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -274,7 +274,7 @@ class ManufacturersController extends Controller
|
||||
]);
|
||||
|
||||
if ($request->filled('search')) {
|
||||
$manufacturers = $manufacturers->where('name', 'LIKE', '%'.$request->get('search').'%');
|
||||
$manufacturers = $manufacturers->where('name', 'LIKE', '%'.$request->input('search').'%');
|
||||
}
|
||||
|
||||
$manufacturers = $manufacturers->orderBy('name', 'ASC')->paginate(50);
|
||||
|
||||
@@ -145,7 +145,7 @@ class PredefinedKitsController extends Controller
|
||||
]);
|
||||
|
||||
if ($request->filled('search')) {
|
||||
$kits = $kits->where('name', 'LIKE', '%'.$request->get('search').'%');
|
||||
$kits = $kits->where('name', 'LIKE', '%'.$request->input('search').'%');
|
||||
}
|
||||
|
||||
$kits = $kits->orderBy('name', 'ASC')->paginate(50);
|
||||
@@ -184,7 +184,7 @@ class PredefinedKitsController extends Controller
|
||||
$quantity = 1;
|
||||
}
|
||||
|
||||
$license_id = $request->get('license');
|
||||
$license_id = $request->input('license');
|
||||
$relation = $kit->licenses();
|
||||
if ($relation->find($license_id)) {
|
||||
return response()->json(Helper::formatStandardApiResponse('error', null, ['license' => trans('admin/kits/general.license_error')]));
|
||||
@@ -254,7 +254,7 @@ class PredefinedKitsController extends Controller
|
||||
|
||||
$kit = PredefinedKit::findOrFail($kit_id);
|
||||
|
||||
$model_id = $request->get('model');
|
||||
$model_id = $request->input('model');
|
||||
$quantity = $request->input('quantity', 1);
|
||||
if ($quantity < 1) {
|
||||
$quantity = 1;
|
||||
@@ -332,7 +332,7 @@ class PredefinedKitsController extends Controller
|
||||
$quantity = 1;
|
||||
}
|
||||
|
||||
$consumable_id = $request->get('consumable');
|
||||
$consumable_id = $request->input('consumable');
|
||||
$relation = $kit->consumables();
|
||||
if ($relation->find($consumable_id)) {
|
||||
return response()->json(Helper::formatStandardApiResponse('error', null, ['consumable' => trans('admin/kits/general.consumable_error')]));
|
||||
@@ -406,7 +406,7 @@ class PredefinedKitsController extends Controller
|
||||
$quantity = 1;
|
||||
}
|
||||
|
||||
$accessory_id = $request->get('accessory');
|
||||
$accessory_id = $request->input('accessory');
|
||||
$relation = $kit->accessories();
|
||||
if ($relation->find($accessory_id)) {
|
||||
return response()->json(Helper::formatStandardApiResponse('error', null, ['accessory' => trans('admin/kits/general.accessory_error')]));
|
||||
|
||||
@@ -6,6 +6,7 @@ use App\Helpers\Helper;
|
||||
use App\Http\Controllers\Controller;
|
||||
use App\Http\Transformers\ProfileTransformer;
|
||||
use App\Models\CheckoutRequest;
|
||||
use App\Models\Setting;
|
||||
use Illuminate\Http\RedirectResponse;
|
||||
use Illuminate\Http\Response;
|
||||
use Illuminate\Http\Request;
|
||||
@@ -182,19 +183,22 @@ class ProfileController extends Controller
|
||||
*/
|
||||
public function eulas(ProfileTransformer $transformer, Request $request)
|
||||
{
|
||||
if($request->filled('user_id') && $request->input('user_id') != 0) {
|
||||
// Return selected user's EULAs
|
||||
$eulas = User::find($request->input('user_id'))->eulas;
|
||||
}
|
||||
else {
|
||||
// Only return this user's EULAs
|
||||
|
||||
if (($request->filled('user_id')) && ($request->input( 'user_id') != 0)) {
|
||||
|
||||
$eula_user = User::find($request->input('user_id'));
|
||||
|
||||
if (($eula_user) && (Setting::getSettings()->manager_view_enabled) && (auth()->user()->isManagerOf($eula_user))) {
|
||||
$eulas = $eula_user->eulas;
|
||||
} else {
|
||||
return response()->json(Helper:: formatStandardApiResponse('error', null, trans('admin/users/message.user_not_found')));
|
||||
}
|
||||
} else {
|
||||
$eulas = auth()->user()->eulas;
|
||||
}
|
||||
|
||||
return response()->json(
|
||||
$transformer->transformFiles($eulas, $eulas->count())
|
||||
);
|
||||
return response()->json($transformer->transformFiles($eulas, $eulas->count()));
|
||||
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
|
||||
@@ -226,7 +226,7 @@ class SettingsController extends Controller
|
||||
|
||||
$login_attempts = DB::table('login_attempts');
|
||||
$order = $request->input('order') === 'asc' ? 'asc' : 'desc';
|
||||
$sort = in_array($request->get('sort'), $allowed_columns) ? $request->get('sort') : 'created_at';
|
||||
$sort = in_array($request->input('sort'), $allowed_columns) ? $request->input('sort') : 'created_at';
|
||||
|
||||
$total = $login_attempts->count();
|
||||
$login_attempts->orderBy($sort, $order);
|
||||
|
||||
@@ -324,7 +324,7 @@ class StatuslabelsController extends Controller
|
||||
$statuslabels = Statuslabel::orderBy('default_label', 'desc')->orderBy('name', 'asc')->orderBy('deployable', 'desc');
|
||||
|
||||
if ($request->filled('search')) {
|
||||
$statuslabels = $statuslabels->where('name', 'LIKE', '%'.$request->get('search').'%');
|
||||
$statuslabels = $statuslabels->where('name', 'LIKE', '%'.$request->input('search').'%');
|
||||
}
|
||||
|
||||
if ($request->filled('deployable')) {
|
||||
|
||||
@@ -256,7 +256,7 @@ class SuppliersController extends Controller
|
||||
]);
|
||||
|
||||
if ($request->filled('search')) {
|
||||
$suppliers = $suppliers->where('suppliers.name', 'LIKE', '%'.$request->get('search').'%');
|
||||
$suppliers = $suppliers->where('suppliers.name', 'LIKE', '%'.$request->input('search').'%');
|
||||
}
|
||||
|
||||
$suppliers = $suppliers->orderBy('name', 'ASC')->paginate(50);
|
||||
|
||||
@@ -110,15 +110,18 @@ class UploadedFilesController extends Controller
|
||||
foreach ($request->file('file') as $file) {
|
||||
$file_name = $request->handleFile(self::$map_storage_path[$object_type], self::$map_file_prefix[$object_type].'-'.$object->id, $file);
|
||||
$files[] = $file_name;
|
||||
$object->logUpload($file_name, $request->get('notes'));
|
||||
$object->logUpload($file_name, $request->input('notes'));
|
||||
}
|
||||
|
||||
$files = Actionlog::select('action_logs.*')->where('action_type', '=', 'uploaded')
|
||||
->where('item_type', '=', self::$map_object_type[$object_type])
|
||||
->where('item_id', '=', $id)->whereIn('filename', $files)
|
||||
->get();
|
||||
if (isset($files)) {
|
||||
$file_results = Actionlog::select('action_logs.*')->where('action_type', '=', 'uploaded')
|
||||
->where('item_type', '=', self::$map_object_type[$object_type])
|
||||
->where('item_id', '=', $id)->whereIn('filename', $files)
|
||||
->get();
|
||||
|
||||
return response()->json(Helper::formatStandardApiResponse('success', (new UploadedFilesTransformer())->transformFiles($file_results, count($file_results)), trans_choice('general.file_upload_status.upload.success', count($files))));
|
||||
}
|
||||
|
||||
return response()->json(Helper::formatStandardApiResponse('success', (new UploadedFilesTransformer())->transformFiles($files, count($files)), trans_choice('general.file_upload_status.upload.success', count($files))));
|
||||
}
|
||||
|
||||
// No files were submitted
|
||||
|
||||
@@ -253,7 +253,7 @@ class UsersController extends Controller
|
||||
}
|
||||
|
||||
if ($request->filled('group_id')) {
|
||||
$users = $users->ByGroup($request->get('group_id'));
|
||||
$users = $users->ByGroup($request->input('group_id'));
|
||||
}
|
||||
|
||||
if ($request->filled('department_id')) {
|
||||
@@ -400,11 +400,11 @@ class UsersController extends Controller
|
||||
|
||||
if ($request->filled('search')) {
|
||||
$users = $users->where(function ($query) use ($request) {
|
||||
$query->SimpleNameSearch($request->get('search'))
|
||||
->orWhere('username', 'LIKE', '%'.$request->get('search').'%')
|
||||
->orWhere('display_name', 'LIKE', '%'.$request->get('search').'%')
|
||||
->orWhere('email', 'LIKE', '%'.$request->get('search').'%')
|
||||
->orWhere('employee_num', 'LIKE', '%'.$request->get('search').'%');
|
||||
$query->SimpleNameSearch($request->input('search'))
|
||||
->orWhere('username', 'LIKE', '%'.$request->input('search').'%')
|
||||
->orWhere('display_name', 'LIKE', '%'.$request->input('search').'%')
|
||||
->orWhere('email', 'LIKE', '%'.$request->input('search').'%')
|
||||
->orWhere('employee_num', 'LIKE', '%'.$request->input('search').'%');
|
||||
});
|
||||
}
|
||||
|
||||
@@ -459,7 +459,7 @@ class UsersController extends Controller
|
||||
|
||||
//
|
||||
if ($request->filled('password')) {
|
||||
$user->password = bcrypt($request->get('password'));
|
||||
$user->password = bcrypt($request->input('password'));
|
||||
} else {
|
||||
$user->password = $user->noPassword();
|
||||
}
|
||||
@@ -478,12 +478,22 @@ class UsersController extends Controller
|
||||
|
||||
}
|
||||
|
||||
if ($request->filled('groups')) {
|
||||
|
||||
if (($request->has('groups')) && (auth()->user()->isSuperUser())) {
|
||||
|
||||
$validator = Validator::make($request->only('groups'), [
|
||||
'groups.*' => 'integer|exists:permission_groups,id',
|
||||
]);
|
||||
|
||||
if ($validator->fails()) {
|
||||
return response()->json(Helper::formatStandardApiResponse('error', null, $validator->errors()));
|
||||
}
|
||||
|
||||
// Sync the groups since the user is a superuser and the groups pass validation
|
||||
$user->groups()->sync($request->input('groups'));
|
||||
} else {
|
||||
$user->groups()->sync([]);
|
||||
}
|
||||
|
||||
|
||||
return response()->json(Helper::formatStandardApiResponse('success', (new UsersTransformer)->transformUser($user), trans('admin/users/message.success.create')));
|
||||
}
|
||||
|
||||
@@ -632,21 +642,27 @@ class UsersController extends Controller
|
||||
|
||||
$this->authorize('delete', $user);
|
||||
|
||||
if ($user->delete()) {
|
||||
if (auth()->user()->can('canEditAuthFields', $user) && auth()->user()->can('editableOnDemo')) {
|
||||
|
||||
// Remove the user's avatar if they have one
|
||||
if (Storage::disk('public')->exists('avatars/' . $user->avatar)) {
|
||||
try {
|
||||
Storage::disk('public')->delete('avatars/' . $user->avatar);
|
||||
} catch (\Exception $e) {
|
||||
Log::debug($e);
|
||||
}
|
||||
if ($user->delete()) {
|
||||
|
||||
// Remove the user's avatar if they have one
|
||||
// @todo This should be done on purge, not here
|
||||
// if (Storage::disk('public')->exists('avatars/' . $user->avatar)) {
|
||||
// try {
|
||||
// Storage::disk('public')->delete('avatars/' . $user->avatar);
|
||||
// } catch (\Exception $e) {
|
||||
// Log::debug($e);
|
||||
// }
|
||||
// }
|
||||
|
||||
return response()->json(Helper::formatStandardApiResponse('success', null, trans('admin/users/message.success.delete')));
|
||||
}
|
||||
|
||||
return response()->json(Helper::formatStandardApiResponse('success', null, trans('admin/users/message.success.delete')));
|
||||
return response()->json(Helper::formatStandardApiResponse('error', null, trans('admin/users/message.error.delete')));
|
||||
}
|
||||
|
||||
return response()->json(Helper::formatStandardApiResponse('error', null, trans('admin/users/message.error.delete')));
|
||||
return response()->json(Helper::formatStandardApiResponse('error', null, trans('admin/users/message.cannot_delete')));
|
||||
|
||||
}
|
||||
|
||||
@@ -795,7 +811,7 @@ class UsersController extends Controller
|
||||
|
||||
if ($request->filled('id')) {
|
||||
try {
|
||||
$user = User::find($request->get('id'));
|
||||
$user = User::find($request->input('id'));
|
||||
$this->authorize('update', $user);
|
||||
$user->two_factor_secret = null;
|
||||
$user->two_factor_enrolled = 0;
|
||||
|
||||
@@ -98,10 +98,10 @@ class AssetCheckinController extends Controller
|
||||
$asset->expected_checkin = null;
|
||||
$asset->assignedTo()->disassociate($asset);
|
||||
$asset->accepted = null;
|
||||
$asset->name = $request->get('name');
|
||||
$asset->name = $request->input('name');
|
||||
|
||||
if ($request->filled('status_id')) {
|
||||
$asset->status_id = e($request->get('status_id'));
|
||||
$asset->status_id = e($request->input('status_id'));
|
||||
}
|
||||
|
||||
// Add any custom fields that should be included in the checkout
|
||||
@@ -112,11 +112,11 @@ class AssetCheckinController extends Controller
|
||||
$asset->location_id = $asset->rtd_location_id;
|
||||
|
||||
if ($request->filled('location_id')) {
|
||||
Log::debug('NEW Location ID: '.$request->get('location_id'));
|
||||
$asset->location_id = $request->get('location_id');
|
||||
Log::debug('NEW Location ID: '.$request->input('location_id'));
|
||||
$asset->location_id = $request->input('location_id');
|
||||
|
||||
if ($request->get('update_default_location') == 0){
|
||||
$asset->rtd_location_id = $request->get('location_id');
|
||||
if ($request->input('update_default_location') == 0){
|
||||
$asset->rtd_location_id = $request->input('location_id');
|
||||
}
|
||||
}
|
||||
|
||||
@@ -124,9 +124,9 @@ class AssetCheckinController extends Controller
|
||||
|
||||
// Handle last checkin date
|
||||
$checkin_at = date('Y-m-d H:i:s');
|
||||
if (($request->filled('checkin_at')) && ($request->get('checkin_at') != date('Y-m-d'))) {
|
||||
if (($request->filled('checkin_at')) && ($request->input('checkin_at') != date('Y-m-d'))) {
|
||||
$originalValues['action_date'] = $checkin_at;
|
||||
$checkin_at = $request->get('checkin_at');
|
||||
$checkin_at = $request->input('checkin_at');
|
||||
|
||||
}
|
||||
$asset->last_checkin = $checkin_at;
|
||||
@@ -145,7 +145,7 @@ class AssetCheckinController extends Controller
|
||||
$acceptance->delete();
|
||||
});
|
||||
|
||||
session()->put('redirect_option', $request->get('redirect_option'));
|
||||
session()->put('redirect_option', $request->input('redirect_option'));
|
||||
|
||||
// Add any custom fields that should be included in the checkout
|
||||
$asset->customFieldsForCheckinCheckout('display_checkin');
|
||||
|
||||
@@ -88,17 +88,17 @@ class AssetCheckoutController extends Controller
|
||||
$asset = $this->updateAssetLocation($asset, $target);
|
||||
|
||||
$checkout_at = date('Y-m-d H:i:s');
|
||||
if (($request->filled('checkout_at')) && ($request->get('checkout_at') != date('Y-m-d'))) {
|
||||
$checkout_at = $request->get('checkout_at');
|
||||
if (($request->filled('checkout_at')) && ($request->input('checkout_at') != date('Y-m-d'))) {
|
||||
$checkout_at = $request->input('checkout_at');
|
||||
}
|
||||
|
||||
$expected_checkin = '';
|
||||
if ($request->filled('expected_checkin')) {
|
||||
$expected_checkin = $request->get('expected_checkin');
|
||||
$expected_checkin = $request->input('expected_checkin');
|
||||
}
|
||||
|
||||
if ($request->filled('status_id')) {
|
||||
$asset->status_id = $request->get('status_id');
|
||||
$asset->status_id = $request->input('status_id');
|
||||
}
|
||||
|
||||
|
||||
@@ -123,9 +123,9 @@ class AssetCheckoutController extends Controller
|
||||
}
|
||||
}
|
||||
|
||||
session()->put(['redirect_option' => $request->get('redirect_option'), 'checkout_to_type' => $request->get('checkout_to_type')]);
|
||||
session()->put(['redirect_option' => $request->input('redirect_option'), 'checkout_to_type' => $request->input('checkout_to_type')]);
|
||||
|
||||
if ($asset->checkOut($target, $admin, $checkout_at, $expected_checkin, $request->get('note'), $request->get('name'))) {
|
||||
if ($asset->checkOut($target, $admin, $checkout_at, $expected_checkin, $request->input('note'), $request->input('name'))) {
|
||||
return Helper::getRedirectOption($request, $asset->id, 'Assets')
|
||||
->with('success', trans('admin/hardware/message.checkout.success'));
|
||||
}
|
||||
|
||||
@@ -249,7 +249,7 @@ class AssetsController extends Controller
|
||||
}
|
||||
|
||||
if (isset($target)) {
|
||||
$asset->checkOut($target, auth()->user(), date('Y-m-d H:i:s'), $request->input('expected_checkin', null), 'Checked out on asset creation', $request->get('name'), $location);
|
||||
$asset->checkOut($target, auth()->user(), date('Y-m-d H:i:s'), $request->input('expected_checkin', null), 'Checked out on asset creation', $request->input('name'), $location);
|
||||
}
|
||||
|
||||
$successes[] = "<a href='" . route('hardware.show', $asset) . "' style='color: white;'>" . e($asset->asset_tag) . "</a>";
|
||||
@@ -266,13 +266,13 @@ class AssetsController extends Controller
|
||||
}
|
||||
DB::commit();
|
||||
|
||||
if($request->get('redirect_option') === 'back'){
|
||||
if($request->input('redirect_option') === 'back'){
|
||||
session()->put(['redirect_option' => 'index']);
|
||||
} else {
|
||||
session()->put(['redirect_option' => $request->get('redirect_option')]);
|
||||
session()->put(['redirect_option' => $request->input('redirect_option')]);
|
||||
}
|
||||
|
||||
session()->put(['checkout_to_type' => $request->get('checkout_to_type'),
|
||||
session()->put(['checkout_to_type' => $request->input('checkout_to_type'),
|
||||
'other_redirect' => 'model' ]);
|
||||
|
||||
|
||||
@@ -454,7 +454,7 @@ class AssetsController extends Controller
|
||||
// Update custom fields in the database.
|
||||
// FIXME: No idea why this is returning a Builder error on db_column_name.
|
||||
// Need to investigate and fix. Using static method for now.
|
||||
$model = AssetModel::find($request->get('model_id'));
|
||||
$model = AssetModel::find($request->input('model_id'));
|
||||
if (($model) && ($model->fieldset)) {
|
||||
foreach ($model->fieldset->fields as $field) {
|
||||
if ($field->element == 'checkbox' && !$request->has($field->db_column)) {
|
||||
@@ -480,9 +480,9 @@ class AssetsController extends Controller
|
||||
}
|
||||
}
|
||||
session()->put([
|
||||
'redirect_option' => $request->get('redirect_option'),
|
||||
'checkout_to_type' => $request->get('checkout_to_type'),
|
||||
'other_redirect' => $request->get('redirect_option') === 'other_redirect' ? 'model' : null,
|
||||
'redirect_option' => $request->input('redirect_option'),
|
||||
'checkout_to_type' => $request->input('checkout_to_type'),
|
||||
'other_redirect' => $request->input('redirect_option') === 'other_redirect' ? 'model' : null,
|
||||
]);
|
||||
|
||||
|
||||
@@ -552,9 +552,9 @@ class AssetsController extends Controller
|
||||
*/
|
||||
public function getAssetBySerial(Request $request) : RedirectResponse
|
||||
{
|
||||
$topsearch = ($request->get('topsearch')=="true");
|
||||
$topsearch = ($request->input('topsearch')=="true");
|
||||
|
||||
if (!$asset = Asset::where('serial', '=', $request->get('serial'))->first()) {
|
||||
if (!$asset = Asset::where('serial', '=', $request->input('serial'))->first()) {
|
||||
return redirect()->route('hardware.index')->with('error', trans('admin/hardware/message.does_not_exist'));
|
||||
}
|
||||
$this->authorize('view', $asset);
|
||||
@@ -570,8 +570,8 @@ class AssetsController extends Controller
|
||||
*/
|
||||
public function getAssetByTag(Request $request, $tag=null) : RedirectResponse
|
||||
{
|
||||
$tag = $tag ? $tag : $request->get('assetTag');
|
||||
$topsearch = ($request->get('topsearch') == 'true');
|
||||
$tag = $tag ? $tag : $request->input('assetTag');
|
||||
$topsearch = ($request->input('topsearch') == 'true');
|
||||
|
||||
// Search for an exact and unique asset tag match
|
||||
$assets = Asset::where('asset_tag', '=', $tag);
|
||||
@@ -682,8 +682,8 @@ class AssetsController extends Controller
|
||||
return (new Label())
|
||||
->with('assets', collect([ $asset ]))
|
||||
->with('settings', Setting::getSettings())
|
||||
->with('template', request()->get('template'))
|
||||
->with('offset', request()->get('offset'))
|
||||
->with('template', request()->input('template'))
|
||||
->with('offset', request()->input('offset'))
|
||||
->with('bulkedit', false)
|
||||
->with('count', 0);
|
||||
}
|
||||
@@ -982,7 +982,7 @@ class AssetsController extends Controller
|
||||
|
||||
$this->authorize('audit', Asset::class);
|
||||
|
||||
session()->put('redirect_option', $request->get('redirect_option'));
|
||||
session()->put('redirect_option', $request->input('redirect_option'));
|
||||
session()->put('other_redirect', 'audit');
|
||||
|
||||
|
||||
|
||||
@@ -588,7 +588,7 @@ class BulkAssetsController extends Controller
|
||||
if ($request->session()->has('bulk_back_url')) {
|
||||
$bulk_back_url = $request->session()->pull('bulk_back_url');
|
||||
}
|
||||
$assetIds = $request->get('ids');
|
||||
$assetIds = $request->input('ids');
|
||||
|
||||
if(empty($assetIds)) {
|
||||
return redirect($bulk_back_url)->with('error', trans('admin/hardware/message.delete.nothing_updated'));
|
||||
@@ -652,11 +652,11 @@ class BulkAssetsController extends Controller
|
||||
$target = $this->determineCheckoutTarget();
|
||||
session()->put(['checkout_to_type' => $target]);
|
||||
|
||||
if (! is_array($request->get('selected_assets'))) {
|
||||
if (! is_array($request->input('selected_assets'))) {
|
||||
return redirect()->route('hardware.bulkcheckout.show')->withInput()->with('error', trans('admin/hardware/message.checkout.no_assets_selected'));
|
||||
}
|
||||
|
||||
$asset_ids = array_filter($request->get('selected_assets'));
|
||||
$asset_ids = array_filter($request->input('selected_assets'));
|
||||
|
||||
$assets = Asset::findOrFail($asset_ids);
|
||||
|
||||
@@ -692,14 +692,14 @@ class BulkAssetsController extends Controller
|
||||
}
|
||||
}
|
||||
$checkout_at = date('Y-m-d H:i:s');
|
||||
if (($request->filled('checkout_at')) && ($request->get('checkout_at') != date('Y-m-d'))) {
|
||||
$checkout_at = $request->get('checkout_at');
|
||||
if (($request->filled('checkout_at')) && ($request->input('checkout_at') != date('Y-m-d'))) {
|
||||
$checkout_at = $request->input('checkout_at');
|
||||
}
|
||||
|
||||
$expected_checkin = '';
|
||||
|
||||
if ($request->filled('expected_checkin')) {
|
||||
$expected_checkin = $request->get('expected_checkin');
|
||||
$expected_checkin = $request->input('expected_checkin');
|
||||
}
|
||||
|
||||
$errors = [];
|
||||
@@ -709,10 +709,10 @@ class BulkAssetsController extends Controller
|
||||
|
||||
// See if there is a status label passed
|
||||
if ($request->filled('status_id')) {
|
||||
$asset->status_id = $request->get('status_id');
|
||||
$asset->status_id = $request->input('status_id');
|
||||
}
|
||||
|
||||
$checkout_success = $asset->checkOut($target, $admin, $checkout_at, $expected_checkin, e($request->get('note')), $asset->name, null);
|
||||
$checkout_success = $asset->checkOut($target, $admin, $checkout_at, $expected_checkin, e($request->input('note')), $asset->name, null);
|
||||
|
||||
//TODO - I think this logic is duplicated in the checkOut method?
|
||||
if ($target->location_id != '') {
|
||||
@@ -743,7 +743,7 @@ class BulkAssetsController extends Controller
|
||||
public function restore(Request $request) : RedirectResponse
|
||||
{
|
||||
$this->authorize('update', Asset::class);
|
||||
$assetIds = $request->get('ids');
|
||||
$assetIds = $request->input('ids');
|
||||
|
||||
if (empty($assetIds)) {
|
||||
return redirect()->route('hardware.index')->with('error', trans('admin/hardware/message.restore.nothing_updated'));
|
||||
|
||||
@@ -98,7 +98,7 @@ class ComponentCheckinController extends Controller
|
||||
|
||||
event(new CheckoutableCheckedIn($component, $asset, auth()->user(), $request->input('note'), Carbon::now()));
|
||||
|
||||
session()->put(['redirect_option' => $request->get('redirect_option')]);
|
||||
session()->put(['redirect_option' => $request->input('redirect_option')]);
|
||||
|
||||
return Helper::getRedirectOption($request, $component->id, 'Components')
|
||||
->with('success', trans('admin/components/message.checkin.success'));
|
||||
|
||||
@@ -80,8 +80,8 @@ class ComponentCheckoutController extends Controller
|
||||
$max_to_checkout = $component->numRemaining();
|
||||
|
||||
// Make sure there are at least the requested number of components available to checkout
|
||||
if ($max_to_checkout < $request->get('assigned_qty')) {
|
||||
return redirect()->back()->withInput()->with('error', trans('admin/components/message.checkout.unavailable', ['remaining' => $max_to_checkout, 'requested' => $request->get('assigned_qty')]));
|
||||
if ($max_to_checkout < $request->input('assigned_qty')) {
|
||||
return redirect()->back()->withInput()->with('error', trans('admin/components/message.checkout.unavailable', ['remaining' => $max_to_checkout, 'requested' => $request->input('assigned_qty')]));
|
||||
}
|
||||
|
||||
$validator = Validator::make($request->all(), [
|
||||
@@ -115,12 +115,19 @@ class ComponentCheckoutController extends Controller
|
||||
'note' => $request->input('note'),
|
||||
]);
|
||||
|
||||
event(new CheckoutableCheckedOut($component, $asset, auth()->user(), $request->input('note')));
|
||||
event(new CheckoutableCheckedOut(
|
||||
$component,
|
||||
$asset,
|
||||
auth()->user(),
|
||||
$request->input('note'),
|
||||
[],
|
||||
$component->checkout_qty,
|
||||
));
|
||||
|
||||
$request->request->add(['checkout_to_type' => 'asset']);
|
||||
$request->request->add(['assigned_asset' => $asset->id]);
|
||||
|
||||
session()->put(['redirect_option' => $request->get('redirect_option'), 'checkout_to_type' => $request->get('checkout_to_type')]);
|
||||
session()->put(['redirect_option' => $request->input('redirect_option'), 'checkout_to_type' => $request->input('checkout_to_type')]);
|
||||
|
||||
return Helper::getRedirectOption($request, $component->id, 'Components')
|
||||
->with('success', trans('admin/components/message.checkout.success'));
|
||||
|
||||
@@ -88,10 +88,10 @@ class ComponentsController extends Controller
|
||||
|
||||
$component = $request->handleImages($component);
|
||||
|
||||
if($request->get('redirect_option') === 'back'){
|
||||
if($request->input('redirect_option') === 'back'){
|
||||
session()->put(['redirect_option' => 'index']);
|
||||
} else {
|
||||
session()->put(['redirect_option' => $request->get('redirect_option')]);
|
||||
session()->put(['redirect_option' => $request->input('redirect_option')]);
|
||||
}
|
||||
|
||||
|
||||
@@ -168,7 +168,7 @@ class ComponentsController extends Controller
|
||||
|
||||
$component = $request->handleImages($component);
|
||||
|
||||
session()->put(['redirect_option' => $request->get('redirect_option')]);
|
||||
session()->put(['redirect_option' => $request->input('redirect_option')]);
|
||||
|
||||
if ($component->save()) {
|
||||
return Helper::getRedirectOption($request, $component->id, 'Components')
|
||||
|
||||
@@ -102,12 +102,20 @@ class ConsumableCheckoutController extends Controller
|
||||
}
|
||||
|
||||
$consumable->checkout_qty = $quantity;
|
||||
event(new CheckoutableCheckedOut($consumable, $user, auth()->user(), $request->input('note')));
|
||||
|
||||
event(new CheckoutableCheckedOut(
|
||||
$consumable,
|
||||
$user,
|
||||
auth()->user(),
|
||||
$request->input('note'),
|
||||
[],
|
||||
$consumable->checkout_qty,
|
||||
));
|
||||
|
||||
$request->request->add(['checkout_to_type' => 'user']);
|
||||
$request->request->add(['assigned_user' => $user->id]);
|
||||
|
||||
session()->put(['redirect_option' => $request->get('redirect_option'), 'checkout_to_type' => $request->get('checkout_to_type')]);
|
||||
session()->put(['redirect_option' => $request->input('redirect_option'), 'checkout_to_type' => $request->input('checkout_to_type')]);
|
||||
|
||||
|
||||
// Redirect to the new consumable page
|
||||
|
||||
@@ -98,10 +98,10 @@ class ConsumablesController extends Controller
|
||||
$consumable = $request->handleImages($consumable);
|
||||
}
|
||||
|
||||
if($request->get('redirect_option') === 'back'){
|
||||
if($request->input('redirect_option') === 'back'){
|
||||
session()->put(['redirect_option' => 'index']);
|
||||
} else {
|
||||
session()->put(['redirect_option' => $request->get('redirect_option')]);
|
||||
session()->put(['redirect_option' => $request->input('redirect_option')]);
|
||||
}
|
||||
|
||||
|
||||
@@ -175,7 +175,7 @@ class ConsumablesController extends Controller
|
||||
|
||||
$consumable = $request->handleImages($consumable);
|
||||
|
||||
session()->put(['redirect_option' => $request->get('redirect_option')]);
|
||||
session()->put(['redirect_option' => $request->input('redirect_option')]);
|
||||
|
||||
if ($consumable->save()) {
|
||||
return Helper::getRedirectOption($request, $consumable->id, 'Consumables')
|
||||
|
||||
@@ -112,9 +112,9 @@ class CustomFieldsController extends Controller
|
||||
|
||||
|
||||
if ($request->filled('custom_format')) {
|
||||
$field->format = $request->get('custom_format');
|
||||
$field->format = $request->input('custom_format');
|
||||
} else {
|
||||
$field->format = $request->get('format');
|
||||
$field->format = $request->input('format');
|
||||
}
|
||||
|
||||
if ($field->save()) {
|
||||
@@ -225,34 +225,34 @@ class CustomFieldsController extends Controller
|
||||
public function update(CustomFieldRequest $request, CustomField $field) : RedirectResponse
|
||||
{
|
||||
$this->authorize('update', CustomField::class);
|
||||
$show_in_email = $request->get("show_in_email", 0);
|
||||
$display_in_user_view = $request->get("display_in_user_view", 0);
|
||||
$show_in_email = $request->input("show_in_email", 0);
|
||||
$display_in_user_view = $request->input("display_in_user_view", 0);
|
||||
|
||||
// Override the display settings if the field is encrypted
|
||||
if ($request->get("field_encrypted") == '1') {
|
||||
if ($request->input("field_encrypted") == '1') {
|
||||
$show_in_email = '0';
|
||||
$display_in_user_view = '0';
|
||||
}
|
||||
|
||||
$field->name = trim($request->get("name"));
|
||||
$field->element = $request->get("element");
|
||||
$field->field_values = $request->get("field_values");
|
||||
$field->name = trim($request->input("name"));
|
||||
$field->element = $request->input("element");
|
||||
$field->field_values = $request->input("field_values");
|
||||
$field->created_by = auth()->id();
|
||||
$field->help_text = $request->get("help_text");
|
||||
$field->help_text = $request->input("help_text");
|
||||
$field->show_in_email = $show_in_email;
|
||||
$field->is_unique = $request->get("is_unique", 0);
|
||||
$field->is_unique = $request->input("is_unique", 0);
|
||||
$field->display_in_user_view = $display_in_user_view;
|
||||
$field->auto_add_to_fieldsets = $request->get("auto_add_to_fieldsets", 0);
|
||||
$field->show_in_listview = $request->get("show_in_listview", 0);
|
||||
$field->show_in_requestable_list = $request->get("show_in_requestable_list", 0);
|
||||
$field->display_checkin = $request->get("display_checkin", 0);
|
||||
$field->display_checkout = $request->get("display_checkout", 0);
|
||||
$field->display_audit = $request->get("display_audit", 0);
|
||||
$field->auto_add_to_fieldsets = $request->input("auto_add_to_fieldsets", 0);
|
||||
$field->show_in_listview = $request->input("show_in_listview", 0);
|
||||
$field->show_in_requestable_list = $request->input("show_in_requestable_list", 0);
|
||||
$field->display_checkin = $request->input("display_checkin", 0);
|
||||
$field->display_checkout = $request->input("display_checkout", 0);
|
||||
$field->display_audit = $request->input("display_audit", 0);
|
||||
|
||||
if ($request->get('format') == 'CUSTOM REGEX') {
|
||||
$field->format = $request->get('custom_format');
|
||||
if ($request->input('format') == 'CUSTOM REGEX') {
|
||||
$field->format = $request->input('custom_format');
|
||||
} else {
|
||||
$field->format = $request->get('format');
|
||||
$field->format = $request->input('format');
|
||||
}
|
||||
|
||||
if ($field->element == 'checkbox' || $field->element == 'radio'){
|
||||
|
||||
@@ -74,7 +74,7 @@ class CustomFieldsetsController extends Controller
|
||||
{
|
||||
$this->authorize('create', CustomField::class);
|
||||
|
||||
return view('custom_fields.fieldsets.edit')->with('item', new CustomFieldset());
|
||||
return view('custom_fields.fieldsets.view')->with('custom_fieldset', new CustomFieldset());
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -91,7 +91,7 @@ class CustomFieldsetsController extends Controller
|
||||
$this->authorize('create', CustomField::class);
|
||||
|
||||
$fieldset = new CustomFieldset([
|
||||
'name' => $request->get('name'),
|
||||
'name' => $request->input('name'),
|
||||
'created_by' => auth()->id(),
|
||||
]);
|
||||
|
||||
@@ -127,7 +127,7 @@ class CustomFieldsetsController extends Controller
|
||||
public function edit(CustomFieldset $fieldset) : View | RedirectResponse
|
||||
{
|
||||
$this->authorize('create', CustomField::class);
|
||||
return view('custom_fields.fieldsets.edit')->with('item', $fieldset);
|
||||
return view('custom_fields.fieldsets.view')->with('custom_fieldset', $fieldset);
|
||||
}
|
||||
|
||||
/**
|
||||
|
||||
@@ -44,7 +44,11 @@ class GroupsController extends Controller
|
||||
$permissions = config('permissions');
|
||||
$groupPermissions = Helper::selectedPermissionsArray($permissions, $permissions);
|
||||
$selectedPermissions = $request->old('permissions', $groupPermissions);
|
||||
$users_query = User::where('show_in_list', 1)->whereNull('deleted_at');
|
||||
$users_query = User::query()
|
||||
->select(['users.id', 'users.first_name', 'users.last_name', 'users.username'])
|
||||
->where('show_in_list', 1)
|
||||
->whereNull('deleted_at');
|
||||
|
||||
$users_count = $users_query->count();
|
||||
|
||||
$users = collect();
|
||||
@@ -55,7 +59,7 @@ class GroupsController extends Controller
|
||||
// Show the page
|
||||
return view('groups/edit', compact('permissions', 'selectedPermissions', 'groupPermissions'))
|
||||
->with('group', $group)
|
||||
->with('associated_users', [])
|
||||
->with('associated_users', collect())
|
||||
->with('unselected_users', $users)
|
||||
->with('all_users_count', $users_count);
|
||||
}
|
||||
@@ -114,8 +118,11 @@ class GroupsController extends Controller
|
||||
|
||||
$selected_array = Helper::selectedPermissionsArray($permissions, $groupPermissions);
|
||||
|
||||
$users_query = User::query()
|
||||
->select(['users.id', 'users.first_name', 'users.last_name', 'users.username'])
|
||||
->where('show_in_list', 1)
|
||||
->whereNull('deleted_at');
|
||||
|
||||
$users_query = User::where('show_in_list', 1)->whereNull('deleted_at');
|
||||
$users_count = $users_query->count();
|
||||
|
||||
$associated_users = collect();
|
||||
@@ -124,7 +131,13 @@ class GroupsController extends Controller
|
||||
if ($users_count <= config('app.max_unpaginated_records')) {
|
||||
$associated_users = $group->users()->where('show_in_list', 1)->orderBy('first_name', 'asc')->orderBy('last_name', 'asc')->get();
|
||||
// Get the unselected users
|
||||
$unselected_users = User::where('show_in_list', 1)->whereNotIn('id', $associated_users->pluck('id')->toArray())->orderBy('first_name', 'asc')->orderBy('last_name', 'asc')->get();
|
||||
$unselected_users = User::query()
|
||||
->select(['users.id', 'users.first_name', 'users.last_name', 'users.username'])
|
||||
->where('show_in_list', 1)
|
||||
->whereNotIn('id', $associated_users->pluck('id')->toArray())
|
||||
->orderBy('first_name', 'asc')
|
||||
->orderBy('last_name', 'asc')
|
||||
->get();
|
||||
}
|
||||
|
||||
return view('groups.edit', compact('group', 'permissions', 'selected_array', 'groupPermissions'))
|
||||
|
||||
@@ -47,7 +47,7 @@ class CheckoutKitController extends Controller
|
||||
*/
|
||||
public function store(Request $request, $kit_id)
|
||||
{
|
||||
$user_id = e($request->get('user_id'));
|
||||
$user_id = e($request->input('user_id'));
|
||||
if (is_null($user = User::find($user_id))) {
|
||||
return redirect()->back()->with('error', trans('admin/users/message.user_not_found'));
|
||||
}
|
||||
|
||||
@@ -81,7 +81,7 @@ class LabelsController extends Controller
|
||||
|
||||
$settings = Setting::getSettings();
|
||||
if (request()->has('settings')) {
|
||||
$overrides = request()->get('settings');
|
||||
$overrides = request()->input('settings');
|
||||
foreach ($overrides as $key => $value) {
|
||||
$settings->$key = $value;
|
||||
}
|
||||
|
||||
@@ -97,8 +97,8 @@ class LicenseCheckinController extends Controller
|
||||
$licenseSeat->unreassignable_seat = true;
|
||||
}
|
||||
|
||||
session()->put(['redirect_option' => $request->get('redirect_option')]);
|
||||
if ($request->get('redirect_option') === 'target'){
|
||||
session()->put(['redirect_option' => $request->input('redirect_option')]);
|
||||
if ($request->input('redirect_option') === 'target'){
|
||||
session()->put(['checkout_to_type' => 'user']);
|
||||
}
|
||||
|
||||
|
||||
@@ -96,13 +96,13 @@ class LicenseCheckoutController extends Controller
|
||||
session()->put(['checkout_to_type' => 'asset']);
|
||||
$checkoutTarget = $this->checkoutToAsset($licenseSeat);
|
||||
$request->request->add(['assigned_asset' => $checkoutTarget->id]);
|
||||
session()->put(['redirect_option' => $request->get('redirect_option'), 'checkout_to_type' => 'asset']);
|
||||
session()->put(['redirect_option' => $request->input('redirect_option'), 'checkout_to_type' => 'asset']);
|
||||
|
||||
} elseif ($request->filled('assigned_to')) {
|
||||
session()->put(['checkout_to_type' => 'user']);
|
||||
$checkoutTarget = $this->checkoutToUser($licenseSeat);
|
||||
$request->request->add(['assigned_user' => $checkoutTarget->id]);
|
||||
session()->put(['redirect_option' => $request->get('redirect_option'), 'checkout_to_type' => 'user']);
|
||||
session()->put(['redirect_option' => $request->input('redirect_option'), 'checkout_to_type' => 'user']);
|
||||
}
|
||||
|
||||
|
||||
|
||||
@@ -102,10 +102,10 @@ class LicensesController extends Controller
|
||||
$license->created_by = auth()->id();
|
||||
$license->min_amt = $request->input('min_amt');
|
||||
|
||||
if($request->get('redirect_option') === 'back'){
|
||||
if($request->input('redirect_option') === 'back'){
|
||||
session()->put(['redirect_option' => 'index']);
|
||||
} else {
|
||||
session()->put(['redirect_option' => $request->get('redirect_option')]);
|
||||
session()->put(['redirect_option' => $request->input('redirect_option')]);
|
||||
}
|
||||
|
||||
if ($license->save()) {
|
||||
@@ -183,7 +183,7 @@ class LicensesController extends Controller
|
||||
$license->category_id = $request->input('category_id');
|
||||
$license->min_amt = $request->input('min_amt');
|
||||
|
||||
session()->put(['redirect_option' => $request->get('redirect_option')]);
|
||||
session()->put(['redirect_option' => $request->input('redirect_option')]);
|
||||
|
||||
if ($license->save()) {
|
||||
return Helper::getRedirectOption($request, $license->id, 'Licenses')
|
||||
|
||||
@@ -818,7 +818,7 @@ class ReportsController extends Controller
|
||||
}
|
||||
|
||||
if ($request->filled('eol')) {
|
||||
$row[] = ($asset->purchase_date != '') ? $asset->asset_eol_date : '';
|
||||
$row[] = ($asset->asset_eol_date != '') ? $asset->asset_eol_date : '';
|
||||
}
|
||||
|
||||
if ($request->filled('warranty')) {
|
||||
@@ -1228,12 +1228,14 @@ class ReportsController extends Controller
|
||||
];
|
||||
$mailable= $lookup[get_class($acceptance->checkoutable)];
|
||||
|
||||
return new $mailable($acceptance->checkoutable,
|
||||
return new $mailable(
|
||||
$acceptance->checkoutable,
|
||||
$acceptance->checkedOutTo ?? $acceptance->assignedTo,
|
||||
$logItem->adminuser,
|
||||
$acceptance,
|
||||
$acceptance->note);
|
||||
|
||||
$acceptance->note,
|
||||
firstTimeSending: false,
|
||||
);
|
||||
}
|
||||
/**
|
||||
* sentAssetAcceptanceReminder
|
||||
|
||||
@@ -114,7 +114,7 @@ class SettingsController extends Controller
|
||||
$setting->email_domain = $request->input('email_domain');
|
||||
$setting->email_format = $request->input('email_format');
|
||||
$setting->username_format = $request->input('username_format');
|
||||
$setting->require_accept_signature = $request->input('require_accept_signature');
|
||||
$setting->require_accept_signature = $request->input('require_accept_signature', '0');
|
||||
$setting->show_assigned_assets = $request->input('show_assigned_assets', '0');
|
||||
if (! config('app.lock_passwords')) {
|
||||
$setting->login_note = $request->input('login_note');
|
||||
|
||||
@@ -56,7 +56,7 @@ class UploadedFilesController extends Controller
|
||||
foreach ($request->file('file') as $file) {
|
||||
$file_name = $request->handleFile(self::$map_storage_path[$object_type], self::$map_file_prefix[$object_type].'-'.$object->id, $file);
|
||||
$files[] = $file_name;
|
||||
$object->logUpload($file_name, $request->get('notes'));
|
||||
$object->logUpload($file_name, $request->input('notes'));
|
||||
}
|
||||
|
||||
$files = Actionlog::select('action_logs.*')->where('action_type', '=', 'uploaded')
|
||||
|
||||
@@ -169,6 +169,7 @@ class BulkUsersController extends Controller
|
||||
->conditionallyAddItem('remote')
|
||||
->conditionallyAddItem('ldap_import')
|
||||
->conditionallyAddItem('activated')
|
||||
->conditionallyAddItem('display_name')
|
||||
->conditionallyAddItem('start_date')
|
||||
->conditionallyAddItem('end_date')
|
||||
->conditionallyAddItem('city')
|
||||
@@ -214,6 +215,10 @@ class BulkUsersController extends Controller
|
||||
$this->update_array['locale'] = null;
|
||||
}
|
||||
|
||||
if ($request->input('null_display_name')=='1') {
|
||||
$this->update_array['display_name'] = null;
|
||||
}
|
||||
|
||||
if (! $manager_conflict) {
|
||||
$this->conditionallyAddItem('manager_id');
|
||||
}
|
||||
@@ -229,8 +234,11 @@ class BulkUsersController extends Controller
|
||||
|
||||
// Only sync groups if groups were selected
|
||||
if ($request->filled('groups')) {
|
||||
|
||||
foreach ($users as $user) {
|
||||
$user->groups()->sync($request->input('groups'));
|
||||
if (auth()->user()->can('canEditAuthFields', $user) && auth()->user()->can('editableOnDemo')) {
|
||||
$user->groups()->sync($request->input('groups'));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -312,7 +320,9 @@ class BulkUsersController extends Controller
|
||||
foreach ($users as $user) {
|
||||
$user->accessories()->sync([]);
|
||||
if ($request->input('delete_user')=='1') {
|
||||
$user->delete();
|
||||
if (auth()->user()->can('canEditAuthFields', $user) && auth()->user()->can('editableOnDemo')) {
|
||||
$user->delete();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -56,7 +56,7 @@ class UsersController extends Controller
|
||||
public function create(Request $request)
|
||||
{
|
||||
$this->authorize('create', User::class);
|
||||
$groups = Group::pluck('name', 'id');
|
||||
$groups = Group::orderBy('name', 'asc')->pluck('name', 'id');
|
||||
|
||||
$userGroups = collect();
|
||||
|
||||
@@ -130,10 +130,10 @@ class UsersController extends Controller
|
||||
// we have to invoke the form request here to handle image uploads
|
||||
app(ImageUploadRequest::class)->handleImages($user, 600, 'avatar', 'avatars', 'avatar');
|
||||
|
||||
if ($request->get('redirect_option') === 'back'){
|
||||
if ($request->input('redirect_option') === 'back'){
|
||||
session()->put(['redirect_option' => 'index']);
|
||||
} else {
|
||||
session()->put(['redirect_option' => $request->get('redirect_option')]);
|
||||
session()->put(['redirect_option' => $request->input('redirect_option')]);
|
||||
}
|
||||
|
||||
|
||||
@@ -151,7 +151,9 @@ class UsersController extends Controller
|
||||
}
|
||||
|
||||
if ($request->filled('groups')) {
|
||||
$user->groups()->sync($request->input('groups'));
|
||||
if (auth()->user()->can('canEditAuthFields', $user) && auth()->user()->can('editableOnDemo')) {
|
||||
$user->groups()->sync($request->input('groups'));
|
||||
}
|
||||
} else {
|
||||
$user->groups()->sync([]);
|
||||
}
|
||||
@@ -199,7 +201,7 @@ class UsersController extends Controller
|
||||
}
|
||||
|
||||
$permissions = config('permissions');
|
||||
$groups = Group::pluck('name', 'id');
|
||||
$groups = Group::orderBy('name', 'asc')->pluck('name', 'id');
|
||||
|
||||
$userGroups = $user->groups()->pluck('name', 'id');
|
||||
$user->permissions = $user->decodePermissions();
|
||||
@@ -325,7 +327,7 @@ class UsersController extends Controller
|
||||
|
||||
// Handle uploaded avatar
|
||||
app(ImageUploadRequest::class)->handleImages($user, 600, 'avatar', 'avatars', 'avatar');
|
||||
session()->put(['redirect_option' => $request->get('redirect_option')]);
|
||||
session()->put(['redirect_option' => $request->input('redirect_option')]);
|
||||
|
||||
if ($user->save()) {
|
||||
// Redirect to the user page
|
||||
@@ -351,10 +353,13 @@ class UsersController extends Controller
|
||||
if ($user = User::find($id)) {
|
||||
|
||||
$this->authorize('delete', $user);
|
||||
if (auth()->user()->can('canEditAuthFields', $user) && auth()->user()->can('editableOnDemo')) {
|
||||
|
||||
if ($user->delete()) {
|
||||
return redirect()->route('users.index')->with('success', trans('admin/users/message.success.delete'));
|
||||
if ($user->delete()) {
|
||||
return redirect()->route('users.index')->with('success', trans('admin/users/message.success.delete'));
|
||||
}
|
||||
}
|
||||
return redirect()->route('users.index')->with('error', trans('admin/users/message.cannot_delete'));
|
||||
}
|
||||
return redirect()->route('users.index')->with('error', trans('admin/users/message.user_not_found'));
|
||||
|
||||
|
||||
@@ -62,8 +62,8 @@ class ItemImportRequest extends FormRequest
|
||||
}
|
||||
$importer->setCallbacks([$this, 'log'], [$this, 'progress'], [$this, 'errorCallback'])
|
||||
->setCreatedBy(auth()->id())
|
||||
->setUpdating($this->get('import-update'))
|
||||
->setShouldNotify($this->get('send-welcome'))
|
||||
->setUpdating($this->input('import-update'))
|
||||
->setShouldNotify($this->input('send-welcome'))
|
||||
->setUsernameFormat('firstname.lastname')
|
||||
->setFieldMappings($fieldMappings);
|
||||
$importer->import();
|
||||
|
||||
@@ -44,7 +44,7 @@ class SaveUserRequest extends FormRequest
|
||||
case 'POST':
|
||||
$rules['first_name'] = 'required|string|min:1';
|
||||
$rules['username'] = 'required_unless:ldap_import,1|string|min:1';
|
||||
if ($this->request->get('ldap_import') == false) {
|
||||
if ($this->input('ldap_import') == false) {
|
||||
$rules['password'] = Setting::passwordComplexityRulesSaving('store').'|confirmed';
|
||||
}
|
||||
break;
|
||||
|
||||
@@ -19,6 +19,7 @@ class StoreAccessoryRequest extends ImageUploadRequest
|
||||
|
||||
public function prepareForValidation(): void
|
||||
{
|
||||
parent::prepareForValidation();
|
||||
|
||||
if ($this->category_id) {
|
||||
if ($category = Category::find($this->category_id)) {
|
||||
|
||||
@@ -19,6 +19,7 @@ class StoreConsumableRequest extends ImageUploadRequest
|
||||
|
||||
public function prepareForValidation(): void
|
||||
{
|
||||
parent::prepareForValidation();
|
||||
|
||||
if ($this->category_id) {
|
||||
if ($category = Category::find($this->category_id)) {
|
||||
|
||||
@@ -1,6 +1,7 @@
|
||||
<?php
|
||||
namespace App\Http\Transformers;
|
||||
|
||||
use App\Enums\ActionType;
|
||||
use App\Helpers\Helper;
|
||||
use App\Helpers\StorageHelper;
|
||||
use App\Models\Actionlog;
|
||||
@@ -80,7 +81,7 @@ class ActionlogsTransformer
|
||||
|
||||
// this is a custom field
|
||||
if (str_starts_with($fieldname, '_snipeit_')) {
|
||||
|
||||
|
||||
foreach ($custom_fields as $custom_field) {
|
||||
|
||||
if ($custom_field->db_column == $fieldname) {
|
||||
@@ -185,9 +186,9 @@ class ActionlogsTransformer
|
||||
'name' => e($actionlog->target->display_name) ?? null,
|
||||
'type' => e($actionlog->targetType()),
|
||||
] : null,
|
||||
|
||||
'quantity' => $this->getQuantity($actionlog),
|
||||
'note' => ($actionlog->note) ? Helper::parseEscapedMarkedownInline($actionlog->note): null,
|
||||
'signature_file' => ($actionlog->accept_signature) ? route('log.signature.view', ['filename' => $actionlog->accept_signature ]) : null,
|
||||
'signature_file' => (($actionlog->accept_signature) && Storage::exists('private_uploads/signatures/'.$actionlog->accept_signature)) ? route('log.signature.view', ['filename' => $actionlog->accept_signature ]) : null,
|
||||
'log_meta' => ((isset($clean_meta)) && (is_array($clean_meta))) ? $clean_meta: null,
|
||||
'remote_ip' => e($actionlog->remote_ip) ?? null,
|
||||
'user_agent' => e($actionlog->user_agent) ?? null,
|
||||
@@ -336,6 +337,26 @@ class ActionlogsTransformer
|
||||
|
||||
}
|
||||
|
||||
private function getQuantity(Actionlog $actionlog): ?int
|
||||
{
|
||||
if (!$actionlog->quantity) {
|
||||
return null;
|
||||
}
|
||||
|
||||
// only a few action types will have a quantity we are interested in.
|
||||
if (!in_array($actionlog->action_type, [
|
||||
ActionType::Checkout->value,
|
||||
ActionType::Accepted->value,
|
||||
ActionType::Declined->value,
|
||||
ActionType::CheckinFrom->value,
|
||||
ActionType::AddSeats->value,
|
||||
ActionType::DeleteSeats->value,
|
||||
])) {
|
||||
return null;
|
||||
}
|
||||
|
||||
return (int) $actionlog->quantity;
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
|
||||
@@ -104,6 +104,7 @@ class AssetsTransformer
|
||||
'next_audit_date' => Helper::getFormattedDateObject($asset->next_audit_date, 'date'),
|
||||
'deleted_at' => Helper::getFormattedDateObject($asset->deleted_at, 'datetime'),
|
||||
'purchase_date' => Helper::getFormattedDateObject($asset->purchase_date, 'date'),
|
||||
'first_checkout' => Helper::getFormattedDateObject($asset->first_checkout_at, 'datetime'),
|
||||
'age' => $asset->purchase_date ? $asset->purchase_date->locale(app()->getLocale())->diffForHumans() : '',
|
||||
'last_checkout' => Helper::getFormattedDateObject($asset->last_checkout, 'datetime'),
|
||||
'last_checkin' => Helper::getFormattedDateObject($asset->last_checkin, 'datetime'),
|
||||
|
||||
@@ -101,7 +101,7 @@ class UsersTransformer
|
||||
|
||||
$permissions_array['available_actions'] = [
|
||||
'update' => (Gate::allows('update', User::class) && ($user->deleted_at == '')),
|
||||
'delete' => $user->isDeletable(),
|
||||
'delete' => ($user->isDeletable() && (auth()->user()->can('canEditAuthFields', $user) && auth()->user()->can('editableOnDemo'))),
|
||||
'clone' => (Gate::allows('create', User::class) && ($user->deleted_at == '')),
|
||||
'restore' => (Gate::allows('create', User::class) && ($user->deleted_at != '')),
|
||||
];
|
||||
|
||||
@@ -85,9 +85,9 @@ class AssetImporter extends ItemImporter
|
||||
if ($this->findCsvMatch($row, 'id')!='') {
|
||||
// Override asset if an ID was given
|
||||
\Log::debug('Finding asset by ID: '.$this->findCsvMatch($row, 'id'));
|
||||
$asset = Asset::find($this->findCsvMatch($row, 'id'));
|
||||
$asset = Asset::with('assignedTo')->find($this->findCsvMatch($row, 'id'));
|
||||
} else {
|
||||
$asset = Asset::where(['asset_tag'=> (string) $asset_tag])->first();
|
||||
$asset = Asset::with('assignedTo')->where(['asset_tag' => (string) $asset_tag])->first();
|
||||
}
|
||||
|
||||
if ($asset) {
|
||||
@@ -203,7 +203,7 @@ class AssetImporter extends ItemImporter
|
||||
if (isset($target) && ($target !== false)) {
|
||||
if (!is_null($asset->assigned_to)){
|
||||
if ($asset->assigned_to != $target->id) {
|
||||
event(new CheckoutableCheckedIn($asset, User::find($asset->assigned_to), auth()->user(), 'Checkin from CSV Importer', $checkin_date));
|
||||
event(new CheckoutableCheckedIn($asset, $asset->assigned, auth()->user(), 'Checkin from CSV Importer', $checkin_date));
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -10,6 +10,7 @@ use App\Notifications\WelcomeNotification;
|
||||
use Illuminate\Support\Facades\Gate;
|
||||
use Illuminate\Support\Facades\Log;
|
||||
use Illuminate\Support\Facades\Password;
|
||||
use Illuminate\Support\Facades\Auth;
|
||||
|
||||
/**
|
||||
* This is ONLY used for the User Import. When we are importing users
|
||||
@@ -102,8 +103,7 @@ class UserImporter extends ItemImporter
|
||||
|
||||
$this->log('Updating User');
|
||||
|
||||
// Todo - check that this works
|
||||
if (!Gate::allows('canEditAuthFields', $user)) {
|
||||
if (Auth::check() && (!Gate::allows('canEditAuthFields', $user))) {
|
||||
unset($user->username);
|
||||
unset($user->email);
|
||||
unset($user->password);
|
||||
|
||||
@@ -128,11 +128,18 @@ class CheckoutableListener
|
||||
->notify($this->getCheckoutNotification($event, $acceptance));
|
||||
}
|
||||
} catch (ClientException $e) {
|
||||
$status = optional($e->getResponse()->getStatusCode());
|
||||
|
||||
if (strpos($e->getMessage(), 'channel_not_found') !== false) {
|
||||
Log::warning(Setting::getSettings()->webhook_selected . " notification failed: " . $e->getMessage());
|
||||
return redirect()->back()->with('warning', ucfirst(Setting::getSettings()->webhook_selected) . trans('admin/settings/message.webhook.webhook_channel_not_found'));
|
||||
} else {
|
||||
Log::error("ClientException caught during checkin notification: " . $e->getMessage());
|
||||
if ($status >= 500 || $status === null) {
|
||||
Log::error(Setting::getSettings()->webhook_selected . " notification failed: " . $e->getMessage());
|
||||
} else {
|
||||
Log::warning("ClientException caught during checkin notification: " . $e->getMessage());
|
||||
return redirect()->back()->with('warning', ucfirst(Setting::getSettings()->webhook_selected) . trans('admin/settings/message.webhook.webhook_fail'));
|
||||
}
|
||||
}
|
||||
return redirect()->back()->with('warning', ucfirst(Setting::getSettings()->webhook_selected) . trans('admin/settings/message.webhook.webhook_fail'));
|
||||
} catch (Exception $e) {
|
||||
@@ -224,12 +231,18 @@ class CheckoutableListener
|
||||
->notify($this->getCheckinNotification($event));
|
||||
}
|
||||
} catch (ClientException $e) {
|
||||
$status = optional($e->getResponse()->getStatusCode());
|
||||
|
||||
if (strpos($e->getMessage(), 'channel_not_found') !== false) {
|
||||
Log::warning(Setting::getSettings()->webhook_selected . " notification failed: " . $e->getMessage());
|
||||
return redirect()->back()->with('warning', ucfirst(Setting::getSettings()->webhook_selected) . trans('admin/settings/message.webhook.webhook_channel_not_found'));
|
||||
} else {
|
||||
Log::error("ClientException caught during checkin notification: " . $e->getMessage());
|
||||
return redirect()->back()->with('warning', ucfirst(Setting::getSettings()->webhook_selected) . trans('admin/settings/message.webhook.webhook_fail'));
|
||||
if ($status >= 500 || $status === null) {
|
||||
Log::error(Setting::getSettings()->webhook_selected . " notification failed: " . $e->getMessage());
|
||||
} else {
|
||||
Log::warning("ClientException caught during checkin notification: " . $e->getMessage());
|
||||
return redirect()->back()->with('warning', ucfirst(Setting::getSettings()->webhook_selected) . trans('admin/settings/message.webhook.webhook_fail'));
|
||||
}
|
||||
}
|
||||
} catch (Exception $e) {
|
||||
Log::warning(ucfirst(Setting::getSettings()->webhook_selected) . ' webhook notification failed:', [
|
||||
|
||||
@@ -47,7 +47,13 @@ class LogListener
|
||||
*/
|
||||
public function onCheckoutableCheckedOut(CheckoutableCheckedOut $event)
|
||||
{
|
||||
$event->checkoutable->logCheckout($event->note, $event->checkedOutTo, $event->checkoutable->last_checkout, $event->originalValues);
|
||||
$event->checkoutable->logCheckout(
|
||||
$event->note,
|
||||
$event->checkedOutTo,
|
||||
$event->checkoutable->last_checkout,
|
||||
$event->originalValues,
|
||||
$event->quantity
|
||||
);
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -66,6 +72,9 @@ class LogListener
|
||||
$logaction->note = $event->acceptance->note;
|
||||
$logaction->action_type = 'accepted';
|
||||
$logaction->action_date = $event->acceptance->accepted_at;
|
||||
$logaction->quantity = $event->acceptance->qty ?? 1;
|
||||
$logaction->created_by = auth()->user()->id;
|
||||
|
||||
|
||||
// TODO: log the actual license seat that was checked out
|
||||
if ($event->acceptance->checkoutable instanceof LicenseSeat) {
|
||||
@@ -84,6 +93,8 @@ class LogListener
|
||||
$logaction->note = $event->acceptance->note;
|
||||
$logaction->action_type = 'declined';
|
||||
$logaction->action_date = $event->acceptance->declined_at;
|
||||
$logaction->quantity = $event->acceptance->qty ?? 1;
|
||||
$logaction->created_by = auth()->user()->id;
|
||||
|
||||
// TODO: log the actual license seat that was checked out
|
||||
if ($event->acceptance->checkoutable instanceof LicenseSeat) {
|
||||
|
||||
@@ -409,14 +409,13 @@ class Importer extends Component
|
||||
'category' => trans('general.category'),
|
||||
'eol' => trans('general.eol'),
|
||||
'fieldset' => trans('admin/models/general.fieldset'),
|
||||
'item_name' => trans('general.item_name_var', ['item' => trans('general.asset_model')]),
|
||||
'name' => trans('general.item_name_var', ['item' => trans('general.asset_model')]),
|
||||
'manufacturer' => trans('general.manufacturer'),
|
||||
'min_amt' => trans('mail.min_QTY'),
|
||||
'model_number' => trans('general.model_no'),
|
||||
'notes' => trans('general.item_notes', ['item' => trans('admin/hardware/form.model')]),
|
||||
'requestable' => trans('admin/models/general.requestable'),
|
||||
'require_serial' => trans('admin/hardware/general.require_serial'),
|
||||
|
||||
];
|
||||
|
||||
// "real fieldnames" to a list of aliases for that field
|
||||
@@ -425,6 +424,8 @@ class Importer extends Component
|
||||
[
|
||||
'item name',
|
||||
'asset name',
|
||||
'model name',
|
||||
'asset model name',
|
||||
'accessory name',
|
||||
'user name',
|
||||
'consumable name',
|
||||
|
||||
@@ -18,10 +18,12 @@ class CheckoutAccessoryMail extends BaseMailable
|
||||
{
|
||||
use Queueable, SerializesModels;
|
||||
|
||||
private bool $firstTimeSending;
|
||||
|
||||
/**
|
||||
* Create a new message instance.
|
||||
*/
|
||||
public function __construct(Accessory $accessory, $checkedOutTo, User $checkedOutBy, $acceptance, $note)
|
||||
public function __construct(Accessory $accessory, $checkedOutTo, User $checkedOutBy, $acceptance, $note, bool $firstTimeSending = true)
|
||||
{
|
||||
$this->item = $accessory;
|
||||
$this->admin = $checkedOutBy;
|
||||
@@ -29,6 +31,7 @@ class CheckoutAccessoryMail extends BaseMailable
|
||||
$this->checkout_qty = $accessory->checkout_qty;
|
||||
$this->target = $checkedOutTo;
|
||||
$this->acceptance = $acceptance;
|
||||
$this->firstTimeSending = $firstTimeSending;
|
||||
$this->settings = Setting::getSettings();
|
||||
}
|
||||
|
||||
@@ -41,7 +44,7 @@ class CheckoutAccessoryMail extends BaseMailable
|
||||
|
||||
return new Envelope(
|
||||
from: $from,
|
||||
subject: trans_choice('mail.Accessory_Checkout_Notification', $this->checkout_qty),
|
||||
subject: $this->getSubject(),
|
||||
);
|
||||
}
|
||||
|
||||
@@ -88,14 +91,18 @@ class CheckoutAccessoryMail extends BaseMailable
|
||||
return trans_choice('mail.new_item_checked_location', $this->checkout_qty, ['location' => $this->target->name]);
|
||||
}
|
||||
|
||||
if ($this->requiresAcceptance()) {
|
||||
if ($this->firstTimeSending && $this->requiresAcceptance()) {
|
||||
return trans_choice('mail.new_item_checked_with_acceptance', $this->checkout_qty);
|
||||
}
|
||||
|
||||
if (!$this->requiresAcceptance()) {
|
||||
if ($this->firstTimeSending && !$this->requiresAcceptance()) {
|
||||
return trans_choice('mail.new_item_checked', $this->checkout_qty);
|
||||
}
|
||||
|
||||
if (!$this->firstTimeSending && $this->requiresAcceptance()) {
|
||||
return trans('mail.recent_item_checked');
|
||||
}
|
||||
|
||||
// we shouldn't get here but let's send a default message just in case
|
||||
return trans('new_item_checked');
|
||||
}
|
||||
@@ -113,4 +120,13 @@ class CheckoutAccessoryMail extends BaseMailable
|
||||
{
|
||||
return [];
|
||||
}
|
||||
|
||||
private function getSubject(): string
|
||||
{
|
||||
if ($this->firstTimeSending) {
|
||||
return trans_choice('mail.Accessory_Checkout_Notification', $this->checkout_qty);
|
||||
}
|
||||
|
||||
return trans('mail.unaccepted_asset_reminder');
|
||||
}
|
||||
}
|
||||
|
||||
@@ -15,10 +15,12 @@ class CheckoutConsumableMail extends BaseMailable
|
||||
{
|
||||
use Queueable, SerializesModels;
|
||||
|
||||
private bool $firstTimeSending;
|
||||
|
||||
/**
|
||||
* Create a new message instance.
|
||||
*/
|
||||
public function __construct(Consumable $consumable, $checkedOutTo, User $checkedOutBy, $acceptance, $note)
|
||||
public function __construct(Consumable $consumable, $checkedOutTo, User $checkedOutBy, $acceptance, $note, bool $firstTimeSending = true)
|
||||
{
|
||||
$this->item = $consumable;
|
||||
$this->admin = $checkedOutBy;
|
||||
@@ -26,6 +28,7 @@ class CheckoutConsumableMail extends BaseMailable
|
||||
$this->target = $checkedOutTo;
|
||||
$this->acceptance = $acceptance;
|
||||
$this->qty = $consumable->checkout_qty;
|
||||
$this->firstTimeSending = $firstTimeSending;
|
||||
|
||||
$this->settings = Setting::getSettings();
|
||||
}
|
||||
@@ -39,7 +42,7 @@ class CheckoutConsumableMail extends BaseMailable
|
||||
|
||||
return new Envelope(
|
||||
from: $from,
|
||||
subject: trans('mail.Confirm_consumable_delivery'),
|
||||
subject: $this->getSubject(),
|
||||
);
|
||||
}
|
||||
|
||||
@@ -65,6 +68,7 @@ class CheckoutConsumableMail extends BaseMailable
|
||||
'req_accept' => $req_accept,
|
||||
'accept_url' => $accept_url,
|
||||
'qty' => $this->qty,
|
||||
'introduction_line' => $this->introductionLine(),
|
||||
]
|
||||
);
|
||||
}
|
||||
@@ -78,4 +82,36 @@ class CheckoutConsumableMail extends BaseMailable
|
||||
{
|
||||
return [];
|
||||
}
|
||||
|
||||
private function getSubject(): string
|
||||
{
|
||||
if ($this->firstTimeSending) {
|
||||
return trans('mail.Confirm_consumable_delivery');
|
||||
}
|
||||
|
||||
return trans('mail.unaccepted_asset_reminder');
|
||||
}
|
||||
|
||||
private function introductionLine()
|
||||
{
|
||||
if ($this->firstTimeSending && $this->requiresAcceptance()) {
|
||||
return trans_choice('mail.new_item_checked_with_acceptance', $this->qty);
|
||||
}
|
||||
|
||||
if ($this->firstTimeSending && !$this->requiresAcceptance()) {
|
||||
return trans_choice('mail.new_item_checked', $this->qty);
|
||||
}
|
||||
|
||||
if (!$this->firstTimeSending && $this->requiresAcceptance()) {
|
||||
return trans('mail.recent_item_checked');
|
||||
}
|
||||
|
||||
// we shouldn't get here but let's send a default message just in case
|
||||
return trans('new_item_checked');
|
||||
}
|
||||
|
||||
private function requiresAcceptance(): int|bool
|
||||
{
|
||||
return method_exists($this->item, 'requireAcceptance') ? $this->item->requireAcceptance() : 0;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -16,10 +16,12 @@ class CheckoutLicenseMail extends BaseMailable
|
||||
{
|
||||
use Queueable, SerializesModels;
|
||||
|
||||
private bool $firstTimeSending;
|
||||
|
||||
/**
|
||||
* Create a new message instance.
|
||||
*/
|
||||
public function __construct(LicenseSeat $licenseSeat, $checkedOutTo, User $checkedOutBy, $acceptance, $note)
|
||||
public function __construct(LicenseSeat $licenseSeat, $checkedOutTo, User $checkedOutBy, $acceptance, $note, bool $firstTimeSending = true)
|
||||
{
|
||||
$this->item = $licenseSeat;
|
||||
$this->admin = $checkedOutBy;
|
||||
@@ -27,6 +29,7 @@ class CheckoutLicenseMail extends BaseMailable
|
||||
$this->acceptance = $acceptance;
|
||||
$this->settings = Setting::getSettings();
|
||||
$this->target = $checkedOutTo;
|
||||
$this->firstTimeSending = $firstTimeSending;
|
||||
|
||||
if($this->target instanceof User){
|
||||
$this->target = $this->target->display_name;
|
||||
@@ -45,7 +48,7 @@ class CheckoutLicenseMail extends BaseMailable
|
||||
|
||||
return new Envelope(
|
||||
from: $from,
|
||||
subject: trans('mail.Confirm_license_delivery'),
|
||||
subject: $this->getSubject(),
|
||||
);
|
||||
}
|
||||
|
||||
@@ -69,6 +72,7 @@ class CheckoutLicenseMail extends BaseMailable
|
||||
'eula' => $eula,
|
||||
'req_accept' => $req_accept,
|
||||
'accept_url' => $accept_url,
|
||||
'introduction_line' => $this->introductionLine(),
|
||||
]
|
||||
);
|
||||
}
|
||||
@@ -82,4 +86,36 @@ class CheckoutLicenseMail extends BaseMailable
|
||||
{
|
||||
return [];
|
||||
}
|
||||
|
||||
private function getSubject(): string
|
||||
{
|
||||
if ($this->firstTimeSending) {
|
||||
return trans('mail.Confirm_license_delivery');
|
||||
}
|
||||
|
||||
return trans('mail.unaccepted_asset_reminder');
|
||||
}
|
||||
|
||||
private function introductionLine(): string
|
||||
{
|
||||
if ($this->firstTimeSending && $this->requiresAcceptance()) {
|
||||
return trans_choice('mail.new_item_checked_with_acceptance', 1);
|
||||
}
|
||||
|
||||
if ($this->firstTimeSending && !$this->requiresAcceptance()) {
|
||||
return trans_choice('mail.new_item_checked', 1);
|
||||
}
|
||||
|
||||
if (!$this->firstTimeSending && $this->requiresAcceptance()) {
|
||||
return trans('mail.recent_item_checked');
|
||||
}
|
||||
|
||||
// we shouldn't get here but let's send a default message just in case
|
||||
return trans('new_item_checked');
|
||||
}
|
||||
|
||||
private function requiresAcceptance(): int|bool
|
||||
{
|
||||
return method_exists($this->item, 'requireAcceptance') ? $this->item->requireAcceptance() : 0;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -61,7 +61,7 @@ class Accessory extends SnipeModel
|
||||
* Accessory validation rules
|
||||
*/
|
||||
public $rules = [
|
||||
'name' => 'required|min:3|max:255',
|
||||
'name' => 'required|max:255',
|
||||
'qty' => 'required|integer|min:1',
|
||||
'category_id' => 'required|integer|exists:categories,id',
|
||||
'company_id' => 'integer|nullable',
|
||||
|
||||
@@ -20,6 +20,7 @@ use Watson\Validating\ValidatingTrait;
|
||||
*/
|
||||
class AccessoryCheckout extends Model
|
||||
{
|
||||
use HasFactory;
|
||||
use Searchable;
|
||||
|
||||
protected $fillable = [
|
||||
@@ -41,7 +42,7 @@ class AccessoryCheckout extends Model
|
||||
*/
|
||||
public function accessory()
|
||||
{
|
||||
return $this->hasOne(Accessory::class, 'id', 'accessory_id');
|
||||
return $this->belongsTo(Accessory::class);
|
||||
}
|
||||
|
||||
public function accessories()
|
||||
@@ -57,7 +58,7 @@ class AccessoryCheckout extends Model
|
||||
*/
|
||||
public function adminuser()
|
||||
{
|
||||
return $this->hasOne(\App\Models\User::class, 'id', 'created_by');
|
||||
return $this->belongsTo(User::class, 'created_by');
|
||||
}
|
||||
|
||||
/**
|
||||
|
||||
@@ -375,7 +375,7 @@ class Actionlog extends SnipeModel
|
||||
}
|
||||
|
||||
// Show as negative number if the next audit date is before the audit date we're looking at
|
||||
if ($this->created_at > $override_default_next) {
|
||||
if ($this->created_at->toDateString() > $override_default_next->toDateString()) {
|
||||
$next_audit_days = '-'.$next_audit_days;
|
||||
}
|
||||
|
||||
|
||||
@@ -570,7 +570,7 @@ class Asset extends Depreciable
|
||||
if (is_array(request()->input($field->db_column))) {
|
||||
$this->{$field->db_column} = Crypt::encrypt(implode(', ', request()->input($field->db_column)));
|
||||
} else {
|
||||
$this->{$field->db_column} = Crypt::encrypt(request()->get($field->db_column));
|
||||
$this->{$field->db_column} = Crypt::encrypt(request()->input($field->db_column));
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -85,7 +85,7 @@ class CheckoutAcceptance extends Model
|
||||
/**
|
||||
* The user that the checkoutable was checked out to
|
||||
*
|
||||
* @return Illuminate\Database\Eloquent\Relations\BelongsTo
|
||||
* @return \Illuminate\Database\Eloquent\Relations\BelongsTo
|
||||
*/
|
||||
public function assignedTo()
|
||||
{
|
||||
@@ -186,6 +186,10 @@ class CheckoutAcceptance extends Model
|
||||
);
|
||||
}
|
||||
|
||||
protected function scopeHasFiles(Builder $query) {
|
||||
return $query->whereNotNull('signature_filename')->orWhereNotNull('stored_eula_file');
|
||||
}
|
||||
|
||||
public function generateAcceptancePdf($data, $pdf_filename) {
|
||||
|
||||
// set some language dependent data:
|
||||
|
||||
@@ -27,10 +27,10 @@ final class Company extends SnipeModel
|
||||
|
||||
// Declare the rules for the model validation
|
||||
protected $rules = [
|
||||
'name' => 'required|min:1|max:255|unique:companies,name',
|
||||
'name' => 'required|max:255|unique:companies,name',
|
||||
'fax' => 'min:7|max:35|nullable',
|
||||
'phone' => 'min:7|max:35|nullable',
|
||||
'email' => 'email|max:150|nullable',
|
||||
'email' => 'email|max:150|nullable',
|
||||
];
|
||||
|
||||
protected $presenter = \App\Presenters\CompanyPresenter::class;
|
||||
|
||||
@@ -36,7 +36,7 @@ class Component extends SnipeModel
|
||||
* Category validation rules
|
||||
*/
|
||||
public $rules = [
|
||||
'name' => 'required|min:3|max:191',
|
||||
'name' => 'required|max:191',
|
||||
'qty' => 'required|integer|min:1',
|
||||
'category_id' => 'required|integer|exists:categories,id',
|
||||
'supplier_id' => 'nullable|integer|exists:suppliers,id',
|
||||
@@ -269,7 +269,7 @@ class Component extends SnipeModel
|
||||
// is *not* null - so we don't have to keep recalculating for un-checked-out components
|
||||
// NOTE: doing this will add a 'pseudo-attribute' to the component in question, so we need to _remove_ this
|
||||
// before we save - so that gets handled in the 'saving' callback defined in the 'booted' method, above.
|
||||
$this->sum_unconstrained_assets = $this->uncontrainedAssets()->sum('assigned_qty') ?? 0;
|
||||
$this->sum_unconstrained_assets = $this->unconstrainedAssets()->sum('assigned_qty') ?? 0;
|
||||
}
|
||||
return $this->sum_unconstrained_assets;
|
||||
}
|
||||
@@ -280,7 +280,7 @@ class Component extends SnipeModel
|
||||
*
|
||||
* This allows us to get the assets with assigned components without the company restriction
|
||||
*/
|
||||
public function uncontrainedAssets()
|
||||
public function unconstrainedAssets()
|
||||
{
|
||||
|
||||
return $this->belongsToMany(\App\Models\Asset::class, 'components_assets')
|
||||
|
||||
@@ -42,7 +42,7 @@ class Consumable extends SnipeModel
|
||||
* Category validation rules
|
||||
*/
|
||||
public $rules = [
|
||||
'name' => 'required|min:3|max:255',
|
||||
'name' => 'required|max:255',
|
||||
'qty' => 'required|integer|min:0|max:99999',
|
||||
'category_id' => 'required|integer',
|
||||
'company_id' => 'integer|nullable',
|
||||
|
||||
@@ -2,6 +2,8 @@
|
||||
|
||||
namespace App\Models;
|
||||
|
||||
use App\Models\Traits\Loggable;
|
||||
use App\Presenters\Presentable;
|
||||
use App\Rules\AlphaEncrypted;
|
||||
use App\Rules\BooleanEncrypted;
|
||||
use App\Rules\DateEncrypted;
|
||||
@@ -18,10 +20,13 @@ use Illuminate\Database\Eloquent\Factories\HasFactory;
|
||||
use Illuminate\Database\Eloquent\Model;
|
||||
use Watson\Validating\ValidatingTrait;
|
||||
|
||||
class CustomFieldset extends Model
|
||||
class CustomFieldset extends SnipeModel
|
||||
{
|
||||
use HasFactory;
|
||||
use ValidatingTrait;
|
||||
use Presentable;
|
||||
|
||||
protected $presenter = \App\Presenters\CustomFieldsetPresenter::class;
|
||||
|
||||
protected $guarded = ['id'];
|
||||
|
||||
|
||||
@@ -5,6 +5,7 @@ namespace App\Models;
|
||||
use App\Models\Traits\Searchable;
|
||||
use App\Presenters\Presentable;
|
||||
use Illuminate\Database\Eloquent\Factories\HasFactory;
|
||||
use Illuminate\Support\Facades\Gate;
|
||||
use Watson\Validating\ValidatingTrait;
|
||||
|
||||
class Depreciation extends SnipeModel
|
||||
@@ -15,7 +16,7 @@ class Depreciation extends SnipeModel
|
||||
use Presentable;
|
||||
// Declare the rules for the form validation
|
||||
protected $rules = [
|
||||
'name' => 'required|min:3|max:255|unique:depreciations,name',
|
||||
'name' => 'required|max:255|unique:depreciations,name',
|
||||
'months' => 'required|max:3600|integer',
|
||||
];
|
||||
|
||||
@@ -52,6 +53,16 @@ class Depreciation extends SnipeModel
|
||||
*/
|
||||
protected $searchableRelations = [];
|
||||
|
||||
|
||||
public function isDeletable()
|
||||
{
|
||||
return Gate::allows('delete', $this)
|
||||
&& (($this->assets_count ?? $this->assets()->count()) === 0)
|
||||
&& (($this->licenses_count ?? $this->licenses()->count()) === 0)
|
||||
&& (($this->models_count ?? $this->models()->count()) === 0)
|
||||
&& ($this->deleted_at == '');
|
||||
}
|
||||
|
||||
/**
|
||||
* Establishes the depreciation -> models relationship
|
||||
*
|
||||
|
||||
@@ -13,7 +13,7 @@ class Group extends SnipeModel
|
||||
protected $table = 'permission_groups';
|
||||
|
||||
public $rules = [
|
||||
'name' => 'required|min:2|max:255|unique',
|
||||
'name' => 'required|max:255|unique',
|
||||
];
|
||||
|
||||
protected $fillable = [
|
||||
|
||||
@@ -3,6 +3,8 @@
|
||||
namespace App\Models\Labels\Sheets\Avery;
|
||||
|
||||
|
||||
use App\Helpers\Helper;
|
||||
|
||||
class L4736_A extends L4736
|
||||
{
|
||||
private const BARCODE_MARGIN = 1.80;
|
||||
@@ -96,38 +98,38 @@ class L4736_A extends L4736
|
||||
$usableWidth -= $barcodeSize + self::BARCODE_MARGIN;
|
||||
}
|
||||
$fields = $record->get('fields');
|
||||
$fieldCount = count($fields);
|
||||
|
||||
$perFieldHeight = (self::LABEL_SIZE + self::LABEL_MARGIN)
|
||||
+ (self::FIELD_SIZE + self::FIELD_MARGIN);
|
||||
$field_layout = Helper::labelFieldLayoutScaling(
|
||||
pdf: $pdf,
|
||||
fields: $fields,
|
||||
currentX: $currentX,
|
||||
usableWidth: $usableWidth,
|
||||
usableHeight: $usableHeight,
|
||||
baseLabelSize: self::LABEL_SIZE,
|
||||
baseFieldSize: self::FIELD_SIZE,
|
||||
baseFieldMargin: self::FIELD_MARGIN,
|
||||
baseLabelPadding: 1.5,
|
||||
baseGap: 1.5,
|
||||
maxScale: 1.8,
|
||||
labelFont: 'freesans',
|
||||
);
|
||||
|
||||
$baseHeight = $fieldCount * $perFieldHeight;
|
||||
$scale = 1.0;
|
||||
if ($baseHeight > $usableHeight && $baseHeight > 0) {
|
||||
$scale = $usableHeight / $baseHeight;
|
||||
}
|
||||
|
||||
$labelSize = self::LABEL_SIZE * $scale;
|
||||
$labelMargin = self::LABEL_MARGIN * $scale;
|
||||
$fieldSize = self::FIELD_SIZE * $scale;
|
||||
$fieldMargin = self::FIELD_MARGIN * $scale;
|
||||
|
||||
foreach ($fields as $field) {
|
||||
static::writeText(
|
||||
$pdf, $field['label'],
|
||||
$currentX, $currentY,
|
||||
'freesans', '', $labelSize, 'L',
|
||||
$usableWidth, $labelSize, true, 0
|
||||
'freesans', '', $field_layout['labelSize'], 'L',
|
||||
$field_layout['labelWidth'], $field_layout['rowAdvance'], true, 0
|
||||
);
|
||||
$currentY += $labelSize + $labelMargin;
|
||||
|
||||
static::writeText(
|
||||
$pdf, $field['value'],
|
||||
$currentX, $currentY,
|
||||
'freemono', 'B', $fieldSize, 'L',
|
||||
$usableWidth, $fieldSize, true, 0, 0.01
|
||||
$field_layout['valueX'], $currentY,
|
||||
'freemono', 'B', $field_layout['fieldSize'], 'L',
|
||||
$field_layout['valueWidth'], $field_layout['rowAdvance'], true, 0, 0.01
|
||||
);
|
||||
$currentY += $fieldSize + $fieldMargin;
|
||||
$currentY += $field_layout['rowAdvance'];
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@@ -2,6 +2,8 @@
|
||||
|
||||
namespace App\Models\Labels\Sheets\Avery;
|
||||
|
||||
use App\Helpers\Helper;
|
||||
|
||||
class L6009_A extends L6009
|
||||
{
|
||||
private const BARCODE_MARGIN = 1.80;
|
||||
@@ -60,43 +62,36 @@ class L6009_A extends L6009
|
||||
$usableWidth -= $barcodeSize + self::BARCODE_MARGIN;
|
||||
}
|
||||
$fields = $record->get('fields');
|
||||
// Below rescales the size of the field box to fit, it feels like it could/should be abstracted one class above
|
||||
// to be usable on other labels but im unsure of how to implement that, since it uses a lot of private
|
||||
// constants.
|
||||
|
||||
// Figure out how tall the label fields wants to be
|
||||
$fieldCount = count($fields);
|
||||
$perFieldHeight = (self::LABEL_SIZE + self::LABEL_MARGIN)
|
||||
+ (self::FIELD_SIZE + self::FIELD_MARGIN);
|
||||
|
||||
$baseHeight = $fieldCount * $perFieldHeight;
|
||||
// If it doesn't fit in the available height, scale everything down
|
||||
$scale = 1.0;
|
||||
if ($baseHeight > $usableHeight && $baseHeight > 0) {
|
||||
$scale = $usableHeight / $baseHeight;
|
||||
}
|
||||
|
||||
$labelSize = self::LABEL_SIZE * $scale;
|
||||
$labelMargin = self::LABEL_MARGIN * $scale;
|
||||
$fieldSize = self::FIELD_SIZE * $scale;
|
||||
$fieldMargin = self::FIELD_MARGIN * $scale;
|
||||
|
||||
$field_layout = Helper::labelFieldLayoutScaling(
|
||||
pdf: $pdf,
|
||||
fields: $fields,
|
||||
currentX: $currentX,
|
||||
usableWidth: $usableWidth,
|
||||
usableHeight: $usableHeight,
|
||||
baseLabelSize: self::LABEL_SIZE,
|
||||
baseFieldSize: self::FIELD_SIZE,
|
||||
baseFieldMargin: self::FIELD_MARGIN,
|
||||
baseLabelPadding: 1.5,
|
||||
baseGap: 1.5,
|
||||
maxScale: 1.8,
|
||||
labelFont: 'freesans',
|
||||
);
|
||||
foreach ($fields as $field) {
|
||||
static::writeText(
|
||||
$pdf, $field['label'],
|
||||
$currentX, $currentY,
|
||||
'freesans', '', $labelSize, 'L',
|
||||
$usableWidth, $labelSize, true, 0
|
||||
'freesans', '', $field_layout['labelSize'], 'L',
|
||||
$field_layout['labelWidth'], $field_layout['rowAdvance'], true, 0
|
||||
);
|
||||
$currentY += $labelSize + $labelMargin;
|
||||
|
||||
static::writeText(
|
||||
$pdf, $field['value'],
|
||||
$currentX, $currentY,
|
||||
'freemono', 'B', $fieldSize, 'L',
|
||||
$usableWidth, $fieldSize, true, 0, 0.01
|
||||
$field_layout['valueX'], $currentY,
|
||||
'freemono', 'B', $field_layout['fieldSize'], 'L',
|
||||
$field_layout['valueWidth'], $field_layout['rowAdvance'], true, 0, 0.01
|
||||
);
|
||||
$currentY += $fieldSize + $fieldMargin;
|
||||
$currentY += $field_layout['rowAdvance'];
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -3,16 +3,18 @@
|
||||
namespace App\Models\Labels\Sheets\Avery;
|
||||
|
||||
|
||||
use App\Helpers\Helper;
|
||||
|
||||
class L7163_A extends L7163
|
||||
{
|
||||
private const BARCODE_MARGIN = 1.80;
|
||||
private const TAG_SIZE = 4.80;
|
||||
private const TITLE_SIZE = 5.00;
|
||||
private const TITLE_MARGIN = 1.80;
|
||||
private const LABEL_SIZE = 2.35;
|
||||
private const TITLE_MARGIN = .75;
|
||||
private const LABEL_SIZE = 3.35;
|
||||
private const LABEL_MARGIN = - 0.30;
|
||||
private const FIELD_SIZE = 4.80;
|
||||
private const FIELD_MARGIN = 0.30;
|
||||
private const FIELD_MARGIN = 0.20;
|
||||
|
||||
public function getUnit()
|
||||
{
|
||||
@@ -74,17 +76,7 @@ class L7163_A extends L7163
|
||||
$currentX = $pa->x1;
|
||||
$currentY = $pa->y1;
|
||||
|
||||
if ($record->has('title')) {
|
||||
static::writeText(
|
||||
$pdf, $record->get('title'),
|
||||
$currentX, $currentY,
|
||||
'freesans', '', self::TITLE_SIZE, 'C',
|
||||
$usableWidth, self::TITLE_SIZE, true, 0
|
||||
);
|
||||
$currentY += self::TITLE_SIZE + self::TITLE_MARGIN;
|
||||
}
|
||||
|
||||
$barcodeSize = $pa->h - self::TITLE_SIZE - self::TITLE_MARGIN - self::TAG_SIZE;
|
||||
$barcodeSize = $pa->h - self::TAG_SIZE;
|
||||
|
||||
if ($record->has('barcode2d')) {
|
||||
static::writeText(
|
||||
@@ -108,25 +100,71 @@ class L7163_A extends L7163
|
||||
$usableWidth, self::TAG_SIZE, true, 0
|
||||
);
|
||||
}
|
||||
$title = $record->has('title') ? $record->get('title') : null;
|
||||
$fields = $record->get('fields');
|
||||
|
||||
foreach ($record->get('fields') as $field) {
|
||||
$field_layout = Helper::labelFieldLayoutScaling(
|
||||
pdf: $pdf,
|
||||
fields: $fields,
|
||||
currentX: $currentX,
|
||||
usableWidth: $usableWidth,
|
||||
usableHeight: $usableHeight,
|
||||
baseLabelSize: self::LABEL_SIZE,
|
||||
baseFieldSize: self::FIELD_SIZE,
|
||||
baseFieldMargin: self::FIELD_MARGIN,
|
||||
title: $title,
|
||||
baseTitleSize: self::TITLE_SIZE,
|
||||
baseTitleMargin: self::TITLE_MARGIN,
|
||||
baseLabelPadding: 1.5,
|
||||
baseGap: 1.5,
|
||||
maxScale: 1.8,
|
||||
labelFont: 'freesans',
|
||||
);
|
||||
|
||||
if ($field_layout['hasTitle']) {
|
||||
static::writeText(
|
||||
$pdf, $field['label'],
|
||||
$pdf, $title,
|
||||
$currentX, $currentY,
|
||||
'freesans', '', self::LABEL_SIZE, 'L',
|
||||
$usableWidth, self::LABEL_SIZE, true, 0
|
||||
'freesans', 'b', $field_layout['titleSize'], 'L',
|
||||
$usableWidth, $field_layout['titleSize'], true, 0
|
||||
);
|
||||
$currentY += $field_layout['titleAdvance'];
|
||||
}
|
||||
|
||||
foreach ($fields as $field) {
|
||||
$rawLabel = $field['label'] ?? null;
|
||||
$value = (string)($field['value'] ?? '');
|
||||
|
||||
// No label: value takes the whole row
|
||||
if (!is_string($rawLabel) || trim($rawLabel) === '') {
|
||||
static::writeText(
|
||||
$pdf, $value,
|
||||
$currentX, $currentY,
|
||||
'freemono', 'B', $field_layout['fieldSize'], 'L',
|
||||
$usableWidth, $field_layout['rowAdvance'], true, 0, 0.01
|
||||
);
|
||||
|
||||
$currentY += $field_layout['rowAdvance'];
|
||||
continue;
|
||||
}
|
||||
|
||||
$labelText = rtrim($field['label'], ':') . ':';
|
||||
|
||||
static::writeText(
|
||||
$pdf, $labelText,
|
||||
$currentX, $currentY,
|
||||
'freesans', '', $field_layout['labelSize'], 'L',
|
||||
$field_layout['labelWidth'], $field_layout['rowAdvance'], true,
|
||||
);
|
||||
$currentY += self::LABEL_SIZE + self::LABEL_MARGIN;
|
||||
|
||||
static::writeText(
|
||||
$pdf, $field['value'],
|
||||
$currentX, $currentY,
|
||||
'freemono', 'B', self::FIELD_SIZE, 'L',
|
||||
$usableWidth, self::FIELD_SIZE, true, 0, 0.5
|
||||
$field_layout['valueX'], $currentY,
|
||||
'freemono', 'B', $field_layout['fieldSize'], 'L',
|
||||
$field_layout['valueWidth'], $field_layout['rowAdvance'], true, 0, 0.01
|
||||
);
|
||||
$currentY += self::FIELD_SIZE + self::FIELD_MARGIN;
|
||||
$currentY += $field_layout['rowAdvance'];;
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -2,6 +2,8 @@
|
||||
|
||||
namespace App\Models\Labels\Tapes\Brother;
|
||||
|
||||
use App\Helpers\Helper;
|
||||
|
||||
class TZe_241 extends TZe_18mm
|
||||
{
|
||||
private const LABEL_SIZE = 5.0;
|
||||
@@ -55,40 +57,36 @@ class TZe_241 extends TZe_18mm
|
||||
|
||||
$fields = $record->get('fields') ?? [];
|
||||
|
||||
$fieldCount = count($fields);
|
||||
|
||||
$perFieldHeight = (self::LABEL_SIZE + self::LABEL_MARGIN)
|
||||
+ (self::FIELD_SIZE + self::FIELD_MARGIN);
|
||||
|
||||
$baseHeight = $fieldCount * $perFieldHeight;
|
||||
|
||||
// If it doesn't fit in the available height, scale everything down
|
||||
$scale = 1.0;
|
||||
if ($baseHeight > $usableHeight && $baseHeight > 0) {
|
||||
$scale = $usableHeight / $baseHeight;
|
||||
}
|
||||
|
||||
$labelSize = self::LABEL_SIZE * $scale;
|
||||
$labelMargin = self::LABEL_MARGIN * $scale;
|
||||
$fieldSize = self::FIELD_SIZE * $scale;
|
||||
$fieldMargin = self::FIELD_MARGIN * $scale;
|
||||
$field_layout = Helper::labelFieldLayoutScaling(
|
||||
pdf: $pdf,
|
||||
fields: $fields,
|
||||
currentX: $currentX,
|
||||
usableWidth: $usableWidth,
|
||||
usableHeight: $usableHeight,
|
||||
baseLabelSize: self::LABEL_SIZE,
|
||||
baseFieldSize: self::FIELD_SIZE,
|
||||
baseFieldMargin: self::FIELD_MARGIN,
|
||||
baseLabelPadding: 1.5,
|
||||
baseGap: 1.5,
|
||||
maxScale: 1.8,
|
||||
labelFont: 'freesans',
|
||||
);
|
||||
|
||||
foreach ($fields as $field) {
|
||||
static::writeText(
|
||||
$pdf, $field['label'],
|
||||
$currentX, $currentY,
|
||||
'freesans', '', $labelSize, 'L',
|
||||
$usableWidth, $labelSize, true, 0
|
||||
'freesans', '', $field_layout['labelSize'], 'L',
|
||||
$field_layout['labelWidth'], $field_layout['rowAdvance'], true, 0
|
||||
);
|
||||
$currentY += $labelSize + $labelMargin;
|
||||
|
||||
static::writeText(
|
||||
$pdf, $field['value'],
|
||||
$currentX, $currentY,
|
||||
'freemono', 'B', $fieldSize, 'L',
|
||||
$usableWidth, $fieldSize, true, 0, 0.01
|
||||
$field_layout['valueX'], $currentY,
|
||||
'freemono', 'B', $field_layout['fieldSize'], 'L',
|
||||
$field_layout['valueWidth'], $field_layout['rowAdvance'], true, 0, 0.01
|
||||
);
|
||||
$currentY += $fieldSize + $fieldMargin;
|
||||
$currentY += $field_layout['rowAdvance'];
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -2,6 +2,8 @@
|
||||
|
||||
namespace App\Models\Labels\Tapes\Brother;
|
||||
|
||||
use App\Helpers\Helper;
|
||||
|
||||
class TZe_24mm_E extends TZe_24mm
|
||||
{
|
||||
private const BARCODE_MARGIN = 1.75;
|
||||
@@ -71,49 +73,39 @@ class TZe_24mm_E extends TZe_24mm
|
||||
}
|
||||
|
||||
$fields = $record->get('fields');
|
||||
// Figure out how tall the label fields wants to be
|
||||
$fieldCount = count($fields);
|
||||
$perFieldHeight = (self::LABEL_SIZE + self::LABEL_MARGIN)
|
||||
+ (self::FIELD_SIZE + self::FIELD_MARGIN);
|
||||
|
||||
$baseHeight = $fieldCount * $perFieldHeight;
|
||||
// If it doesn't fit in the available height, scale everything down
|
||||
$scale = 1.0;
|
||||
if ($baseHeight > $usableHeight && $baseHeight > 0) {
|
||||
$scale = $usableHeight / $baseHeight;
|
||||
}
|
||||
$field_layout = Helper::labelFieldLayoutScaling(
|
||||
pdf: $pdf,
|
||||
fields: $fields,
|
||||
currentX: $currentX,
|
||||
usableWidth: $usableWidth,
|
||||
usableHeight: $usableHeight,
|
||||
baseLabelSize: self::LABEL_SIZE,
|
||||
baseFieldSize: self::FIELD_SIZE,
|
||||
baseFieldMargin: self::FIELD_MARGIN,
|
||||
baseLabelPadding: 1.5,
|
||||
baseGap: 1.5,
|
||||
maxScale: 1.8,
|
||||
labelFont: 'freesans',
|
||||
);
|
||||
|
||||
$labelSize = self::LABEL_SIZE * $scale;
|
||||
$fieldSize = self::FIELD_SIZE * $scale;
|
||||
$fieldMargin = self::FIELD_MARGIN * $scale;
|
||||
foreach ($fields as $field) {
|
||||
static::writeText(
|
||||
$pdf, $field['label'],
|
||||
$currentX, $currentY,
|
||||
'freesans', '', $field_layout['labelSize'], 'L',
|
||||
$field_layout['labelWidth'], $field_layout['rowAdvance'], true, 0
|
||||
);
|
||||
|
||||
foreach ($fields as $field) {
|
||||
// Write label and value on the same line
|
||||
// Calculate label width with proportional character spacing
|
||||
$labelWidth = $pdf->GetStringWidth($field['label'], 'freesans', '', $labelSize);
|
||||
$charCount = strlen($field['label']);
|
||||
$spacingPerChar = 0.5;
|
||||
$totalSpacing = $charCount * $spacingPerChar;
|
||||
$adjustedWidth = $labelWidth + $totalSpacing;
|
||||
static::writeText(
|
||||
$pdf, $field['value'],
|
||||
$field_layout['valueX'], $currentY,
|
||||
'freemono', 'B', $field_layout['fieldSize'], 'L',
|
||||
$field_layout['valueWidth'], $field_layout['rowAdvance'], true, 0, 0.01
|
||||
);
|
||||
$currentY += $field_layout['rowAdvance'];
|
||||
}
|
||||
|
||||
static::writeText(
|
||||
$pdf, $field['label'],
|
||||
$currentX, $currentY,
|
||||
'freesans', 'B', $labelSize, 'L',
|
||||
$adjustedWidth, $labelSize, true, 0, $spacingPerChar
|
||||
);
|
||||
|
||||
static::writeText(
|
||||
$pdf, $field['value'],
|
||||
$currentX + $adjustedWidth + 2, $currentY,
|
||||
'freesans', 'B', $fieldSize, 'L',
|
||||
$usableWidth - $adjustedWidth - 2, $fieldSize, true, 0, 0.3
|
||||
);
|
||||
|
||||
$currentY += max($labelSize, $fieldSize) +$fieldMargin;
|
||||
}
|
||||
|
||||
|
||||
if ($record->has('barcode1d')) {
|
||||
static::write1DBarcode(
|
||||
$pdf, $record->get('barcode1d')->content, $record->get('barcode1d')->type,
|
||||
|
||||
@@ -3,6 +3,8 @@
|
||||
namespace App\Models\Labels\Tapes\Dymo;
|
||||
|
||||
|
||||
use App\Helpers\Helper;
|
||||
|
||||
class LabelWriter_11354 extends LabelWriter
|
||||
{
|
||||
private const BARCODE1D_HEIGHT = 3.00;
|
||||
@@ -94,57 +96,80 @@ class LabelWriter_11354 extends LabelWriter
|
||||
}
|
||||
|
||||
// Right column
|
||||
if ($record->has('title')) {
|
||||
static::writeText(
|
||||
$pdf, $record->get('title'),
|
||||
$currentX, $currentY,
|
||||
'freesans', 'b', self::TITLE_SIZE, 'L',
|
||||
$usableWidth, self::TITLE_SIZE, true, 0
|
||||
);
|
||||
$currentY += self::TITLE_SIZE + self::TITLE_MARGIN;
|
||||
}
|
||||
|
||||
$title = $record->has('title') ? $record->get('title') : null;
|
||||
$fields = $record->get('fields');
|
||||
// Below rescales the size of the field box to fit, it feels like it could/should be abstracted one class above
|
||||
// to be usable on other labels but im unsure of how to implement that, since it uses a lot of private
|
||||
// constants.
|
||||
|
||||
// Figure out how tall the label fields wants to be
|
||||
$fieldCount = count($fields);
|
||||
$perFieldHeight = (self::LABEL_SIZE + self::LABEL_MARGIN)
|
||||
+ (self::FIELD_SIZE + self::FIELD_MARGIN);
|
||||
$usableHeight = $pa->h
|
||||
- self::TAG_SIZE
|
||||
- self::BARCODE_MARGIN;
|
||||
|
||||
$baseHeight = $fieldCount * $perFieldHeight;
|
||||
// If it doesn't fit in the available height, scale everything down
|
||||
$scale = 1.0;
|
||||
if ($baseHeight > $usableHeight && $baseHeight > 0) {
|
||||
$scale = $usableHeight / $baseHeight;
|
||||
$maxFields = $this->getSupportFields();
|
||||
$fields = collect($fields);
|
||||
if ($title) {
|
||||
$maxFields = max(0, $maxFields - 1); // title consumes one row’s worth of space
|
||||
}
|
||||
|
||||
$labelSize = self::LABEL_SIZE * $scale;
|
||||
$labelMargin = self::LABEL_MARGIN * $scale;
|
||||
$fieldSize = self::FIELD_SIZE * $scale;
|
||||
$fieldMargin = self::FIELD_MARGIN * $scale;
|
||||
$fields = $fields->take($maxFields)->values();
|
||||
|
||||
foreach ($fields as $field) {
|
||||
$usableHeight = $pa->h
|
||||
- self::TAG_SIZE // bottom tag text
|
||||
- self::BARCODE_MARGIN; // gap between fields and 1D
|
||||
|
||||
$field_layout = Helper::labelFieldLayoutScaling(
|
||||
pdf: $pdf,
|
||||
fields: $fields,
|
||||
currentX: $currentX,
|
||||
usableWidth: $usableWidth,
|
||||
usableHeight: $usableHeight,
|
||||
baseLabelSize: self::LABEL_SIZE,
|
||||
baseFieldSize: self::FIELD_SIZE,
|
||||
baseFieldMargin: self::FIELD_MARGIN,
|
||||
title: $title,
|
||||
baseTitleSize: self::TITLE_SIZE,
|
||||
baseTitleMargin: self::TITLE_MARGIN,
|
||||
baseLabelPadding: 1.5,
|
||||
baseGap: 1.5,
|
||||
maxScale: 1.8,
|
||||
labelFont: 'freesans',
|
||||
);
|
||||
|
||||
if ($field_layout['hasTitle']) {
|
||||
static::writeText(
|
||||
$pdf, $field['label'],
|
||||
$pdf, $title,
|
||||
$currentX, $currentY,
|
||||
'freesans', '', $labelSize, 'L',
|
||||
$usableWidth, $labelSize, true, 0
|
||||
'freesans', 'b', $field_layout['titleSize'], 'L',
|
||||
$usableWidth, $field_layout['titleSize'], true, 0
|
||||
);
|
||||
$currentY += $field_layout['titleAdvance'];
|
||||
}
|
||||
foreach ($fields as $field) {
|
||||
$rawLabel = $field['label'] ?? null;
|
||||
$value = (string)($field['value'] ?? '');
|
||||
|
||||
// No label: value takes the whole row
|
||||
if (!is_string($rawLabel) || trim($rawLabel) === '') {
|
||||
static::writeText(
|
||||
$pdf, $value,
|
||||
$currentX, $currentY,
|
||||
'freemono', 'B', $field_layout['fieldSize'], 'L',
|
||||
$usableWidth, $field_layout['rowAdvance'], true, 0, 0.01
|
||||
);
|
||||
|
||||
$currentY += $field_layout['rowAdvance'];
|
||||
continue;
|
||||
}
|
||||
|
||||
$labelText = rtrim($field['label'], ':') . ':';
|
||||
|
||||
static::writeText(
|
||||
$pdf, $labelText,
|
||||
$currentX, $currentY,
|
||||
'freesans', '', $field_layout['labelSize'], 'L',
|
||||
$field_layout['labelWidth'], $field_layout['rowAdvance'], true,
|
||||
);
|
||||
$currentY += $labelSize + $labelMargin;
|
||||
|
||||
static::writeText(
|
||||
$pdf, $field['value'],
|
||||
$currentX, $currentY,
|
||||
'freemono', 'B', $fieldSize, 'L',
|
||||
$usableWidth, $fieldSize, true, 0, 0.01
|
||||
$field_layout['valueX'], $currentY,
|
||||
'freemono', 'B', $field_layout['fieldSize'], 'L',
|
||||
$field_layout['valueWidth'], $field_layout['rowAdvance'], true, 0, 0.01
|
||||
);
|
||||
$currentY += $fieldSize + $fieldMargin;
|
||||
$currentY += $field_layout['rowAdvance'];;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -3,6 +3,8 @@
|
||||
namespace App\Models\Labels\Tapes\Dymo;
|
||||
|
||||
|
||||
use App\Helpers\Helper;
|
||||
|
||||
class LabelWriter_1933081 extends LabelWriter
|
||||
{
|
||||
private const BARCODE_MARGIN = 1.80;
|
||||
@@ -79,59 +81,82 @@ class LabelWriter_1933081 extends LabelWriter
|
||||
);
|
||||
$currentX += $barcodeSize + self::BARCODE_MARGIN;
|
||||
$usableWidth -= $barcodeSize + self::BARCODE_MARGIN;
|
||||
}
|
||||
|
||||
if ($record->has('title')) {
|
||||
static::writeText(
|
||||
$pdf, $record->get('title'),
|
||||
$currentX, $currentY,
|
||||
'freesans', 'b', self::TITLE_SIZE, 'L',
|
||||
$usableWidth, self::TITLE_SIZE, true, 0
|
||||
);
|
||||
$currentY += self::TITLE_SIZE + self::TITLE_MARGIN;
|
||||
}
|
||||
|
||||
$title = $record->has('title') ? $record->get('title') : null;
|
||||
$fields = $record->get('fields');
|
||||
// Below rescales the size of the field box to fit, it feels like it could/should be abstracted one class above
|
||||
// to be usable on other labels but im unsure of how to implement that, since it uses a lot of private
|
||||
// constants.
|
||||
$maxFields = $this->getSupportFields();
|
||||
$fields = collect($fields);
|
||||
if ($title) {
|
||||
$maxFields = max(0, $maxFields - 1); // title consumes one row’s worth of space
|
||||
}
|
||||
|
||||
$fields = $fields->take($maxFields)->values();
|
||||
|
||||
// Figure out how tall the label fields wants to be
|
||||
$fieldCount = count($fields);
|
||||
$perFieldHeight = (self::LABEL_SIZE + self::LABEL_MARGIN)
|
||||
+ (self::FIELD_SIZE + self::FIELD_MARGIN);
|
||||
$usableHeight = $pa->h
|
||||
- self::TAG_SIZE // bottom tag text
|
||||
- self::BARCODE_MARGIN; // gap between fields and 1D
|
||||
|
||||
$baseHeight = $fieldCount * $perFieldHeight;
|
||||
// If it doesn't fit in the available height, scale everything down
|
||||
$scale = 1.0;
|
||||
if ($baseHeight > $usableHeight && $baseHeight > 0) {
|
||||
$scale = $usableHeight / $baseHeight;
|
||||
}
|
||||
$field_layout = Helper::labelFieldLayoutScaling(
|
||||
pdf: $pdf,
|
||||
fields: $fields,
|
||||
currentX: $currentX,
|
||||
usableWidth: $usableWidth,
|
||||
usableHeight: $usableHeight,
|
||||
baseLabelSize: self::LABEL_SIZE,
|
||||
baseFieldSize: self::FIELD_SIZE,
|
||||
baseFieldMargin: self::FIELD_MARGIN,
|
||||
title: $title,
|
||||
baseTitleSize: self::TITLE_SIZE,
|
||||
baseTitleMargin: self::TITLE_MARGIN,
|
||||
baseLabelPadding: 1.5,
|
||||
baseGap: 1.5,
|
||||
maxScale: 1.8,
|
||||
labelFont: 'freesans',
|
||||
);
|
||||
|
||||
$labelSize = self::LABEL_SIZE * $scale;
|
||||
$labelMargin = self::LABEL_MARGIN * $scale;
|
||||
$fieldSize = self::FIELD_SIZE * $scale;
|
||||
$fieldMargin = self::FIELD_MARGIN * $scale;
|
||||
|
||||
foreach ($fields as $field) {
|
||||
if ($field_layout['hasTitle']) {
|
||||
static::writeText(
|
||||
$pdf, $field['label'],
|
||||
$pdf, $title,
|
||||
$currentX, $currentY,
|
||||
'freesans', '', $labelSize, 'L',
|
||||
$usableWidth, $labelSize, true, 0
|
||||
'freesans', 'b', $field_layout['titleSize'], 'L',
|
||||
$usableWidth, $field_layout['titleSize'], true, 0
|
||||
);
|
||||
$currentY += $field_layout['titleAdvance'];
|
||||
}
|
||||
foreach ($fields as $field) {
|
||||
$rawLabel = $field['label'] ?? null;
|
||||
$value = (string)($field['value'] ?? '');
|
||||
|
||||
// No label: value takes the whole row
|
||||
if (!is_string($rawLabel) || trim($rawLabel) === '') {
|
||||
static::writeText(
|
||||
$pdf, $value,
|
||||
$currentX, $currentY,
|
||||
'freemono', 'B', $field_layout['fieldSize'], 'L',
|
||||
$usableWidth, $field_layout['rowAdvance'], true, 0, 0.01
|
||||
);
|
||||
|
||||
$currentY += $field_layout['rowAdvance'];
|
||||
continue;
|
||||
}
|
||||
|
||||
$labelText = rtrim($field['label'], ':') . ':';
|
||||
|
||||
static::writeText(
|
||||
$pdf, $labelText,
|
||||
$currentX, $currentY,
|
||||
'freesans', '', $field_layout['labelSize'], 'L',
|
||||
$field_layout['labelWidth'], $field_layout['rowAdvance'], true,
|
||||
);
|
||||
$currentY += $labelSize + $labelMargin;
|
||||
|
||||
static::writeText(
|
||||
$pdf, $field['value'],
|
||||
$currentX, $currentY,
|
||||
'freemono', 'B', $fieldSize, 'L',
|
||||
$usableWidth, $fieldSize, true, 0, 0.01
|
||||
$field_layout['valueX'], $currentY,
|
||||
'freemono', 'B', $field_layout['fieldSize'], 'L',
|
||||
$field_layout['valueWidth'], $field_layout['rowAdvance'], true, 0, 0.01
|
||||
);
|
||||
$currentY += $fieldSize + $fieldMargin;
|
||||
$currentY += $field_layout['rowAdvance'];;
|
||||
}
|
||||
|
||||
if ($record->has('barcode1d')) {
|
||||
|
||||
@@ -3,6 +3,8 @@
|
||||
namespace App\Models\Labels\Tapes\Dymo;
|
||||
|
||||
|
||||
use App\Helpers\Helper;
|
||||
|
||||
class LabelWriter_2112283 extends LabelWriter
|
||||
{
|
||||
private const BARCODE_MARGIN = 1.80;
|
||||
@@ -81,57 +83,80 @@ class LabelWriter_2112283 extends LabelWriter
|
||||
$usableWidth -= $barcodeSize + self::BARCODE_MARGIN;
|
||||
}
|
||||
|
||||
if ($record->has('title')) {
|
||||
static::writeText(
|
||||
$pdf, $record->get('title'),
|
||||
$currentX, $currentY,
|
||||
'freesans', 'b', self::TITLE_SIZE, 'L',
|
||||
$usableWidth, self::TITLE_SIZE, true, 0
|
||||
);
|
||||
$currentY += self::TITLE_SIZE + self::TITLE_MARGIN;
|
||||
$title = $record->has('title') ? $record->get('title') : null;
|
||||
$fields = $record->get('fields');
|
||||
$maxFields = $this->getSupportFields();
|
||||
$fields = collect($fields);
|
||||
if ($title) {
|
||||
$maxFields = max(0, $maxFields - 1); // title consumes one row’s worth of space
|
||||
}
|
||||
|
||||
$fields = $record->get('fields');
|
||||
// Below rescales the size of the field box to fit, it feels like it could/should be abstracted one class above
|
||||
// to be usable on other labels but im unsure of how to implement that, since it uses a lot of private
|
||||
// constants.
|
||||
$fields = $fields->take($maxFields)->values();
|
||||
|
||||
// Figure out how tall the label fields wants to be
|
||||
$fieldCount = count($fields);
|
||||
$perFieldHeight = (self::LABEL_SIZE + self::LABEL_MARGIN)
|
||||
+ (self::FIELD_SIZE + self::FIELD_MARGIN);
|
||||
$usableHeight = $pa->h
|
||||
- self::TAG_SIZE // bottom tag text
|
||||
- self::BARCODE_MARGIN; // gap between fields and 1D
|
||||
|
||||
$baseHeight = $fieldCount * $perFieldHeight;
|
||||
// If it doesn't fit in the available height, scale everything down
|
||||
$scale = 1.0;
|
||||
if ($baseHeight > $usableHeight && $baseHeight > 0) {
|
||||
$scale = $usableHeight / $baseHeight;
|
||||
}
|
||||
$field_layout = Helper::labelFieldLayoutScaling(
|
||||
pdf: $pdf,
|
||||
fields: $fields,
|
||||
currentX: $currentX,
|
||||
usableWidth: $usableWidth,
|
||||
usableHeight: $usableHeight,
|
||||
baseLabelSize: self::LABEL_SIZE,
|
||||
baseFieldSize: self::FIELD_SIZE,
|
||||
baseFieldMargin: self::FIELD_MARGIN,
|
||||
title: $title,
|
||||
baseTitleSize: self::TITLE_SIZE,
|
||||
baseTitleMargin: self::TITLE_MARGIN,
|
||||
baseLabelPadding: 1.5,
|
||||
baseGap: 1.5,
|
||||
maxScale: 1.8,
|
||||
labelFont: 'freesans',
|
||||
);
|
||||
|
||||
$labelSize = self::LABEL_SIZE * $scale;
|
||||
$labelMargin = self::LABEL_MARGIN * $scale;
|
||||
$fieldSize = self::FIELD_SIZE * $scale;
|
||||
$fieldMargin = self::FIELD_MARGIN * $scale;
|
||||
|
||||
foreach ($fields as $field) {
|
||||
if ($field_layout['hasTitle']) {
|
||||
static::writeText(
|
||||
$pdf, $field['label'],
|
||||
$pdf, $title,
|
||||
$currentX, $currentY,
|
||||
'freesans', '', $labelSize, 'L',
|
||||
$usableWidth, $labelSize, true, 0
|
||||
'freesans', 'b', $field_layout['titleSize'], 'L',
|
||||
$usableWidth, $field_layout['titleSize'], true, 0
|
||||
);
|
||||
$currentY += $field_layout['titleAdvance'];
|
||||
}
|
||||
foreach ($fields as $field) {
|
||||
$rawLabel = $field['label'] ?? null;
|
||||
$value = (string)($field['value'] ?? '');
|
||||
|
||||
// No label: value takes the whole row
|
||||
if (!is_string($rawLabel) || trim($rawLabel) === '') {
|
||||
static::writeText(
|
||||
$pdf, $value,
|
||||
$currentX, $currentY,
|
||||
'freemono', 'B', $field_layout['fieldSize'], 'L',
|
||||
$usableWidth, $field_layout['rowAdvance'], true, 0, 0.01
|
||||
);
|
||||
|
||||
$currentY += $field_layout['rowAdvance'];
|
||||
continue;
|
||||
}
|
||||
|
||||
$labelText = rtrim($field['label'], ':') . ':';
|
||||
|
||||
static::writeText(
|
||||
$pdf, $labelText,
|
||||
$currentX, $currentY,
|
||||
'freesans', '', $field_layout['labelSize'], 'L',
|
||||
$field_layout['labelWidth'], $field_layout['rowAdvance'], true,
|
||||
);
|
||||
$currentY += $labelSize + $labelMargin;
|
||||
|
||||
static::writeText(
|
||||
$pdf, $field['value'],
|
||||
$currentX, $currentY,
|
||||
'freemono', 'B', $fieldSize, 'L',
|
||||
$usableWidth, $fieldSize, true, 0, 0.01
|
||||
$field_layout['valueX'], $currentY,
|
||||
'freemono', 'B', $field_layout['fieldSize'], 'L',
|
||||
$field_layout['valueWidth'], $field_layout['rowAdvance'], true, 0, 0.01
|
||||
);
|
||||
$currentY += $fieldSize + $fieldMargin;
|
||||
$currentY += $field_layout['rowAdvance'];;
|
||||
}
|
||||
if ($record->has('barcode1d')) {
|
||||
static::write1DBarcode(
|
||||
|
||||
@@ -47,7 +47,7 @@ class License extends Depreciable
|
||||
];
|
||||
|
||||
protected $rules = [
|
||||
'name' => 'required|string|min:3|max:255',
|
||||
'name' => 'required|string|max:255',
|
||||
'seats' => 'required|min:1|integer|limit_change:10000', // limit_change is a "pseudo-rule" that translates into 'between', see prepareLimitChangeRule() below
|
||||
'license_email' => 'email|nullable|max:120',
|
||||
'license_name' => 'string|nullable|max:100',
|
||||
@@ -223,6 +223,7 @@ class License extends Depreciable
|
||||
$logAction->created_by = auth()->id() ?: 1; // We don't have an id while running the importer from CLI.
|
||||
$logAction->note = "deleted {$change} seats";
|
||||
$logAction->target_id = null;
|
||||
$logAction->quantity = $change;
|
||||
$logAction->logaction('delete seats');
|
||||
|
||||
return true;
|
||||
@@ -259,6 +260,7 @@ class License extends Depreciable
|
||||
$logAction->created_by = auth()->id() ?: 1; // Importer.
|
||||
$logAction->note = "added {$change} seats";
|
||||
$logAction->target_id = null;
|
||||
$logAction->quantity = $change;
|
||||
$logAction->logaction('add seats');
|
||||
}
|
||||
|
||||
|
||||
@@ -26,7 +26,7 @@ class Location extends SnipeModel
|
||||
|
||||
protected $table = 'locations';
|
||||
protected $rules = [
|
||||
'name' => 'required|min:2|max:255|unique_undeleted',
|
||||
'name' => 'required|max:255|unique_undeleted',
|
||||
'address' => 'max:191|nullable',
|
||||
'address2' => 'max:191|nullable',
|
||||
'city' => 'max:191|nullable',
|
||||
|
||||
@@ -21,7 +21,7 @@ class Manufacturer extends SnipeModel
|
||||
|
||||
// Declare the rules for the form validation
|
||||
protected $rules = [
|
||||
'name' => 'required|min:2|max:255|unique:manufacturers,name,NULL,id,deleted_at,NULL',
|
||||
'name' => 'required|max:255|unique:manufacturers,name,NULL,id,deleted_at,NULL',
|
||||
'url' => 'nullable|starts_with:http://,https://,afp://,facetime://,file://,irc://',
|
||||
'support_email' => 'email|nullable',
|
||||
'support_url' => 'nullable|starts_with:http://,https://,afp://,facetime://,file://,irc://',
|
||||
|
||||
@@ -25,7 +25,7 @@ class PredefinedKit extends SnipeModel
|
||||
* Category validation rules
|
||||
*/
|
||||
public $rules = [
|
||||
'name' => 'required|min:1|max:255|unique',
|
||||
'name' => 'required|max:255|unique',
|
||||
];
|
||||
|
||||
use ValidatingTrait;
|
||||
|
||||
@@ -21,7 +21,7 @@ class Statuslabel extends SnipeModel
|
||||
protected $hidden = ['user_id', 'deleted_at'];
|
||||
|
||||
protected $rules = [
|
||||
'name' => 'required|string|unique_undeleted',
|
||||
'name' => 'required|max:255|string|unique_undeleted',
|
||||
'notes' => 'string|nullable',
|
||||
'deployable' => 'required',
|
||||
'pending' => 'required',
|
||||
|
||||
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user