mirror of
https://github.com/snipe/snipe-it.git
synced 2024-11-09 23:24:06 -08:00
Merge branch 'develop' into v5-master-develop-integration
# Conflicts: # .env.example # .travis.yml # Dockerfile # README.md # app/Console/Commands/LdapSync.php # app/Console/Kernel.php # app/Http/Controllers/AccessoriesController.php # app/Http/Controllers/Api/AccessoriesController.php # app/Http/Controllers/Api/AssetsController.php # app/Http/Controllers/Api/LocationsController.php # app/Http/Controllers/Api/SettingsController.php # app/Http/Controllers/Api/UsersController.php # app/Http/Controllers/AssetModelsController.php # app/Http/Controllers/Assets/AssetFilesController.php # app/Http/Controllers/Assets/AssetsController.php # app/Http/Controllers/CategoriesController.php # app/Http/Controllers/CompaniesController.php # app/Http/Controllers/ComponentsController.php # app/Http/Controllers/ConsumablesController.php # app/Http/Controllers/DepartmentsController.php # app/Http/Controllers/LicensesController.php # app/Http/Controllers/LocationsController.php # app/Http/Controllers/ManufacturersController.php # app/Http/Controllers/ReportsController.php # app/Http/Controllers/SettingsController.php # app/Http/Controllers/SuppliersController.php # app/Http/Controllers/UsersController.php # app/Http/Middleware/EncryptCookies.php # app/Http/Requests/AssetRequest.php # app/Http/Transformers/AssetMaintenancesTransformer.php # app/Importer/AssetImporter.php # app/Models/AssetMaintenance.php # app/Models/Location.php # app/Models/User.php # composer.json # composer.lock # config/backup.php # config/database.php # config/version.php # public/mix-manifest.json # resources/lang/en-ID/general.php # resources/lang/vi/admin/settings/general.php # resources/views/accessories/edit.blade.php # resources/views/hardware/view.blade.php # resources/views/layouts/default.blade.php # tests/api/ApiCategoriesCest.php
This commit is contained in:
commit
5290c47e2a
|
@ -1651,6 +1651,186 @@
|
|||
"code"
|
||||
]
|
||||
},
|
||||
{
|
||||
"login": "jwhulette",
|
||||
"name": "Wes Hulette",
|
||||
"avatar_url": "https://avatars1.githubusercontent.com/u/4930051?v=4",
|
||||
"profile": "http://macfoo.wordpress.com/",
|
||||
"contributions": [
|
||||
"code"
|
||||
]
|
||||
},
|
||||
{
|
||||
"login": "patrict",
|
||||
"name": "patrict",
|
||||
"avatar_url": "https://avatars0.githubusercontent.com/u/8134591?v=4",
|
||||
"profile": "https://github.com/patrict",
|
||||
"contributions": [
|
||||
"code"
|
||||
]
|
||||
},
|
||||
{
|
||||
"login": "VELIKII-DIVAN",
|
||||
"name": "Dmitriy Minaev",
|
||||
"avatar_url": "https://avatars3.githubusercontent.com/u/2611616?v=4",
|
||||
"profile": "https://github.com/VELIKII-DIVAN",
|
||||
"contributions": [
|
||||
"code"
|
||||
]
|
||||
},
|
||||
{
|
||||
"login": "liquidhorse",
|
||||
"name": "liquidhorse",
|
||||
"avatar_url": "https://avatars0.githubusercontent.com/u/5132245?v=4",
|
||||
"profile": "https://github.com/liquidhorse",
|
||||
"contributions": [
|
||||
"code"
|
||||
]
|
||||
},
|
||||
{
|
||||
"login": "Seldaek",
|
||||
"name": "Jordi Boggiano",
|
||||
"avatar_url": "https://avatars1.githubusercontent.com/u/183678?v=4",
|
||||
"profile": "https://seld.be/",
|
||||
"contributions": [
|
||||
"code"
|
||||
]
|
||||
},
|
||||
{
|
||||
"login": "inietov",
|
||||
"name": "Ivan Nieto",
|
||||
"avatar_url": "https://avatars0.githubusercontent.com/u/653557?v=4",
|
||||
"profile": "https://github.com/inietov",
|
||||
"contributions": [
|
||||
"code"
|
||||
]
|
||||
},
|
||||
{
|
||||
"login": "benrubson",
|
||||
"name": "Ben RUBSON",
|
||||
"avatar_url": "https://avatars2.githubusercontent.com/u/6764151?v=4",
|
||||
"profile": "https://github.com/benrubson",
|
||||
"contributions": [
|
||||
"code"
|
||||
]
|
||||
},
|
||||
{
|
||||
"login": "NMathar",
|
||||
"name": "NMathar",
|
||||
"avatar_url": "https://avatars2.githubusercontent.com/u/8554558?v=4",
|
||||
"profile": "https://github.com/NMathar",
|
||||
"contributions": [
|
||||
"code"
|
||||
]
|
||||
},
|
||||
{
|
||||
"login": "smb",
|
||||
"name": "Steffen",
|
||||
"avatar_url": "https://avatars1.githubusercontent.com/u/139566?v=4",
|
||||
"profile": "https://github.com/smb",
|
||||
"contributions": [
|
||||
"code"
|
||||
]
|
||||
},
|
||||
{
|
||||
"login": "Sxderp",
|
||||
"name": "Sxderp",
|
||||
"avatar_url": "https://avatars0.githubusercontent.com/u/6609453?v=4",
|
||||
"profile": "https://github.com/Sxderp",
|
||||
"contributions": [
|
||||
"code"
|
||||
]
|
||||
},
|
||||
{
|
||||
"login": "fanta8897",
|
||||
"name": "fanta8897",
|
||||
"avatar_url": "https://avatars1.githubusercontent.com/u/4807843?v=4",
|
||||
"profile": "https://github.com/fanta8897",
|
||||
"contributions": [
|
||||
"code"
|
||||
]
|
||||
},
|
||||
{
|
||||
"login": "andreybolonin",
|
||||
"name": "Andrey Bolonin",
|
||||
"avatar_url": "https://avatars2.githubusercontent.com/u/2576509?v=4",
|
||||
"profile": "https://andreybolonin.com/phpconsulting/",
|
||||
"contributions": [
|
||||
"code"
|
||||
]
|
||||
},
|
||||
{
|
||||
"login": "shinayoshi",
|
||||
"name": "shinayoshi",
|
||||
"avatar_url": "https://avatars3.githubusercontent.com/u/2173307?v=4",
|
||||
"profile": "http://www.shinayoshi.net/",
|
||||
"contributions": [
|
||||
"code"
|
||||
]
|
||||
},
|
||||
{
|
||||
"login": "reuser",
|
||||
"name": "Hubert",
|
||||
"avatar_url": "https://avatars3.githubusercontent.com/u/2130159?v=4",
|
||||
"profile": "https://github.com/reuser",
|
||||
"contributions": [
|
||||
"code"
|
||||
]
|
||||
},
|
||||
{
|
||||
"login": "KeenRivals",
|
||||
"name": "KeenRivals",
|
||||
"avatar_url": "https://avatars0.githubusercontent.com/u/6865789?v=4",
|
||||
"profile": "https://brashear.me",
|
||||
"contributions": [
|
||||
"code"
|
||||
]
|
||||
},
|
||||
{
|
||||
"login": "omyno",
|
||||
"name": "omyno",
|
||||
"avatar_url": "https://avatars3.githubusercontent.com/u/2902513?v=4",
|
||||
"profile": "https://github.com/omyno",
|
||||
"contributions": [
|
||||
"code"
|
||||
]
|
||||
},
|
||||
{
|
||||
"login": "jackka",
|
||||
"name": "Evgeny",
|
||||
"avatar_url": "https://avatars1.githubusercontent.com/u/6271335?v=4",
|
||||
"profile": "https://github.com/jackka",
|
||||
"contributions": [
|
||||
"code"
|
||||
]
|
||||
},
|
||||
{
|
||||
"login": "colin-campbell",
|
||||
"name": "Colin Campbell",
|
||||
"avatar_url": "https://avatars2.githubusercontent.com/u/1169963?v=4",
|
||||
"profile": "https://digitalist.se",
|
||||
"contributions": [
|
||||
"code"
|
||||
]
|
||||
},
|
||||
{
|
||||
"login": "lubo",
|
||||
"name": "Ľubomír Kučera",
|
||||
"avatar_url": "https://avatars3.githubusercontent.com/u/2872098?v=4",
|
||||
"profile": "https://github.com/lubo",
|
||||
"contributions": [
|
||||
"code"
|
||||
]
|
||||
},
|
||||
{
|
||||
"login": "Mezzle",
|
||||
"name": "Martin Meredith",
|
||||
"avatar_url": "https://avatars3.githubusercontent.com/u/570639?v=4",
|
||||
"profile": "https://www.sourceguru.net",
|
||||
"contributions": [
|
||||
"code"
|
||||
]
|
||||
},
|
||||
{
|
||||
"login": "timothyfarmer",
|
||||
"name": "Tim Farmer",
|
||||
|
|
|
@ -1,5 +1,13 @@
|
|||
.git
|
||||
.github
|
||||
.gitattributes
|
||||
.gitignore
|
||||
.dockerignore
|
||||
app/storage/logs/*
|
||||
app/storage/views/*
|
||||
vendor/*
|
||||
storage/framework/cache/*
|
||||
node_modules
|
||||
.vagrant
|
||||
.idea
|
||||
|
||||
|
|
|
@ -40,10 +40,12 @@ IMAGE_LIB=gd
|
|||
# --------------------------------------------
|
||||
# OPTIONAL: AWS S3 SETTINGS
|
||||
# --------------------------------------------
|
||||
AWS_SECRET=null
|
||||
AWS_KEY=null
|
||||
AWS_REGION=null
|
||||
AWS_SECRET_ACCESS_KEY=null
|
||||
AWS_ACCESS_KEY_ID=null
|
||||
AWS_DEFAULT_REGION=null
|
||||
AWS_BUCKET=null
|
||||
AWS_BUCKET_ROOT=null
|
||||
AWS_URL=null
|
||||
|
||||
|
||||
# --------------------------------------------
|
||||
|
|
|
@ -40,10 +40,12 @@ IMAGE_LIB=gd
|
|||
# --------------------------------------------
|
||||
# OPTIONAL: AWS S3 SETTINGS
|
||||
# --------------------------------------------
|
||||
AWS_SECRET=null
|
||||
AWS_KEY=null
|
||||
AWS_REGION=null
|
||||
AWS_SECRET_ACCESS_KEY=null
|
||||
AWS_ACCESS_KEY_ID=null
|
||||
AWS_DEFAULT_REGION=null
|
||||
AWS_BUCKET=null
|
||||
AWS_BUCKET_ROOT=null
|
||||
AWS_URL=null
|
||||
|
||||
|
||||
# --------------------------------------------
|
||||
|
|
4
.github/autolabeler.yml
vendored
Normal file
4
.github/autolabeler.yml
vendored
Normal file
|
@ -0,0 +1,4 @@
|
|||
frontend: ["*.js", "*.css", "*.vue", "*.scss", "*.less", "*.blade.*"]
|
||||
backend: ["/app", "*.php"]
|
||||
legal: ["LICENSE*", "NOTICES*"]
|
||||
config: .github
|
33
.github/config.yml
vendored
Normal file
33
.github/config.yml
vendored
Normal file
|
@ -0,0 +1,33 @@
|
|||
# Configuration for new-issue-welcome - https://github.com/behaviorbot/new-issue-welcome
|
||||
|
||||
# Comment to be posted to on first time issues
|
||||
newIssueWelcomeComment: |
|
||||
👋 Thanks for opening your first issue here! If you're reporting a 🐞 bug, please make sure you include steps to reproduce it. We get a lot of issues on this repo, so please be patient and we will get back to you as soon as we can.
|
||||
|
||||
# Configuration for new-pr-welcome - https://github.com/behaviorbot/new-pr-welcome
|
||||
|
||||
# Comment to be posted to on PRs from first time contributors in your repository
|
||||
newPRWelcomeComment: |
|
||||
💖 Thanks for this pull request! 💖
|
||||
|
||||
We use [semantic commit messages](https://snipe-it.readme.io/docs/contributing-overview#section-pull-request-guidelines) to streamline the release process and easily generate changelogs between versions. Before your pull request can be merged, you should **update your pull request title** to start with a semantic prefix if it doesn't have one already.
|
||||
|
||||
Examples of commit messages with semantic prefixes:
|
||||
|
||||
- `Fixed #<issue number>: don't overwrite prevent_default if default wasn't prevented`
|
||||
- `Added #<issue number>: add checkout functionality to assets`
|
||||
- `Improved Asset Checkout: use new notification method for checkout`
|
||||
|
||||
Things that will help get your PR across the finish line:
|
||||
|
||||
- Document any user-facing changes you've made.
|
||||
- Include tests when adding/changing behavior.
|
||||
- Include screenshots and animated GIFs whenever possible.
|
||||
|
||||
We get a lot of pull requests on this repo, so please be patient and we will get back to you as soon as we can.
|
||||
|
||||
# Configuration for first-pr-merge - https://github.com/behaviorbot/first-pr-merge
|
||||
|
||||
# Comment to be posted to on pull requests merged by a first time user
|
||||
firstPRMergeComment: >
|
||||
Congrats on merging your first pull request! 🎉🎉🎉
|
7
.github/weekly-digest.yml
vendored
Normal file
7
.github/weekly-digest.yml
vendored
Normal file
|
@ -0,0 +1,7 @@
|
|||
# Configuration for weekly-digest - https://github.com/apps/weekly-digest
|
||||
publishDay: sun
|
||||
canPublishIssues: true
|
||||
canPublishPullRequests: true
|
||||
canPublishContributors: true
|
||||
canPublishStargazers: true
|
||||
canPublishCommits: true
|
9
.gitignore
vendored
9
.gitignore
vendored
|
@ -50,4 +50,13 @@ tests/_support/_generated/*
|
|||
/storage/oauth-public.key
|
||||
|
||||
*.cache
|
||||
|
||||
.vagrant
|
||||
|
||||
\.php_cs\.dist
|
||||
|
||||
phpmd\.xml
|
||||
/public/storage
|
||||
_ide_helper.php
|
||||
.phpstorm.meta.php
|
||||
_ide_helper_models.php
|
||||
|
|
|
@ -14,13 +14,11 @@ services:
|
|||
|
||||
# list any PHP version you want to test against
|
||||
php:
|
||||
- 7.1.2
|
||||
- 7.1.3
|
||||
- 7.1.4
|
||||
- 7.2
|
||||
- 7.3
|
||||
- 7.3.0
|
||||
|
||||
matrix:
|
||||
allow_failures:
|
||||
- php: 7.3
|
||||
|
||||
# execute any number of scripts before the test run, custom env's are available as variables
|
||||
before_script:
|
||||
|
@ -31,6 +29,7 @@ before_script:
|
|||
- mysql -e 'CREATE USER "travis'@'localhost";'
|
||||
- mysql -e 'GRANT ALL PRIVILEGES ON * . * TO "travis'@'localhost";'
|
||||
- mysql -e 'FLUSH PRIVILEGES;'
|
||||
- cp .env.testing-ci .env
|
||||
- composer self-update
|
||||
- composer install -n --prefer-source
|
||||
- chmod -R 777 storage
|
||||
|
|
69
Dockerfile
69
Dockerfile
|
@ -1,36 +1,59 @@
|
|||
FROM ubuntu:xenial
|
||||
LABEL maintainer="uberbrady, hinchk"
|
||||
FROM ubuntu:bionic
|
||||
LABEL maintainer Brady Wetherington <uberbrady@gmail.com>
|
||||
|
||||
RUN apt-get update && apt-get install -y software-properties-common
|
||||
RUN LC_ALL=C.UTF-8 add-apt-repository -y ppa:ondrej/php
|
||||
RUN apt-get update && apt-get install -y \
|
||||
RUN export DEBIAN_FRONTEND=noninteractive; \
|
||||
export DEBCONF_NONINTERACTIVE_SEEN=true; \
|
||||
echo 'tzdata tzdata/Areas select Etc' | debconf-set-selections; \
|
||||
echo 'tzdata tzdata/Zones/Etc select UTC' | debconf-set-selections; \
|
||||
apt-get update -qqy \
|
||||
&& apt-get install -qqy --no-install-recommends \
|
||||
apt-utils \
|
||||
apache2 \
|
||||
apache2-bin \
|
||||
libapache2-mod-php7.1 \
|
||||
php7.1-curl \
|
||||
php7.1-ldap \
|
||||
php7.1-mysql \
|
||||
php7.1-mcrypt \
|
||||
php7.1-gd \
|
||||
php7.1-xml \
|
||||
php7.1-mbstring \
|
||||
php7.1-zip \
|
||||
php7.1-bcmath \
|
||||
libapache2-mod-php7.2 \
|
||||
php7.2-curl \
|
||||
php7.2-ldap \
|
||||
php7.2-mysql \
|
||||
php7.2-gd \
|
||||
php7.2-xml \
|
||||
php7.2-mbstring \
|
||||
php7.2-zip \
|
||||
php7.2-bcmath \
|
||||
patch \
|
||||
curl \
|
||||
wget \
|
||||
vim \
|
||||
git \
|
||||
cron \
|
||||
mysql-client \
|
||||
supervisor \
|
||||
cron \
|
||||
gcc \
|
||||
make \
|
||||
autoconf \
|
||||
libc-dev \
|
||||
pkg-config \
|
||||
libmcrypt-dev \
|
||||
php7.2-dev \
|
||||
ca-certificates \
|
||||
unzip \
|
||||
&& apt-get clean \
|
||||
&& rm -rf /var/lib/apt/lists/* /tmp/* /var/tmp/*
|
||||
|
||||
|
||||
RUN curl -L -O https://github.com/pear/pearweb_phars/raw/master/go-pear.phar
|
||||
RUN php go-pear.phar
|
||||
|
||||
RUN pecl install mcrypt-1.0.2
|
||||
|
||||
RUN bash -c "echo extension=/usr/lib/php/20170718/mcrypt.so > /etc/php/7.2/mods-available/mcrypt.ini"
|
||||
|
||||
RUN phpenmod mcrypt
|
||||
RUN phpenmod gd
|
||||
RUN phpenmod bcmath
|
||||
|
||||
RUN sed -i 's/variables_order = .*/variables_order = "EGPCS"/' /etc/php/7.1/apache2/php.ini
|
||||
RUN sed -i 's/variables_order = .*/variables_order = "EGPCS"/' /etc/php/7.1/cli/php.ini
|
||||
RUN sed -i 's/variables_order = .*/variables_order = "EGPCS"/' /etc/php/7.2/apache2/php.ini
|
||||
RUN sed -i 's/variables_order = .*/variables_order = "EGPCS"/' /etc/php/7.2/cli/php.ini
|
||||
|
||||
RUN useradd -m --uid 1000 --gid 50 docker
|
||||
|
||||
|
@ -41,11 +64,11 @@ COPY docker/000-default.conf /etc/apache2/sites-enabled/000-default.conf
|
|||
|
||||
#SSL
|
||||
RUN mkdir -p /var/lib/snipeit/ssl
|
||||
COPY docker/001-default-ssl.conf /etc/apache2/sites-enabled/001-default-ssl.conf
|
||||
#COPY docker/001-default-ssl.conf /etc/apache2/sites-available/001-default-ssl.conf
|
||||
#COPY docker/001-default-ssl.conf /etc/apache2/sites-enabled/001-default-ssl.conf
|
||||
COPY docker/001-default-ssl.conf /etc/apache2/sites-available/001-default-ssl.conf
|
||||
|
||||
RUN a2enmod ssl
|
||||
#RUN a2ensite 001-default-ssl.conf
|
||||
RUN a2ensite 001-default-ssl.conf
|
||||
|
||||
COPY . /var/www/html
|
||||
|
||||
|
@ -68,7 +91,7 @@ RUN \
|
|||
rm -r "/var/www/html/storage/private_uploads" && ln -fs "/var/lib/snipeit/data/private_uploads" "/var/www/html/storage/private_uploads" \
|
||||
&& rm -rf "/var/www/html/public/uploads" && ln -fs "/var/lib/snipeit/data/uploads" "/var/www/html/public/uploads" \
|
||||
&& rm -r "/var/www/html/storage/app/backups" && ln -fs "/var/lib/snipeit/dumps" "/var/www/html/storage/app/backups" \
|
||||
&& mkdir "/var/lib/snipeit/keys" && ln -fs "/var/lib/snipeit/keys/oauth-private.key" "/var/www/html/storage/oauth-private.key" \
|
||||
&& mkdir -p "/var/lib/snipeit/keys" && ln -fs "/var/lib/snipeit/keys/oauth-private.key" "/var/www/html/storage/oauth-private.key" \
|
||||
&& ln -fs "/var/lib/snipeit/keys/oauth-public.key" "/var/www/html/storage/oauth-public.key" \
|
||||
&& chown docker "/var/lib/snipeit/keys/" \
|
||||
&& chmod +x /var/www/html/artisan \
|
||||
|
@ -77,11 +100,11 @@ RUN \
|
|||
############## DEPENDENCIES via COMPOSER ###################
|
||||
|
||||
#global install of composer
|
||||
RUN cd /tmp;curl -sS https://getcomposer.org/installer | php;mv /tmp/composer.phar /usr/local/bin/composer
|
||||
COPY --from=composer:latest /usr/bin/composer /usr/bin/composer
|
||||
|
||||
# Get dependencies
|
||||
USER docker
|
||||
RUN cd /var/www/html;composer install && rm -rf /home/docker/.composer/cache
|
||||
RUN composer install --no-dev --working-dir=/var/www/html
|
||||
USER root
|
||||
|
||||
############### APPLICATION INSTALL/INIT #################
|
||||
|
|
80
Dockerfile.alpine
Normal file
80
Dockerfile.alpine
Normal file
|
@ -0,0 +1,80 @@
|
|||
FROM alpine:3.8
|
||||
# Apache + PHP
|
||||
RUN apk add --update --no-cache \
|
||||
apache2 \
|
||||
php7 \
|
||||
php7-common \
|
||||
php7-apache2 \
|
||||
php7-curl \
|
||||
php7-ldap \
|
||||
php7-mysqli \
|
||||
php7-gd \
|
||||
php7-xml \
|
||||
php7-mbstring \
|
||||
php7-zip \
|
||||
php7-ctype \
|
||||
php7-tokenizer \
|
||||
php7-pdo_mysql \
|
||||
php7-openssl \
|
||||
php7-bcmath \
|
||||
php7-phar \
|
||||
php7-json \
|
||||
php7-iconv \
|
||||
php7-fileinfo \
|
||||
php7-simplexml \
|
||||
php7-session \
|
||||
curl \
|
||||
wget \
|
||||
vim \
|
||||
git \
|
||||
mysql-client \
|
||||
tini
|
||||
|
||||
# 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/php7/php.ini
|
||||
COPY docker/000-default-2.4.conf /etc/apache2/conf.d/default.conf
|
||||
|
||||
# Enable mod_rewrite
|
||||
RUN sed -i '/LoadModule rewrite_module/s/^#//g' /etc/apache2/httpd.conf
|
||||
|
||||
COPY . /var/www/html
|
||||
|
||||
WORKDIR /var/www/html
|
||||
|
||||
COPY docker/docker.env /var/www/html/.env
|
||||
|
||||
RUN chown -R apache:apache /var/www/html
|
||||
|
||||
RUN \
|
||||
rm -r "/var/www/html/storage/private_uploads" \
|
||||
&& mkdir -p "/var/lib/snipeit/data/private_uploads" && ln -fs "/var/lib/snipeit/data/private_uploads" "/var/www/html/storage/private_uploads" \
|
||||
&& rm -rf "/var/www/html/public/uploads" \
|
||||
&& mkdir -p "/var/lib/snipeit/data/uploads" && ln -fs "/var/lib/snipeit/data/uploads" "/var/www/html/public/uploads" \
|
||||
&& mkdir -p "/var/lib/snipeit/dumps" && rm -r "/var/www/html/storage/app/backups" && ln -fs "/var/lib/snipeit/dumps" "/var/www/html/storage/app/backups" \
|
||||
&& mkdir -p "/var/lib/snipeit/keys" && ln -fs "/var/lib/snipeit/keys/oauth-private.key" "/var/www/html/storage/oauth-private.key" \
|
||||
&& ln -fs "/var/lib/snipeit/keys/oauth-public.key" "/var/www/html/storage/oauth-public.key" \
|
||||
&& chown -R apache "/var/lib/snipeit"
|
||||
|
||||
# Install composer
|
||||
COPY --from=composer:latest /usr/bin/composer /usr/bin/composer
|
||||
RUN mkdir -p /var/www/.composer && chown apache /var/www/.composer
|
||||
|
||||
# Install dependencies
|
||||
USER apache
|
||||
RUN COMPOSER_CACHE_DIR=/dev/null composer install --no-dev --working-dir=/var/www/html
|
||||
|
||||
USER root
|
||||
|
||||
VOLUME ["/var/lib/snipeit"]
|
||||
|
||||
# Entrypoints
|
||||
COPY docker/entrypoint_alpine.sh /entrypoint.sh
|
||||
RUN chmod +x /entrypoint.sh
|
||||
|
||||
ENTRYPOINT ["/sbin/tini", "--"]
|
||||
|
||||
CMD ["/entrypoint.sh"]
|
||||
|
||||
EXPOSE 80
|
20
README.md
20
README.md
|
@ -68,6 +68,15 @@ As these were created by third-parties, Snipe-IT cannot provide support for thes
|
|||
|
||||
-----
|
||||
|
||||
### Contributing
|
||||
|
||||
Please see the documentation on [contributing and developing for Snipe-IT](https://snipe-it.readme.io/docs/contributing-overview).
|
||||
|
||||
|
||||
Please note that this project is released with a [Contributor Code of Conduct](CODE_OF_CONDUCT.md). By participating in this project you agree to abide by its terms.
|
||||
|
||||
-----
|
||||
|
||||
### Security
|
||||
|
||||
To report a security vulnerability, please email security@snipeitapp.com instead of using the issue tracker.
|
||||
|
@ -106,15 +115,10 @@ Thanks goes to all of these wonderful people ([emoji key](https://github.com/ken
|
|||
| [<img src="https://avatars0.githubusercontent.com/u/1680266?v=4" width="110px;"/><br /><sub>saymd</sub>](https://github.com/saymd)<br />[🌍](#translation-saymd "Translation") | [<img src="https://avatars0.githubusercontent.com/u/1826808?v=4" width="110px;"/><br /><sub>Patrik Larsson</sub>](https://nordsken.se)<br />[🌍](#translation-pooot "Translation") | [<img src="https://avatars1.githubusercontent.com/u/20584746?v=4" width="110px;"/><br /><sub>drcryo</sub>](https://github.com/drcryo)<br />[🌍](#translation-drcryo "Translation") | [<img src="https://avatars1.githubusercontent.com/u/19408004?v=4" width="110px;"/><br /><sub>pawel1615</sub>](https://github.com/pawel1615)<br />[🌍](#translation-pawel1615 "Translation") | [<img src="https://avatars2.githubusercontent.com/u/23340468?v=4" width="110px;"/><br /><sub>bodrovics</sub>](https://github.com/bodrovics)<br />[🌍](#translation-bodrovics "Translation") | [<img src="https://avatars0.githubusercontent.com/u/3257654?v=4" width="110px;"/><br /><sub>priatna</sub>](https://github.com/priatna)<br />[🌍](#translation-priatna "Translation") | [<img src="https://avatars1.githubusercontent.com/u/5358374?v=4" width="110px;"/><br /><sub>Fan Jiang</sub>](https://amayume.net)<br />[🌍](#translation-ProfFan "Translation") |
|
||||
| [<img src="https://avatars1.githubusercontent.com/u/22555451?v=4" width="110px;"/><br /><sub>ragnarcx</sub>](https://github.com/ragnarcx)<br />[🌍](#translation-ragnarcx "Translation") | [<img src="https://avatars2.githubusercontent.com/u/18654582?v=4" width="110px;"/><br /><sub>Rein van Haaren</sub>](http://www.reinvanhaaren.nl/)<br />[🌍](#translation-reinvanhaaren "Translation") | [<img src="https://avatars1.githubusercontent.com/u/386672?v=4" width="110px;"/><br /><sub>Teguh Dwicaksana</sub>](http://dheche.songolimo.net)<br />[🌍](#translation-dheche "Translation") | [<img src="https://avatars2.githubusercontent.com/u/2572552?v=4" width="110px;"/><br /><sub>fraccie</sub>](https://github.com/FRaccie)<br />[🌍](#translation-FRaccie "Translation") | [<img src="https://avatars0.githubusercontent.com/u/35182720?v=4" width="110px;"/><br /><sub>vinzruzell</sub>](https://github.com/vinzruzell)<br />[🌍](#translation-vinzruzell "Translation") | [<img src="https://avatars1.githubusercontent.com/u/7883603?v=4" width="110px;"/><br /><sub>Kevin Austin</sub>](http://kevinaustin.com)<br />[🌍](#translation-vipsystem "Translation") | [<img src="https://avatars3.githubusercontent.com/u/3861828?v=4" width="110px;"/><br /><sub>Wira Sandy</sub>](http://azuraweb.xyz)<br />[🌍](#translation-wira-sandy "Translation") |
|
||||
| [<img src="https://avatars2.githubusercontent.com/u/8663789?v=4" width="110px;"/><br /><sub>Илья</sub>](https://github.com/GrayHoax)<br />[🌍](#translation-GrayHoax "Translation") | [<img src="https://avatars3.githubusercontent.com/u/30119111?v=4" width="110px;"/><br /><sub>GodUseVPN</sub>](https://github.com/godusevpn)<br />[🌍](#translation-godusevpn "Translation") | [<img src="https://avatars1.githubusercontent.com/u/745576?v=4" width="110px;"/><br /><sub>周周</sub>](https://github.com/EngrZhou)<br />[🌍](#translation-EngrZhou "Translation") | [<img src="https://avatars3.githubusercontent.com/u/1631095?v=4" width="110px;"/><br /><sub>Sam</sub>](https://github.com/takuy)<br />[💻](https://github.com/snipe/snipe-it/commits?author=takuy "Code") | [<img src="https://avatars1.githubusercontent.com/u/264022?v=4" width="110px;"/><br /><sub>Azerothian</sub>](https://www.illisian.com.au)<br />[💻](https://github.com/snipe/snipe-it/commits?author=Azerothian "Code") | [<img src="https://avatars1.githubusercontent.com/u/7632599?v=4" width="110px;"/><br /><sub>Tim Farmer</sub>](https://github.com/timothyfarmer)<br />[💻](https://github.com/snipe/snipe-it/commits?author=timothyfarmer "Code") | [<img src="https://avatars0.githubusercontent.com/u/17459600?v=4" width="110px;"/><br /><sub>Marián Skrip</sub>](https://github.com/mskrip)<br />[💻](https://github.com/snipe/snipe-it/commits?author=mskrip "Code") |
|
||||
| [<img src="https://avatars3.githubusercontent.com/u/2611616?v=4" width="110px;"/><br /><sub>Dmitriy Minaev</sub>](https://github.com/VELIKII-DIVAN)<br />[💻](https://github.com/snipe/snipe-it/commits?author=VELIKII-DIVAN "Code") | [<img src="https://avatars0.githubusercontent.com/u/5132245?v=4" width="110px;"/><br /><sub>liquidhorse</sub>](https://github.com/liquidhorse)<br />[💻](https://github.com/snipe/snipe-it/commits?author=liquidhorse "Code") | [<img src="https://avatars1.githubusercontent.com/u/183678?v=4" width="110px;"/><br /><sub>Jordi Boggiano</sub>](https://seld.be/)<br />[💻](https://github.com/snipe/snipe-it/commits?author=Seldaek "Code") | [<img src="https://avatars0.githubusercontent.com/u/653557?v=4" width="110px;"/><br /><sub>Ivan Nieto</sub>](https://github.com/inietov)<br />[💻](https://github.com/snipe/snipe-it/commits?author=inietov "Code") | [<img src="https://avatars2.githubusercontent.com/u/6764151?v=4" width="110px;"/><br /><sub>Ben RUBSON</sub>](https://github.com/benrubson)<br />[💻](https://github.com/snipe/snipe-it/commits?author=benrubson "Code") | [<img src="https://avatars2.githubusercontent.com/u/8554558?v=4" width="110px;"/><br /><sub>NMathar</sub>](https://github.com/NMathar)<br />[💻](https://github.com/snipe/snipe-it/commits?author=NMathar "Code") | [<img src="https://avatars1.githubusercontent.com/u/139566?v=4" width="110px;"/><br /><sub>Steffen</sub>](https://github.com/smb)<br />[💻](https://github.com/snipe/snipe-it/commits?author=smb "Code") |
|
||||
| [<img src="https://avatars0.githubusercontent.com/u/6609453?v=4" width="110px;"/><br /><sub>Sxderp</sub>](https://github.com/Sxderp)<br />[💻](https://github.com/snipe/snipe-it/commits?author=Sxderp "Code") | [<img src="https://avatars1.githubusercontent.com/u/4807843?v=4" width="110px;"/><br /><sub>fanta8897</sub>](https://github.com/fanta8897)<br />[💻](https://github.com/snipe/snipe-it/commits?author=fanta8897 "Code") | [<img src="https://avatars2.githubusercontent.com/u/2576509?v=4" width="110px;"/><br /><sub>Andrey Bolonin</sub>](https://andreybolonin.com/phpconsulting/)<br />[💻](https://github.com/snipe/snipe-it/commits?author=andreybolonin "Code") | [<img src="https://avatars3.githubusercontent.com/u/2173307?v=4" width="110px;"/><br /><sub>shinayoshi</sub>](http://www.shinayoshi.net/)<br />[💻](https://github.com/snipe/snipe-it/commits?author=shinayoshi "Code") | [<img src="https://avatars3.githubusercontent.com/u/2130159?v=4" width="110px;"/><br /><sub>Hubert</sub>](https://github.com/reuser)<br />[💻](https://github.com/snipe/snipe-it/commits?author=reuser "Code") | [<img src="https://avatars0.githubusercontent.com/u/6865789?v=4" width="110px;"/><br /><sub>KeenRivals</sub>](https://brashear.me)<br />[💻](https://github.com/snipe/snipe-it/commits?author=KeenRivals "Code") | [<img src="https://avatars3.githubusercontent.com/u/2902513?v=4" width="110px;"/><br /><sub>omyno</sub>](https://github.com/omyno)<br />[💻](https://github.com/snipe/snipe-it/commits?author=omyno "Code") |
|
||||
| [<img src="https://avatars1.githubusercontent.com/u/6271335?v=4" width="110px;"/><br /><sub>Evgeny</sub>](https://github.com/jackka)<br />[💻](https://github.com/snipe/snipe-it/commits?author=jackka "Code") | [<img src="https://avatars2.githubusercontent.com/u/1169963?v=4" width="110px;"/><br /><sub>Colin Campbell</sub>](https://digitalist.se)<br />[💻](https://github.com/snipe/snipe-it/commits?author=colin-campbell "Code") | [<img src="https://avatars3.githubusercontent.com/u/2872098?v=4" width="110px;"/><br /><sub>Ľubomír Kučera</sub>](https://github.com/lubo)<br />[💻](https://github.com/snipe/snipe-it/commits?author=lubo "Code") | [<img src="https://avatars3.githubusercontent.com/u/570639?v=4" width="110px;"/><br /><sub>Martin Meredith</sub>](https://www.sourceguru.net)<br />[💻](https://github.com/snipe/snipe-it/commits?author=Mezzle "Code") | [<img src="https://avatars1.githubusercontent.com/u/7632599?v=4" width="110px;"/><br /><sub>Tim Farmer</sub>](https://github.com/timothyfarmer)<br />[💻](https://github.com/snipe/snipe-it/commits?author=timothyfarmer "Code") |
|
||||
<!-- ALL-CONTRIBUTORS-LIST:END -->
|
||||
|
||||
This project follows the [all-contributors](https://github.com/kentcdodds/all-contributors) specification. Contributions of any kind welcome!
|
||||
|
||||
-----
|
||||
|
||||
### Contributing
|
||||
|
||||
Please see the documentation on [contributing and developing for Snipe-IT](https://snipe-it.readme.io/docs/contributing-overview).
|
||||
|
||||
|
||||
Please note that this project is released with a [Contributor Code of Conduct](CODE_OF_CONDUCT.md). By participating in this project you agree to abide by its terms.
|
||||
|
|
18
Vagrantfile
vendored
18
Vagrantfile
vendored
|
@ -81,4 +81,22 @@ Vagrant.configure("2") do |config|
|
|||
fedora26.vm.provision :shell, :inline => "wget #{SNIPEIT_SH_URL}"
|
||||
fedora26.vm.provision :shell, :inline => "chmod 755 snipeit.sh"
|
||||
end
|
||||
|
||||
config.vm.define "freebsd" do |freebsd|
|
||||
freebsd.vm.box = "freebsd/FreeBSD-11.2-RELEASE"
|
||||
freebsd.vm.hostname = 'freebsd12'
|
||||
freebsd.vm.network "forwarded_port", guest: 80, host: 8080
|
||||
freebsd.vm.network "forwarded_port", guest:3306, host:3306 # mysql
|
||||
freebsd.vm.network "private_network", type: "dhcp"
|
||||
freebsd.ssh.shell = "sh"
|
||||
freebsd.vm.base_mac = "080027D14C66"
|
||||
freebsd.vm.synced_folder ".", "/vagrant", :nfs => true, id: "vagrant-root",
|
||||
:mount_options => ['rw', 'vers=3', 'tcp', 'actimeo=2']
|
||||
freebsd.vm.provision "shell", inline: <<-SHELL
|
||||
pkg install -y python27;
|
||||
SHELL
|
||||
freebsd.vm.provision "ansible" do |ansible|
|
||||
ansible.playbook = "ansible/freebsd/vagrant_playbook.yml"
|
||||
end
|
||||
end
|
||||
end
|
||||
|
|
260
ansible/freebsd/vagrant_playbook.yml
Normal file
260
ansible/freebsd/vagrant_playbook.yml
Normal file
|
@ -0,0 +1,260 @@
|
|||
---
|
||||
- name: Set up local server
|
||||
hosts: all
|
||||
remote_user: vagrant
|
||||
become_user: root
|
||||
become_method: sudo
|
||||
vars:
|
||||
- ansible_python_interpreter: /usr/local/bin/python2.7
|
||||
gather_facts: no
|
||||
|
||||
# Tasks
|
||||
tasks:
|
||||
|
||||
#
|
||||
# Update the PKG database
|
||||
#
|
||||
- name: Upgrade PKG database
|
||||
raw: sudo pkg upgrade -y
|
||||
|
||||
#
|
||||
# Mount the shared folders
|
||||
#
|
||||
- name: Update Vagrant Shared Folders
|
||||
command: "{{ item }}"
|
||||
with_items:
|
||||
- sysrc rpc_lockd_enable=YES
|
||||
- sysrc rpc_statd_enable=YES
|
||||
become: true
|
||||
|
||||
#
|
||||
# Install required utilities
|
||||
#
|
||||
- name: Install Utilities
|
||||
pkgng:
|
||||
name: "{{ item }}"
|
||||
state: present
|
||||
with_items:
|
||||
- openssl
|
||||
- node
|
||||
- npm
|
||||
- git
|
||||
- nano
|
||||
- wget
|
||||
- bash
|
||||
become: true
|
||||
|
||||
#
|
||||
# Install php and php dependancies
|
||||
#
|
||||
- name: Install PHP dependancies
|
||||
pkgng:
|
||||
name: "{{ item }}"
|
||||
state: present
|
||||
with_items:
|
||||
- php72
|
||||
- php72-zip
|
||||
- php72-zlib
|
||||
- php72-extensions
|
||||
- php72-mbstring
|
||||
- php72-openssl
|
||||
# - php72-mysqli
|
||||
- php72-curl
|
||||
- php72-soap
|
||||
- php72-pdo_mysql
|
||||
# - php72-pdo_pgsql
|
||||
- php72-ldap
|
||||
- php72-curl
|
||||
- php72-fileinfo
|
||||
- php72-bcmath
|
||||
- php72-gd
|
||||
become: true
|
||||
|
||||
#
|
||||
# Create a php.ini file
|
||||
#
|
||||
- name: PHP INI check
|
||||
stat:
|
||||
path: /usr/local/etc/php.ini
|
||||
register: php_ini_exits
|
||||
|
||||
- name: Create PHP ini
|
||||
command: cp /usr/local/etc/php.ini-development /usr/local/etc/php.ini
|
||||
become: true
|
||||
when: not php_ini_exits.stat.exists
|
||||
|
||||
- name: Enable PHP-FPM auto-start
|
||||
command: sysrc php_fpm_enable=YES
|
||||
become: true
|
||||
|
||||
- name: Start PHP-FPM service
|
||||
service:
|
||||
name: php-fpm
|
||||
state: started
|
||||
become: true
|
||||
|
||||
#
|
||||
# Install the lastest version of composer
|
||||
#
|
||||
- name: Composer check
|
||||
stat:
|
||||
path: /usr/local/bin/composer
|
||||
register: composer_exits
|
||||
|
||||
- name: Install Composer
|
||||
shell: |
|
||||
EXPECTED_SIGNATURE=$(wget -q -O - https://composer.github.io/installer.sig)
|
||||
php -r "copy('https://getcomposer.org/installer', 'composer-setup.php');"
|
||||
ACTUAL_SIGNATURE=$(php -r "echo hash_file('SHA384', 'composer-setup.php');")
|
||||
|
||||
if [ "$EXPECTED_SIGNATURE" != "$ACTUAL_SIGNATURE" ]
|
||||
then
|
||||
>&2 echo 'ERROR: Invalid installer signature'
|
||||
rm composer-setup.php
|
||||
exit 1
|
||||
fi
|
||||
|
||||
php composer-setup.php --quiet
|
||||
RESULT=$?
|
||||
rm composer-setup.php
|
||||
mv composer.phar /usr/local/bin/composer
|
||||
exit $RESULT
|
||||
when: not composer_exits.stat.exists
|
||||
become: true
|
||||
|
||||
#
|
||||
# Install MySQL Server
|
||||
|
||||
- name: Install MySQL 5.7
|
||||
pkgng:
|
||||
name: mysql57-server
|
||||
state: present
|
||||
become: true
|
||||
register: sql_server
|
||||
|
||||
- name: Start MySQL server
|
||||
service:
|
||||
name: mysql-server
|
||||
state: started
|
||||
become: true
|
||||
|
||||
- name: MySQL 5.7 auto-start
|
||||
command: sysrc mysql_enable=YES
|
||||
become: true
|
||||
when: sql_server.changed == true
|
||||
|
||||
- name: Get MySQL root password
|
||||
command: tail -1 /root/.mysql_secret
|
||||
register: myql_root_pwd
|
||||
become: true
|
||||
when: sql_server.changed == true
|
||||
|
||||
- name: Change MySQL root password
|
||||
command: mysqladmin -u root -p'{{myql_root_pwd.stdout}}' password vagrant
|
||||
when: sql_server.changed == true
|
||||
|
||||
- name: Enable remote mysql
|
||||
replace:
|
||||
path: /usr/local/etc/mysql/my.cnf
|
||||
regexp: "127.0.0.1"
|
||||
replace: "0.0.0.0"
|
||||
become: true
|
||||
when: sql_server.changed == true
|
||||
|
||||
- name: Grant user vagrant privelages
|
||||
shell: mysql -u root -pvagrant -e "GRANT ALL PRIVILEGES ON *.* TO 'root'@'%' IDENTIFIED BY 'vagrant' WITH GRANT OPTION; FLUSH PRIVILEGES;"
|
||||
become: true
|
||||
when: sql_server.changed == true
|
||||
ignore_errors: true
|
||||
|
||||
- name: Restart MySQL server
|
||||
service:
|
||||
name: mysql-server
|
||||
state: restarted
|
||||
become: true
|
||||
|
||||
|
||||
#
|
||||
# Install Apache Web Server
|
||||
#
|
||||
- name: Install Apache 2.4
|
||||
pkgng:
|
||||
name: apache24
|
||||
state: present
|
||||
become: true
|
||||
register: apache24_server
|
||||
|
||||
- name: Apache 2.4 auto-start
|
||||
command: sysrc apache24_enable=YES
|
||||
become: true
|
||||
when: apache24_server.changed == true
|
||||
|
||||
- name: Enable Apache modules
|
||||
replace:
|
||||
path: /usr/local/etc/apache24/httpd.conf
|
||||
regexp: "#{{ item }}"
|
||||
replace: "{{ item }}"
|
||||
become: true
|
||||
with_items:
|
||||
- LoadModule rewrite_module libexec/apache24/mod_rewrite.so
|
||||
- LoadModule vhost_alias_module libexec/apache24/mod_vhost_alias.so
|
||||
- LoadModule deflate_module libexec/apache24/mod_deflate.so
|
||||
- LoadModule expires_module libexec/apache24/mod_expires.so
|
||||
- LoadModule mpm_worker_module libexec/apache24/mod_mpm_worker.so
|
||||
- LoadModule proxy_fcgi_module libexec/apache24/mod_proxy_fcgi.so
|
||||
- LoadModule proxy_module libexec/apache24/mod_proxy.so
|
||||
- Include etc/apache24/extra/httpd-vhosts.conf
|
||||
when: apache24_server.changed == true
|
||||
|
||||
- name: Disable Apache modules
|
||||
replace:
|
||||
path: /usr/local/etc/apache24/httpd.conf
|
||||
regexp: "{{ item }}"
|
||||
replace: "#{{ item }}"
|
||||
become: true
|
||||
with_items:
|
||||
- LoadModule mpm_prefork_module libexec/apache24/mod_mpm_prefork.so
|
||||
when: apache24_server.changed == true
|
||||
|
||||
- name: Backup vhosts
|
||||
command: cp /usr/local/etc/apache24/extra/httpd-vhosts.conf /usr/local/etc/apache24/extra/httpd-vhosts.conf.bak
|
||||
become: true
|
||||
when: apache24_server.changed == true
|
||||
|
||||
- name: Truncate vhosts
|
||||
command: truncate -s 0 /usr/local/etc/apache24/extra/httpd-vhosts.conf
|
||||
become: true
|
||||
when: apache24_server.changed == true
|
||||
|
||||
- name: Set up vhost
|
||||
blockinfile:
|
||||
path: "/usr/local/etc/apache24/extra/httpd-vhosts.conf"
|
||||
block: |
|
||||
<VirtualHost *>
|
||||
DocumentRoot /usr/local/www/apache24/data/public
|
||||
ServerName vagrant.app
|
||||
ProxyPassMatch ^/(.*\.php(/.*)?)$ fcgi://127.0.0.1:9000/usr/local/www/apache24/data/public/$1
|
||||
DirectoryIndex /index.php index.php
|
||||
<Directory /usr/local/www/apache24/data/public>
|
||||
Options -Indexes +FollowSymLinks
|
||||
AllowOverride All
|
||||
Require all granted
|
||||
</Directory>
|
||||
</VirtualHost>
|
||||
become: true
|
||||
when: apache24_server.changed == true
|
||||
|
||||
- name: Map apache dir to local folder
|
||||
shell: |
|
||||
if ! [ -L /var/www ]; then
|
||||
rm -rf /usr/local/www/apache24/data;
|
||||
ln -fs /vagrant /usr/local/www/apache24/data;
|
||||
fi
|
||||
become: true
|
||||
when: apache24_server.changed == true
|
||||
|
||||
- name: Start Apache 2.4 server
|
||||
service:
|
||||
name: apache24
|
||||
state: started
|
||||
become: true
|
|
@ -76,10 +76,4 @@ class CreateAdmin extends Command
|
|||
|
||||
}
|
||||
|
||||
// protected function getArguments()
|
||||
// {
|
||||
// return array(
|
||||
// array('username', InputArgument::REQUIRED, 'Username'),
|
||||
// );
|
||||
// }
|
||||
}
|
||||
|
|
|
@ -2,8 +2,8 @@
|
|||
|
||||
namespace App\Console\Commands;
|
||||
|
||||
use Illuminate\Console\Command;
|
||||
use App\Models\Setting;
|
||||
use Illuminate\Console\Command;
|
||||
|
||||
class DisableLDAP extends Command
|
||||
{
|
||||
|
@ -41,7 +41,7 @@ class DisableLDAP extends Command
|
|||
|
||||
if ($this->confirm("\n****************************************************\nThis will disable LDAP support. You will not be able \nto login with an account that does not exist \nlocally in the Snipe-IT local database. \n****************************************************\n\nDo you wish to continue? [y|N]")) {
|
||||
|
||||
$setting = Setting::first();
|
||||
$setting = Setting::getSettings();
|
||||
$setting->ldap_enabled = 0;
|
||||
if ($setting->save()) {
|
||||
$this->info('LDAP has been set to disabled.');
|
||||
|
|
|
@ -71,7 +71,7 @@ class FixDoubleEscape extends Command
|
|||
|
||||
foreach($classname::where("$field",'LIKE','%&%')->get() as $row) {
|
||||
$this->info('Updating '.$field.' for '.$classname);
|
||||
$row->{$field} = html_entity_decode($row->{$field});
|
||||
$row->{$field} = html_entity_decode($row->{$field},ENT_QUOTES);
|
||||
$row->save();
|
||||
$count[$classname][$field]++;
|
||||
|
||||
|
|
183
app/Console/Commands/MoveUploadsToNewDisk.php
Normal file
183
app/Console/Commands/MoveUploadsToNewDisk.php
Normal file
|
@ -0,0 +1,183 @@
|
|||
<?php
|
||||
|
||||
namespace App\Console\Commands;
|
||||
|
||||
|
||||
use Illuminate\Console\Command;
|
||||
use Illuminate\Support\Facades\Storage;
|
||||
|
||||
class MoveUploadsToNewDisk extends Command
|
||||
{
|
||||
/**
|
||||
* The name and signature of the console command.
|
||||
*
|
||||
* @var string
|
||||
*/
|
||||
protected $signature = 'snipeit:move-uploads {delete_local?}';
|
||||
|
||||
/**
|
||||
* The console command description.
|
||||
*
|
||||
* @var string
|
||||
*/
|
||||
protected $description = 'This will move your uploaded files to whatever your current disk is.';
|
||||
|
||||
/**
|
||||
* Create a new command instance.
|
||||
*
|
||||
* @return void
|
||||
*/
|
||||
public function __construct()
|
||||
{
|
||||
parent::__construct();
|
||||
}
|
||||
|
||||
/**
|
||||
* Execute the console command.
|
||||
*
|
||||
* @return mixed
|
||||
*/
|
||||
public function handle()
|
||||
{
|
||||
|
||||
if (config('filesystems.default')=='local') {
|
||||
$this->error('Your current disk is set to local so we cannot proceed.');
|
||||
$this->warn("Please configure your .env settings for S3 or Rackspace, \nand change your FILESYSTEM_DISK value to 's3' or 'rackspace'.");
|
||||
return false;
|
||||
}
|
||||
$delete_local = $this->argument('delete_local');
|
||||
|
||||
$public_uploads['accessories'] = glob('storage/app/public/accessories'."/*.*");
|
||||
$public_uploads['assets'] = glob('storage/app/public/assets'."/*.*");
|
||||
$public_uploads['avatars'] = glob('storage/app/public/avatars'."/*.*");
|
||||
$public_uploads['barcodes'] = glob('storage/app/public/barcodes'."/*.*");
|
||||
$public_uploads['categories'] = glob('storage/app/public/categories'."/*.*");
|
||||
$public_uploads['companies'] = glob('storage/app/public/companies'."/*.*");
|
||||
$public_uploads['components'] = glob('storage/app/public/components'."/*.*");
|
||||
$public_uploads['consumables'] = glob('storage/app/public/consumables'."/*.*");
|
||||
$public_uploads['departments'] = glob('storage/app/public/departments'."/*.*");
|
||||
$public_uploads['locations'] = glob('storage/app/public/locations'."/*.*");
|
||||
$public_uploads['manufacturers'] = glob('storage/app/public/manufacturers'."/*.*");
|
||||
$public_uploads['suppliers'] = glob('storage/app/public/suppliers'."/*.*");
|
||||
$public_uploads['assetmodels'] = glob('storage/app/public/models'."/*.*");
|
||||
|
||||
|
||||
// iterate files
|
||||
foreach($public_uploads as $public_type => $public_upload)
|
||||
{
|
||||
$type_count = 0;
|
||||
$this->info("\nThere are ".count($public_upload).' PUBLIC '.$public_type.' files.');
|
||||
|
||||
for ($i = 0; $i < count($public_upload); $i++) {
|
||||
$type_count++;
|
||||
$filename = basename($public_upload[$i]);
|
||||
|
||||
try {
|
||||
Storage::disk('public')->put($public_type.'/'.$filename, file_get_contents($public_upload[$i]));
|
||||
$new_url = Storage::disk('public')->url($public_type.'/'.$filename, $filename);
|
||||
$this->info($type_count.'. PUBLIC: '.$filename.' was copied to '.$new_url);
|
||||
} catch (\Exception $e) {
|
||||
\Log::debug($e);
|
||||
$this->error($e);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
$logos = glob('public/uploads'."/logo*.*");
|
||||
$this->info("\nThere are ".count($logos).' files that might be logos.');
|
||||
$type_count=0;
|
||||
|
||||
for ($l = 0; $l < count($logos); $l++) {
|
||||
$type_count++;
|
||||
$filename = basename($logos[$l]);
|
||||
$new_url = Storage::disk('public')->url($logos[$l], file_get_contents($public_upload[$i]));
|
||||
$this->info($type_count.'. LOGO: '.$filename.' was copied to '.$new_url);
|
||||
}
|
||||
|
||||
$private_uploads['assets'] = glob('storage/private_uploads/assets'."/*.*");
|
||||
$private_uploads['signatures'] = glob('storage/private_uploads/signatures'."/*.*");
|
||||
$private_uploads['audits'] = glob('storage/private_uploads/audits'."/*.*");
|
||||
$private_uploads['assetmodels'] = glob('storage/private_uploads/assetmodels'."/*.*");
|
||||
$private_uploads['imports'] = glob('storage/private_uploads/imports'."/*.*");
|
||||
$private_uploads['licenses'] = glob('storage/private_uploads/licenses'."/*.*");
|
||||
$private_uploads['users'] = glob('storage/private_uploads/users'."/*.*");
|
||||
|
||||
|
||||
foreach($private_uploads as $private_type => $private_upload)
|
||||
{
|
||||
$this->info("\nThere are ".count($private_upload).' PRIVATE '.$private_type.' files.');
|
||||
// $this->info(print_r($private_upload, true));
|
||||
|
||||
$type_count = 0;
|
||||
for ($x = 0; $x < count($private_upload); $x++) {
|
||||
$type_count++;
|
||||
$filename = basename($private_upload[$x]);
|
||||
|
||||
try {
|
||||
Storage::disk('private_uploads')->put($private_type.'/'.$filename, file_get_contents($public_upload[$i]));
|
||||
$new_url = Storage::url($private_type.'/'.$filename, $filename);
|
||||
$this->info($type_count.'. PRIVATE: '.$filename.' was copied to '.$new_url);
|
||||
|
||||
} catch (\Exception $e) {
|
||||
\Log::debug($e);
|
||||
$this->error($e);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
|
||||
if ($delete_local=='true') {
|
||||
$public_delete_count = 0;
|
||||
$private_delete_count = 0;
|
||||
|
||||
$this->info("\n\n");
|
||||
$this->error('!!!!!!!!!!!!!!!!!!!!!!!!!!!!! WARNING!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!');
|
||||
$this->warn("\nTHIS WILL DELETE ALL OF YOUR LOCAL UPLOADED FILES. \n\nThis cannot be undone, so you should take a backup of your system before you proceed.\n");
|
||||
$this->error('!!!!!!!!!!!!!!!!!!!!!!!!!!!!! WARNING!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!');
|
||||
|
||||
if ($this->confirm("Do you wish to continue?")) {
|
||||
|
||||
foreach($public_uploads as $public_type => $public_upload) {
|
||||
|
||||
for ($i = 0; $i < count($public_upload); $i++) {
|
||||
$filename = $public_upload[$i];
|
||||
try {
|
||||
unlink($filename);
|
||||
$public_delete_count++;
|
||||
} catch (\Exception $e) {
|
||||
\Log::debug($e);
|
||||
$this->error($e);
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
foreach($private_uploads as $private_type => $private_upload)
|
||||
{
|
||||
|
||||
for ($i = 0; $i < count($private_upload); $i++) {
|
||||
$filename = $private_upload[$i];
|
||||
try {
|
||||
unlink($filename);
|
||||
$private_delete_count++;
|
||||
} catch (\Exception $e) {
|
||||
\Log::debug($e);
|
||||
$this->error($e);
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
$this->info($public_delete_count." PUBLIC local files and ".$private_delete_count." PRIVATE local files were delete from your filesystem.");
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
}
|
||||
}
|
|
@ -1,31 +1,9 @@
|
|||
<?php
|
||||
namespace App\Console\Commands;
|
||||
|
||||
use App\Helpers\Helper;
|
||||
use App\Importer\AccessoryImporter;
|
||||
use App\Importer\AssetImporter;
|
||||
use App\Importer\ConsumableImporter;
|
||||
use App\Importer\Importer;
|
||||
use App\Models\Accessory;
|
||||
use App\Models\Asset;
|
||||
use App\Models\AssetModel;
|
||||
use App\Models\Category;
|
||||
use App\Models\Company;
|
||||
use App\Models\Consumable;
|
||||
use App\Models\CustomField;
|
||||
use App\Models\Location;
|
||||
use App\Models\Manufacturer;
|
||||
use App\Models\Setting;
|
||||
use App\Models\Statuslabel;
|
||||
use App\Models\Supplier;
|
||||
use App\Models\User;
|
||||
use DB;
|
||||
use Illuminate\Console\Command;
|
||||
use Illuminate\Database\Eloquent\Model;
|
||||
use League\Csv\Reader;
|
||||
use Symfony\Component\Console\Input\InputArgument;
|
||||
use Symfony\Component\Console\Input\InputOption;
|
||||
use ForceUTF8\Encoding;
|
||||
|
||||
ini_set('max_execution_time', 600); //600 seconds = 10 minutes
|
||||
ini_set('memory_limit', '500M');
|
||||
|
|
|
@ -2,22 +2,19 @@
|
|||
|
||||
namespace App\Console\Commands;
|
||||
|
||||
use App\Models\Accessory;
|
||||
use App\Models\Asset;
|
||||
use App\Models\AssetModel;
|
||||
use App\Models\Category;
|
||||
use App\Models\Component;
|
||||
use App\Models\Consumable;
|
||||
use App\Models\License;
|
||||
use App\Models\Location;
|
||||
use App\Models\Manufacturer;
|
||||
use App\Models\Statuslabel;
|
||||
use App\Models\Supplier;
|
||||
use App\Models\User;
|
||||
use Illuminate\Console\Command;
|
||||
use DB;
|
||||
use \App\Models\Asset;
|
||||
use \App\Models\AssetModel;
|
||||
use \App\Models\Location;
|
||||
use \App\Models\Company;
|
||||
use \App\Models\License;
|
||||
use \App\Models\Accessory;
|
||||
use \App\Models\Component;
|
||||
use \App\Models\Consumable;
|
||||
use \App\Models\Category;
|
||||
use \App\Models\User;
|
||||
use \App\Models\Supplier;
|
||||
use \App\Models\Manufacturer;
|
||||
use \App\Models\Depreciation;
|
||||
use \App\Models\Statuslabel;
|
||||
|
||||
class Purge extends Command
|
||||
{
|
||||
|
|
|
@ -2,11 +2,11 @@
|
|||
|
||||
namespace App\Console\Commands;
|
||||
|
||||
use App\Models\CustomField;
|
||||
use Illuminate\Console\Command;
|
||||
use App\LegacyEncrypter\McryptEncrypter;
|
||||
use App\Models\Setting;
|
||||
use App\Models\Asset;
|
||||
use App\Models\CustomField;
|
||||
use App\Models\Setting;
|
||||
use Illuminate\Console\Command;
|
||||
use Illuminate\Support\Facades\Storage;
|
||||
|
||||
class RecryptFromMcrypt extends Command
|
||||
|
|
|
@ -2,11 +2,10 @@
|
|||
|
||||
namespace App\Console\Commands;
|
||||
|
||||
use Illuminate\Console\Command;
|
||||
use App\Models\Asset;
|
||||
use App\Models\Setting;
|
||||
use DB;
|
||||
use Artisan;
|
||||
use Illuminate\Console\Command;
|
||||
|
||||
class RegenerateAssetTags extends Command
|
||||
{
|
||||
|
|
|
@ -3,9 +3,9 @@
|
|||
namespace App\Console\Commands;
|
||||
|
||||
|
||||
use Illuminate\Console\Command;
|
||||
use App\Models\Setting;
|
||||
use App\Models\User;
|
||||
use Illuminate\Console\Command;
|
||||
|
||||
class ResetDemoSettings extends Command
|
||||
{
|
||||
|
|
|
@ -2,16 +2,13 @@
|
|||
|
||||
namespace App\Console\Commands;
|
||||
|
||||
use Illuminate\Console\Command;
|
||||
use App\Models\User;
|
||||
use App\Models\Actionlog;
|
||||
use App\Models\Asset;
|
||||
use App\Models\Consumable;
|
||||
use App\Models\Accessory;
|
||||
use App\Models\LicenseSeat;
|
||||
use App\Models\License;
|
||||
use DB;
|
||||
use App\Models\User;
|
||||
use Artisan;
|
||||
use DB;
|
||||
use Illuminate\Console\Command;
|
||||
|
||||
class RestoreDeletedUsers extends Command
|
||||
{
|
||||
|
|
60
app/Console/Commands/SendCurrentInventoryToUsers.php
Normal file
60
app/Console/Commands/SendCurrentInventoryToUsers.php
Normal file
|
@ -0,0 +1,60 @@
|
|||
<?php
|
||||
|
||||
namespace App\Console\Commands;
|
||||
|
||||
use App\Models\User;
|
||||
use App\Notifications\CurrentInventory;
|
||||
use Illuminate\Console\Command;
|
||||
|
||||
class SendCurrentInventoryToUsers extends Command
|
||||
{
|
||||
/**
|
||||
* The name and signature of the console command.
|
||||
*
|
||||
* @var string
|
||||
*/
|
||||
protected $signature = 'snipeit:user-inventory';
|
||||
|
||||
/**
|
||||
* The console command description.
|
||||
*
|
||||
* @var string
|
||||
*/
|
||||
protected $description = 'This will send users a report of all of the items currently checked out to them.';
|
||||
|
||||
/**
|
||||
* Create a new command instance.
|
||||
*
|
||||
* @return void
|
||||
*/
|
||||
public function __construct()
|
||||
{
|
||||
parent::__construct();
|
||||
}
|
||||
|
||||
/**
|
||||
* Execute the console command.
|
||||
*
|
||||
* @return mixed
|
||||
*/
|
||||
public function handle()
|
||||
{
|
||||
|
||||
$users = User::whereNull('deleted_at')->whereNotNull('email')->with('assets', 'accessories', 'licenses')->get();
|
||||
|
||||
$count = 0;
|
||||
foreach ($users as $user) {
|
||||
|
||||
if (($user->assets->count() > 0) || ($user->accessories->count() > 0) || ($user->licenses->count() > 0))
|
||||
{
|
||||
$count++;
|
||||
$user->notify((new CurrentInventory($user)));
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
$this->info($count.' users notified.');
|
||||
|
||||
|
||||
}
|
||||
}
|
|
@ -2,17 +2,15 @@
|
|||
|
||||
namespace App\Console\Commands;
|
||||
|
||||
|
||||
use App\Models\Asset;
|
||||
use App\Models\Setting;
|
||||
use Illuminate\Console\Command;
|
||||
use App\Notifications\ExpectedCheckinNotification;
|
||||
use App\Notifications\ExpectedCheckinAdminNotification;
|
||||
use App\Notifications\ExpectedCheckinNotification;
|
||||
use Carbon\Carbon;
|
||||
use Illuminate\Console\Command;
|
||||
|
||||
class SendExpectedCheckinAlerts extends Command
|
||||
{
|
||||
|
||||
/**
|
||||
* The console command name.
|
||||
*
|
||||
|
@ -29,8 +27,6 @@ class SendExpectedCheckinAlerts extends Command
|
|||
|
||||
/**
|
||||
* Create a new command instance.
|
||||
*
|
||||
* @return void
|
||||
*/
|
||||
public function __construct()
|
||||
{
|
||||
|
@ -44,15 +40,15 @@ class SendExpectedCheckinAlerts extends Command
|
|||
*/
|
||||
public function handle()
|
||||
{
|
||||
$settings = Setting::getSettings();
|
||||
$settings = Setting::getSettings();
|
||||
$whenNotify = Carbon::now()->addDays(7);
|
||||
$assets = Asset::with('assignedTo')->whereNotNull('assigned_to')->whereNotNull('expected_checkin')->where('expected_checkin', '<=', $whenNotify)->get();
|
||||
$assets = Asset::with('assignedTo')->whereNotNull('assigned_to')->whereNotNull('expected_checkin')->where('expected_checkin', '<=', $whenNotify)->get();
|
||||
|
||||
$this->info($whenNotify.' is deadline');
|
||||
$this->info($assets->count().' assets');
|
||||
$this->info($whenNotify . ' is deadline');
|
||||
$this->info($assets->count() . ' assets');
|
||||
|
||||
foreach ($assets as $asset) {
|
||||
if ($asset->assigned && $asset->checkedOutToUser()) {
|
||||
if ($asset->assigned && $asset->checkedOutToUser()) {
|
||||
$asset->assigned->notify((new ExpectedCheckinNotification($asset)));
|
||||
}
|
||||
}
|
||||
|
@ -60,14 +56,9 @@ class SendExpectedCheckinAlerts extends Command
|
|||
if (($assets) && ($assets->count() > 0) && ($settings->alert_email != '')) {
|
||||
// Send a rollup to the admin, if settings dictate
|
||||
$recipients = collect(explode(',', $settings->alert_email))->map(function ($item, $key) {
|
||||
return new \App\Models\Recipients\AlertRecipient($item);
|
||||
return new AlertRecipient($item);
|
||||
});
|
||||
\Notification::send($recipients, new ExpectedCheckinAdminNotification($assets));
|
||||
Notification::send($recipients, new ExpectedCheckinAdminNotification($assets));
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
}
|
||||
}
|
||||
|
|
|
@ -4,16 +4,14 @@ namespace App\Console\Commands;
|
|||
|
||||
use App\Models\Asset;
|
||||
use App\Models\License;
|
||||
use App\Models\Recipients\AlertRecipient;
|
||||
use App\Models\Setting;
|
||||
use DB;
|
||||
use App\Notifications\ExpiringLicenseNotification;
|
||||
use App\Notifications\ExpiringAssetsNotification;
|
||||
|
||||
use App\Notifications\ExpiringLicenseNotification;
|
||||
use Illuminate\Console\Command;
|
||||
|
||||
class SendExpirationAlerts extends Command
|
||||
{
|
||||
|
||||
/**
|
||||
* The console command name.
|
||||
*
|
||||
|
@ -30,8 +28,6 @@ class SendExpirationAlerts extends Command
|
|||
|
||||
/**
|
||||
* Create a new command instance.
|
||||
*
|
||||
* @return void
|
||||
*/
|
||||
public function __construct()
|
||||
{
|
||||
|
@ -45,48 +41,35 @@ class SendExpirationAlerts extends Command
|
|||
*/
|
||||
public function handle()
|
||||
{
|
||||
|
||||
$settings = Setting::getSettings();
|
||||
$settings = Setting::getSettings();
|
||||
$threshold = $settings->alert_interval;
|
||||
|
||||
|
||||
if (($settings->alert_email != '') && ($settings->alerts_enabled == 1)) {
|
||||
|
||||
// Send a rollup to the admin, if settings dictate
|
||||
$recipients = collect(explode(',', $settings->alert_email))->map(function ($item, $key) {
|
||||
return new \App\Models\Recipients\AlertRecipient($item);
|
||||
return new AlertRecipient($item);
|
||||
});
|
||||
|
||||
// Expiring Assets
|
||||
$assets = Asset::getExpiringWarrantee(Setting::getSettings()->alert_interval);
|
||||
$assets = Asset::getExpiringWarrantee($threshold);
|
||||
if ($assets->count() > 0) {
|
||||
$this->info(trans_choice('mail.assets_warrantee_alert', $assets->count(),
|
||||
['count' => $assets->count(), 'threshold' => $threshold]));
|
||||
\Notification::send($recipients, new ExpiringAssetsNotification($assets, $threshold));
|
||||
$this->info(trans_choice('mail.assets_warrantee_alert', $assets->count(), ['count' => $assets->count(), 'threshold' => $threshold]));
|
||||
Notification::send($recipients, new ExpiringAssetsNotification($assets, $threshold));
|
||||
}
|
||||
|
||||
// Expiring licenses
|
||||
$licenses = License::getExpiringLicenses($threshold);
|
||||
|
||||
|
||||
if ($licenses->count() > 0) {
|
||||
$this->info(trans_choice('mail.license_expiring_alert', $licenses->count(), ['count' => $licenses->count(), 'threshold' => $threshold]));
|
||||
\Notification::send($recipients, new ExpiringLicenseNotification($licenses, $threshold));
|
||||
Notification::send($recipients, new ExpiringLicenseNotification($licenses, $threshold));
|
||||
}
|
||||
|
||||
|
||||
} else {
|
||||
|
||||
if ($settings->alert_email=='') {
|
||||
if ($settings->alert_email == '') {
|
||||
$this->error('Could not send email. No alert email configured in settings');
|
||||
} elseif ($settings->alerts_enabled!=1) {
|
||||
} elseif (1 != $settings->alerts_enabled) {
|
||||
$this->info('Alerts are disabled in the settings. No mail will be sent');
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
}
|
||||
}
|
||||
|
|
|
@ -2,13 +2,12 @@
|
|||
|
||||
namespace App\Console\Commands;
|
||||
|
||||
use App\Models\Setting;
|
||||
use DB;
|
||||
use Mail;
|
||||
use App\Helpers\Helper;
|
||||
use App\Models\Recipients\AlertRecipient;
|
||||
use App\Models\Setting;
|
||||
use App\Notifications\InventoryAlert;
|
||||
|
||||
use Illuminate\Console\Command;
|
||||
use Illuminate\Support\Facades\Notification;
|
||||
|
||||
class SendInventoryAlerts extends Command
|
||||
{
|
||||
|
@ -28,8 +27,6 @@ class SendInventoryAlerts extends Command
|
|||
|
||||
/**
|
||||
* Create a new command instance.
|
||||
*
|
||||
* @return void
|
||||
*/
|
||||
public function __construct()
|
||||
{
|
||||
|
@ -45,29 +42,24 @@ class SendInventoryAlerts extends Command
|
|||
{
|
||||
$settings = Setting::getSettings();
|
||||
|
||||
if (($settings->alert_email!='') && ($settings->alerts_enabled==1)) {
|
||||
|
||||
if (($settings->alert_email != '') && ($settings->alerts_enabled == 1)) {
|
||||
$items = Helper::checkLowInventory();
|
||||
|
||||
// Send a rollup to the admin, if settings dictate
|
||||
|
||||
if (($items) && (count($items) > 0)) {
|
||||
$this->info(trans_choice('mail.low_inventory_alert', count($items)));
|
||||
// Send a rollup to the admin, if settings dictate
|
||||
$recipients = collect(explode(',', $settings->alert_email))->map(function ($item, $key) {
|
||||
return new \App\Models\Recipients\AlertRecipient($item);
|
||||
return new AlertRecipient($item);
|
||||
});
|
||||
\Notification::send($recipients, new InventoryAlert($items, $settings->alert_threshold));
|
||||
}
|
||||
|
||||
Notification::send($recipients, new InventoryAlert($items, $settings->alert_threshold));
|
||||
}
|
||||
} else {
|
||||
if (Setting::getSettings()->alert_email=='') {
|
||||
if ($settings->alert_email == '') {
|
||||
$this->error('Could not send email. No alert email configured in settings');
|
||||
} elseif (Setting::getSettings()->alerts_enabled!=1) {
|
||||
} elseif (1 != $settings->alerts_enabled) {
|
||||
$this->info('Alerts are disabled in the settings. No mail will be sent');
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
}
|
||||
|
|
|
@ -2,8 +2,8 @@
|
|||
|
||||
namespace App\Console\Commands;
|
||||
|
||||
use Illuminate\Console\Command;
|
||||
use App\Models\Asset;
|
||||
use Illuminate\Console\Command;
|
||||
|
||||
class SyncAssetCounters extends Command
|
||||
{
|
||||
|
|
|
@ -2,10 +2,8 @@
|
|||
|
||||
namespace App\Console\Commands;
|
||||
|
||||
use App\Models\CustomField;
|
||||
use Illuminate\Console\Command;
|
||||
use App\Models\Asset;
|
||||
use Illuminate\Support\Facades\Storage;
|
||||
use Illuminate\Console\Command;
|
||||
|
||||
class SyncAssetLocations extends Command
|
||||
{
|
||||
|
|
|
@ -19,7 +19,6 @@ class Kernel extends ConsoleKernel
|
|||
*/
|
||||
protected function schedule(Schedule $schedule)
|
||||
{
|
||||
|
||||
$schedule->command('snipeit:inventory-alerts')->daily();
|
||||
$schedule->command('snipeit:expiring-alerts')->daily();
|
||||
$schedule->command('snipeit:expected-checkin')->daily();
|
||||
|
@ -28,6 +27,10 @@ class Kernel extends ConsoleKernel
|
|||
$schedule->command('snipeit:upcoming-audits')->daily();
|
||||
}
|
||||
|
||||
/**
|
||||
* This method is required by Laravel to handle any console routes
|
||||
* that are defined in routes/console.php.
|
||||
*/
|
||||
protected function commands()
|
||||
{
|
||||
require base_path('routes/console.php');
|
||||
|
|
23
app/Events/CheckoutAccepted.php
Normal file
23
app/Events/CheckoutAccepted.php
Normal file
|
@ -0,0 +1,23 @@
|
|||
<?php
|
||||
|
||||
namespace App\Events;
|
||||
|
||||
use App\Models\CheckoutAcceptance;
|
||||
use App\Models\Contracts\Acceptable;
|
||||
use Illuminate\Foundation\Events\Dispatchable;
|
||||
use Illuminate\Queue\SerializesModels;
|
||||
|
||||
class CheckoutAccepted
|
||||
{
|
||||
use Dispatchable, SerializesModels;
|
||||
|
||||
/**
|
||||
* Create a new event instance.
|
||||
*
|
||||
* @return void
|
||||
*/
|
||||
public function __construct(CheckoutAcceptance $acceptance)
|
||||
{
|
||||
$this->acceptance = $acceptance;
|
||||
}
|
||||
}
|
23
app/Events/CheckoutDeclined.php
Normal file
23
app/Events/CheckoutDeclined.php
Normal file
|
@ -0,0 +1,23 @@
|
|||
<?php
|
||||
|
||||
namespace App\Events;
|
||||
|
||||
use App\Models\CheckoutAcceptance;
|
||||
use App\Models\Contracts\Acceptable;
|
||||
use Illuminate\Foundation\Events\Dispatchable;
|
||||
use Illuminate\Queue\SerializesModels;
|
||||
|
||||
class CheckoutDeclined
|
||||
{
|
||||
use Dispatchable, SerializesModels;
|
||||
|
||||
/**
|
||||
* Create a new event instance.
|
||||
*
|
||||
* @return void
|
||||
*/
|
||||
public function __construct(CheckoutAcceptance $acceptance)
|
||||
{
|
||||
$this->acceptance = $acceptance;
|
||||
}
|
||||
}
|
32
app/Events/CheckoutableCheckedIn.php
Normal file
32
app/Events/CheckoutableCheckedIn.php
Normal file
|
@ -0,0 +1,32 @@
|
|||
<?php
|
||||
|
||||
namespace App\Events;
|
||||
|
||||
use App\Models\User;
|
||||
use Illuminate\Foundation\Events\Dispatchable;
|
||||
use Illuminate\Queue\SerializesModels;
|
||||
|
||||
class CheckoutableCheckedIn
|
||||
{
|
||||
use Dispatchable, SerializesModels;
|
||||
|
||||
public $checkoutable;
|
||||
public $checkedOutTo;
|
||||
public $checkedInBy;
|
||||
public $note;
|
||||
public $action_date; // Date setted in the hardware.checkin view at the checkin_at input, for the action log
|
||||
|
||||
/**
|
||||
* Create a new event instance.
|
||||
*
|
||||
* @return void
|
||||
*/
|
||||
public function __construct($checkoutable, $checkedOutTo, User $checkedInBy, $note, $action_date)
|
||||
{
|
||||
$this->checkoutable = $checkoutable;
|
||||
$this->checkedOutTo = $checkedOutTo;
|
||||
$this->checkedInBy = $checkedInBy;
|
||||
$this->note = $note;
|
||||
$this->action_date = $action_date;
|
||||
}
|
||||
}
|
30
app/Events/CheckoutableCheckedOut.php
Normal file
30
app/Events/CheckoutableCheckedOut.php
Normal file
|
@ -0,0 +1,30 @@
|
|||
<?php
|
||||
|
||||
namespace App\Events;
|
||||
|
||||
use App\Models\User;
|
||||
use Illuminate\Foundation\Events\Dispatchable;
|
||||
use Illuminate\Queue\SerializesModels;
|
||||
|
||||
class CheckoutableCheckedOut
|
||||
{
|
||||
use Dispatchable, SerializesModels;
|
||||
|
||||
public $checkoutable;
|
||||
public $checkedOutTo;
|
||||
public $checkedOutBy;
|
||||
public $note;
|
||||
|
||||
/**
|
||||
* Create a new event instance.
|
||||
*
|
||||
* @return void
|
||||
*/
|
||||
public function __construct($checkoutable, $checkedOutTo, User $checkedOutBy, $note)
|
||||
{
|
||||
$this->checkoutable = $checkoutable;
|
||||
$this->checkedOutTo = $checkedOutTo;
|
||||
$this->checkedOutBy = $checkedOutBy;
|
||||
$this->note = $note;
|
||||
}
|
||||
}
|
|
@ -3,6 +3,7 @@
|
|||
namespace App\Exceptions;
|
||||
|
||||
use Exception;
|
||||
|
||||
class CheckoutNotAllowed extends Exception
|
||||
{
|
||||
|
||||
|
|
|
@ -9,6 +9,7 @@ use App\Helpers\Helper;
|
|||
use Illuminate\Validation\ValidationException;
|
||||
use Log;
|
||||
|
||||
|
||||
class Handler extends ExceptionHandler
|
||||
{
|
||||
/**
|
||||
|
|
|
@ -1,25 +1,16 @@
|
|||
<?php
|
||||
namespace App\Helpers;
|
||||
|
||||
use DB;
|
||||
use App\Models\Statuslabel;
|
||||
use App\Models\Location;
|
||||
use App\Models\Department;
|
||||
use App\Models\AssetModel;
|
||||
use App\Models\Company;
|
||||
use App\Models\User;
|
||||
use App\Models\Manufacturer;
|
||||
use App\Models\Supplier;
|
||||
use App\Models\Category;
|
||||
use App\Models\Depreciation;
|
||||
use App\Models\CustomFieldset;
|
||||
use App\Models\CustomField;
|
||||
use App\Models\Component;
|
||||
use App\Models\Accessory;
|
||||
use App\Models\Component;
|
||||
use App\Models\Consumable;
|
||||
use App\Models\Asset;
|
||||
use App\Models\CustomField;
|
||||
use App\Models\CustomFieldset;
|
||||
use App\Models\Depreciation;
|
||||
use App\Models\Setting;
|
||||
use App\Models\Statuslabel;
|
||||
use Crypt;
|
||||
use Image;
|
||||
use Illuminate\Contracts\Encryption\DecryptException;
|
||||
|
||||
class Helper
|
||||
|
@ -225,8 +216,9 @@ class Helper
|
|||
*/
|
||||
public static function predefined_formats()
|
||||
{
|
||||
$keys = array_keys(CustomField::$PredefinedFormats);
|
||||
$keys = array_keys(CustomField::PREDEFINED_FORMATS);
|
||||
$stuff = array_combine($keys, $keys);
|
||||
|
||||
return $stuff;
|
||||
}
|
||||
|
||||
|
@ -669,7 +661,80 @@ class Helper
|
|||
return false;
|
||||
}
|
||||
|
||||
/**
|
||||
* Generate a random encrypted password.
|
||||
*
|
||||
* @author Wes Hulette <jwhulette@gmail.com>
|
||||
*
|
||||
* @since 5.0.0
|
||||
*
|
||||
* @return string
|
||||
*/
|
||||
public static function generateEncyrptedPassword(): string
|
||||
{
|
||||
return bcrypt(Helper::generateUnencryptedPassword());
|
||||
}
|
||||
|
||||
/**
|
||||
* Get a random unencrypted password.
|
||||
*
|
||||
* @author Steffen Buehl <sb@sbuehl.com>
|
||||
*
|
||||
* @since 5.0.0
|
||||
*
|
||||
* @return string
|
||||
*/
|
||||
public static function generateUnencryptedPassword(): string
|
||||
{
|
||||
$chars = '0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ';
|
||||
|
||||
$password = '';
|
||||
for ( $i = 0; $i < 20; $i++ ) {
|
||||
$password .= substr( $chars, random_int( 0, strlen( $chars ) - 1 ), 1 );
|
||||
}
|
||||
return $password;
|
||||
}
|
||||
|
||||
/**
|
||||
* Process base64 encoded image data and save it on supplied path
|
||||
*
|
||||
* @param string $image_data base64 encoded image data with mime type
|
||||
* @param string $save_path path to a folder where the image should be saved
|
||||
* @return string path to uploaded image or false if something went wrong
|
||||
*/
|
||||
public static function processUploadedImage(String $image_data, String $save_path) {
|
||||
if ($image_data != null && $save_path != null) {
|
||||
// After modification, the image is prefixed by mime info like the following:
|
||||
// data:image/jpeg;base64,; This causes the image library to be unhappy, so we need to remove it.
|
||||
$header = explode(';', $image_data, 2)[0];
|
||||
// Grab the image type from the header while we're at it.
|
||||
$extension = substr($header, strpos($header, '/')+1);
|
||||
// Start reading the image after the first comma, postceding the base64.
|
||||
$image = substr($image_data, strpos($image_data, ',')+1);
|
||||
|
||||
$file_name = str_random(25).".".$extension;
|
||||
|
||||
$directory= public_path($save_path);
|
||||
// Check if the uploads directory exists. If not, try to create it.
|
||||
if (!file_exists($directory)) {
|
||||
mkdir($directory, 0755, true);
|
||||
}
|
||||
|
||||
$path = public_path($save_path.$file_name);
|
||||
|
||||
try {
|
||||
Image::make($image)->resize(500, 500, function ($constraint) {
|
||||
$constraint->aspectRatio();
|
||||
$constraint->upsize();
|
||||
})->save($path);
|
||||
} catch (\Exception $e) {
|
||||
return false;
|
||||
}
|
||||
|
||||
return $file_name;
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
}
|
||||
|
|
207
app/Http/Controllers/Accessories/AccessoriesController.php
Executable file
207
app/Http/Controllers/Accessories/AccessoriesController.php
Executable file
|
@ -0,0 +1,207 @@
|
|||
<?php
|
||||
namespace App\Http\Controllers\Accessories;
|
||||
|
||||
use App\Helpers\Helper;
|
||||
use App\Http\Controllers\Controller;
|
||||
use App\Http\Requests\ImageUploadRequest;
|
||||
use App\Models\Accessory;
|
||||
use App\Models\Company;
|
||||
use Illuminate\Support\Facades\Auth;
|
||||
use Illuminate\Support\Facades\Storage;
|
||||
use Redirect;
|
||||
|
||||
/** This controller handles all actions related to Accessories for
|
||||
* the Snipe-IT Asset Management application.
|
||||
*
|
||||
* @version v1.0
|
||||
*/
|
||||
class AccessoriesController extends Controller
|
||||
{
|
||||
/**
|
||||
* Returns a view that invokes the ajax tables which actually contains
|
||||
* the content for the accessories listing, which is generated in getDatatable.
|
||||
*
|
||||
* @author [A. Gianotto] [<snipe@snipe.net>]
|
||||
* @see AccessoriesController::getDatatable() method that generates the JSON response
|
||||
* @since [v1.0]
|
||||
* @return View
|
||||
* @throws \Illuminate\Auth\Access\AuthorizationException
|
||||
*/
|
||||
public function index()
|
||||
{
|
||||
$this->authorize('index', Accessory::class);
|
||||
return view('accessories/index');
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Returns a view with a form to create a new Accessory.
|
||||
*
|
||||
* @author [A. Gianotto] [<snipe@snipe.net>]
|
||||
* @return View
|
||||
* @throws \Illuminate\Auth\Access\AuthorizationException
|
||||
*/
|
||||
public function create()
|
||||
{
|
||||
$this->authorize('create', Accessory::class);
|
||||
$category_type = 'accessory';
|
||||
return view('accessories/edit')->with('category_type', $category_type)
|
||||
->with('item', new Accessory);
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Validate and save new Accessory from form post
|
||||
*
|
||||
* @author [A. Gianotto] [<snipe@snipe.net>]
|
||||
* @param ImageUploadRequest $request
|
||||
* @return Redirect
|
||||
* @throws \Illuminate\Auth\Access\AuthorizationException
|
||||
*/
|
||||
public function store(ImageUploadRequest $request)
|
||||
{
|
||||
$this->authorize(Accessory::class);
|
||||
// create a new model instance
|
||||
$accessory = new Accessory();
|
||||
|
||||
// Update the accessory data
|
||||
$accessory->name = request('name');
|
||||
$accessory->category_id = request('category_id');
|
||||
$accessory->location_id = request('location_id');
|
||||
$accessory->min_amt = request('min_amt');
|
||||
$accessory->company_id = Company::getIdForCurrentUser(request('company_id'));
|
||||
$accessory->order_number = request('order_number');
|
||||
$accessory->manufacturer_id = request('manufacturer_id');
|
||||
$accessory->model_number = request('model_number');
|
||||
$accessory->purchase_date = request('purchase_date');
|
||||
$accessory->purchase_cost = Helper::ParseFloat(request('purchase_cost'));
|
||||
$accessory->qty = request('qty');
|
||||
$accessory->user_id = Auth::user()->id;
|
||||
$accessory->supplier_id = request('supplier_id');
|
||||
|
||||
$accessory = $request->handleImages($accessory);
|
||||
|
||||
// Was the accessory created?
|
||||
if ($accessory->save()) {
|
||||
// Redirect to the new accessory page
|
||||
return redirect()->route('accessories.index')->with('success', trans('admin/accessories/message.create.success'));
|
||||
}
|
||||
return redirect()->back()->withInput()->withErrors($accessory->getErrors());
|
||||
}
|
||||
|
||||
/**
|
||||
* Return view for the Accessory update form, prepopulated with existing data
|
||||
*
|
||||
* @author [A. Gianotto] [<snipe@snipe.net>]
|
||||
* @param int $accessoryId
|
||||
* @return View
|
||||
* @throws \Illuminate\Auth\Access\AuthorizationException
|
||||
*/
|
||||
public function edit($accessoryId = null)
|
||||
{
|
||||
|
||||
if ($item = Accessory::find($accessoryId)) {
|
||||
$this->authorize($item);
|
||||
return view('accessories/edit', compact('item'))->with('category_type', 'accessory');
|
||||
}
|
||||
|
||||
return redirect()->route('accessories.index')->with('error', trans('admin/accessories/message.does_not_exist'));
|
||||
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Save edited Accessory from form post
|
||||
*
|
||||
* @author [A. Gianotto] [<snipe@snipe.net>]
|
||||
* @param ImageUploadRequest $request
|
||||
* @param int $accessoryId
|
||||
* @return Redirect
|
||||
* @throws \Illuminate\Auth\Access\AuthorizationException
|
||||
*/
|
||||
public function update(ImageUploadRequest $request, $accessoryId = null)
|
||||
{
|
||||
if (is_null($accessory = Accessory::find($accessoryId))) {
|
||||
return redirect()->route('accessories.index')->with('error', trans('admin/accessories/message.does_not_exist'));
|
||||
}
|
||||
|
||||
$this->authorize($accessory);
|
||||
|
||||
// Update the accessory data
|
||||
$accessory->name = request('name');
|
||||
$accessory->location_id = request('location_id');
|
||||
$accessory->min_amt = request('min_amt');
|
||||
$accessory->category_id = request('category_id');
|
||||
$accessory->company_id = Company::getIdForCurrentUser(request('company_id'));
|
||||
$accessory->manufacturer_id = request('manufacturer_id');
|
||||
$accessory->order_number = request('order_number');
|
||||
$accessory->model_number = request('model_number');
|
||||
$accessory->purchase_date = request('purchase_date');
|
||||
$accessory->purchase_cost = request('purchase_cost');
|
||||
$accessory->qty = request('qty');
|
||||
$accessory->supplier_id = request('supplier_id');
|
||||
|
||||
$accessory = $request->handleImages($accessory);
|
||||
|
||||
// Was the accessory updated?
|
||||
if ($accessory->save()) {
|
||||
return redirect()->route('accessories.index')->with('success', trans('admin/accessories/message.update.success'));
|
||||
}
|
||||
return redirect()->back()->withInput()->withErrors($accessory->getErrors());
|
||||
}
|
||||
|
||||
/**
|
||||
* Delete the given accessory.
|
||||
*
|
||||
* @author [A. Gianotto] [<snipe@snipe.net>]
|
||||
* @param int $accessoryId
|
||||
* @return Redirect
|
||||
* @throws \Illuminate\Auth\Access\AuthorizationException
|
||||
*/
|
||||
public function destroy($accessoryId)
|
||||
{
|
||||
if (is_null($accessory = Accessory::find($accessoryId))) {
|
||||
return redirect()->route('accessories.index')->with('error', trans('admin/accessories/message.not_found'));
|
||||
}
|
||||
|
||||
$this->authorize($accessory);
|
||||
|
||||
|
||||
if ($accessory->hasUsers() > 0) {
|
||||
return redirect()->route('accessories.index')->with('error', trans('admin/accessories/message.assoc_users', array('count'=> $accessory->hasUsers())));
|
||||
}
|
||||
|
||||
if ($accessory->image) {
|
||||
try {
|
||||
Storage::disk('public')->delete('accessories'.'/'.$accessory->image);
|
||||
} catch (\Exception $e) {
|
||||
\Log::debug($e);
|
||||
}
|
||||
}
|
||||
|
||||
$accessory->delete();
|
||||
return redirect()->route('accessories.index')->with('success', trans('admin/accessories/message.delete.success'));
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Returns a view that invokes the ajax table which contains
|
||||
* the content for the accessory detail view, which is generated in getDataView.
|
||||
*
|
||||
* @author [A. Gianotto] [<snipe@snipe.net>]
|
||||
* @param int $accessoryID
|
||||
* @see AccessoriesController::getDataView() method that generates the JSON response
|
||||
* @since [v1.0]
|
||||
* @return View
|
||||
* @throws \Illuminate\Auth\Access\AuthorizationException
|
||||
*/
|
||||
public function show($accessoryID = null)
|
||||
{
|
||||
$accessory = Accessory::find($accessoryID);
|
||||
$this->authorize('view', $accessory);
|
||||
if (isset($accessory->id)) {
|
||||
return view('accessories/view', compact('accessory'));
|
||||
}
|
||||
return redirect()->route('accessories.index')->with('error', trans('admin/accessories/message.does_not_exist', ['id' => $accessoryID]));
|
||||
}
|
||||
}
|
|
@ -0,0 +1,78 @@
|
|||
<?php
|
||||
|
||||
namespace App\Http\Controllers\Accessories;
|
||||
|
||||
use App\Events\CheckoutableCheckedIn;
|
||||
use App\Http\Controllers\Controller;
|
||||
use App\Models\Accessory;
|
||||
use App\Models\User;
|
||||
use Illuminate\Http\Request;
|
||||
use Illuminate\Support\Facades\Auth;
|
||||
use Illuminate\Support\Facades\DB;
|
||||
|
||||
class AccessoryCheckinController extends Controller
|
||||
{
|
||||
/**
|
||||
* Check the accessory back into inventory
|
||||
*
|
||||
* @author [A. Gianotto] [<snipe@snipe.net>]
|
||||
* @param Request $request
|
||||
* @param integer $accessoryUserId
|
||||
* @param string $backto
|
||||
* @return View
|
||||
* @internal param int $accessoryId
|
||||
* @throws \Illuminate\Auth\Access\AuthorizationException
|
||||
*/
|
||||
public function create($accessoryUserId = null, $backto = null)
|
||||
{
|
||||
// Check if the accessory exists
|
||||
if (is_null($accessory_user = DB::table('accessories_users')->find($accessoryUserId))) {
|
||||
// Redirect to the accessory management page with error
|
||||
return redirect()->route('accessories.index')->with('error', trans('admin/accessories/message.not_found'));
|
||||
}
|
||||
|
||||
$accessory = Accessory::find($accessory_user->accessory_id);
|
||||
$this->authorize('checkin', $accessory);
|
||||
return view('accessories/checkin', compact('accessory'))->with('backto', $backto);
|
||||
}
|
||||
|
||||
/**
|
||||
* Check in the item so that it can be checked out again to someone else
|
||||
*
|
||||
* @uses Accessory::checkin_email() to determine if an email can and should be sent
|
||||
* @author [A. Gianotto] [<snipe@snipe.net>]
|
||||
* @param null $accessoryUserId
|
||||
* @param string $backto
|
||||
* @return Redirect
|
||||
* @throws \Illuminate\Auth\Access\AuthorizationException
|
||||
* @internal param int $accessoryId
|
||||
*/
|
||||
public function store(Request $request, $accessoryUserId = null, $backto = null)
|
||||
{
|
||||
// Check if the accessory exists
|
||||
if (is_null($accessory_user = DB::table('accessories_users')->find($accessoryUserId))) {
|
||||
// Redirect to the accessory management page with error
|
||||
return redirect()->route('accessories.index')->with('error', trans('admin/accessories/message.does_not_exist'));
|
||||
}
|
||||
|
||||
$accessory = Accessory::find($accessory_user->accessory_id);
|
||||
|
||||
$this->authorize('checkin', $accessory);
|
||||
|
||||
$checkin_at = date('Y-m-d');
|
||||
if($request->filled('checkin_at')){
|
||||
$checkin_at = $request->input('checkin_at');
|
||||
}
|
||||
|
||||
// Was the accessory updated?
|
||||
if (DB::table('accessories_users')->where('id', '=', $accessory_user->id)->delete()) {
|
||||
$return_to = e($accessory_user->assigned_to);
|
||||
|
||||
event(new CheckoutableCheckedIn($accessory, User::find($return_to), Auth::user(), $request->input('note'), $checkin_at));
|
||||
|
||||
return redirect()->route("accessories.show", $accessory->id)->with('success', trans('admin/accessories/message.checkin.success'));
|
||||
}
|
||||
// Redirect to the accessory management page with error
|
||||
return redirect()->route('accessories.index')->with('error', trans('admin/accessories/message.checkin.error'));
|
||||
}
|
||||
}
|
|
@ -0,0 +1,88 @@
|
|||
<?php
|
||||
|
||||
namespace App\Http\Controllers\Accessories;
|
||||
|
||||
use App\Events\CheckoutableCheckedOut;
|
||||
use App\Http\Controllers\Controller;
|
||||
use App\Models\Accessory;
|
||||
use App\Models\User;
|
||||
use Carbon\Carbon;
|
||||
use Illuminate\Http\Request;
|
||||
use Illuminate\Support\Facades\Auth;
|
||||
use Illuminate\Support\Facades\DB;
|
||||
use Illuminate\Support\Facades\Input;
|
||||
|
||||
class AccessoryCheckoutController extends Controller
|
||||
{
|
||||
|
||||
/**
|
||||
* Return the form to checkout an Accessory to a user.
|
||||
*
|
||||
* @author [A. Gianotto] [<snipe@snipe.net>]
|
||||
* @param int $accessoryId
|
||||
* @return View
|
||||
* @throws \Illuminate\Auth\Access\AuthorizationException
|
||||
*/
|
||||
public function create($accessoryId)
|
||||
{
|
||||
// Check if the accessory exists
|
||||
if (is_null($accessory = Accessory::find($accessoryId))) {
|
||||
// Redirect to the accessory management page with error
|
||||
return redirect()->route('accessories.index')->with('error', trans('admin/accessories/message.not_found'));
|
||||
}
|
||||
|
||||
if ($accessory->category) {
|
||||
|
||||
$this->authorize('checkout', $accessory);
|
||||
|
||||
// Get the dropdown of users and then pass it to the checkout view
|
||||
return view('accessories/checkout', compact('accessory'));
|
||||
}
|
||||
|
||||
return redirect()->back()->with('error', 'The category type for this accessory is not valid. Edit the accessory and select a valid accessory category.');
|
||||
}
|
||||
|
||||
/**
|
||||
* Save the Accessory checkout information.
|
||||
*
|
||||
* If Slack is enabled and/or asset acceptance is enabled, it will also
|
||||
* trigger a Slack message and send an email.
|
||||
*
|
||||
* @author [A. Gianotto] [<snipe@snipe.net>]
|
||||
* @param Request $request
|
||||
* @param int $accessoryId
|
||||
* @return Redirect
|
||||
* @throws \Illuminate\Auth\Access\AuthorizationException
|
||||
*/
|
||||
public function store(Request $request, $accessoryId)
|
||||
{
|
||||
// Check if the accessory exists
|
||||
if (is_null($accessory = Accessory::find($accessoryId))) {
|
||||
// Redirect to the accessory management page with error
|
||||
return redirect()->route('accessories.index')->with('error', trans('admin/accessories/message.user_not_found'));
|
||||
}
|
||||
|
||||
$this->authorize('checkout', $accessory);
|
||||
|
||||
if (!$user = User::find(Input::get('assigned_to'))) {
|
||||
return redirect()->route('checkout/accessory', $accessory->id)->with('error', trans('admin/accessories/message.checkout.user_does_not_exist'));
|
||||
}
|
||||
|
||||
// Update the accessory data
|
||||
$accessory->assigned_to = e(Input::get('assigned_to'));
|
||||
|
||||
$accessory->users()->attach($accessory->id, [
|
||||
'accessory_id' => $accessory->id,
|
||||
'created_at' => Carbon::now(),
|
||||
'user_id' => Auth::id(),
|
||||
'assigned_to' => $request->get('assigned_to')
|
||||
]);
|
||||
|
||||
DB::table('accessories_users')->where('assigned_to', '=', $accessory->assigned_to)->where('accessory_id', '=', $accessory->id)->first();
|
||||
|
||||
event(new CheckoutableCheckedOut($accessory, $user, Auth::user(), $request->input('note')));
|
||||
|
||||
// Redirect to the new accessory page
|
||||
return redirect()->route('accessories.index')->with('success', trans('admin/accessories/message.checkout.success'));
|
||||
}
|
||||
}
|
|
@ -1,400 +0,0 @@
|
|||
<?php
|
||||
namespace App\Http\Controllers;
|
||||
|
||||
use App\Helpers\Helper;
|
||||
use App\Models\Accessory;
|
||||
use App\Models\Company;
|
||||
use App\Models\User;
|
||||
use Auth;
|
||||
use Carbon\Carbon;
|
||||
use Config;
|
||||
use DB;
|
||||
use Gate;
|
||||
use Input;
|
||||
use Lang;
|
||||
use Redirect;
|
||||
use Illuminate\Http\Request;
|
||||
use Slack;
|
||||
use Str;
|
||||
use View;
|
||||
use Image;
|
||||
use App\Http\Requests\ImageUploadRequest;
|
||||
|
||||
/** This controller handles all actions related to Accessories for
|
||||
* the Snipe-IT Asset Management application.
|
||||
*
|
||||
* @version v1.0
|
||||
*/
|
||||
class AccessoriesController extends Controller
|
||||
{
|
||||
|
||||
/**
|
||||
* Returns a view that invokes the ajax tables which actually contains
|
||||
* the content for the accessories listing, which is generated in getDatatable.
|
||||
*
|
||||
* @author [A. Gianotto] [<snipe@snipe.net>]
|
||||
* @see AccessoriesController::getDatatable() method that generates the JSON response
|
||||
* @since [v1.0]
|
||||
* @return View
|
||||
*/
|
||||
public function index(Request $request)
|
||||
{
|
||||
$this->authorize('index', Accessory::class);
|
||||
return view('accessories/index');
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Returns a view with a form to create a new Accessory.
|
||||
*
|
||||
* @author [A. Gianotto] [<snipe@snipe.net>]
|
||||
* @return View
|
||||
*/
|
||||
public function create(Request $request)
|
||||
{
|
||||
$this->authorize('create', Accessory::class);
|
||||
$category_type = 'accessory';
|
||||
return view('accessories/edit')->with('category_type', $category_type)
|
||||
->with('item', new Accessory);
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Validate and save new Accessory from form post
|
||||
*
|
||||
* @author [A. Gianotto] [<snipe@snipe.net>]
|
||||
* @return Redirect
|
||||
*/
|
||||
public function store(ImageUploadRequest $request)
|
||||
{
|
||||
$this->authorize(Accessory::class);
|
||||
// create a new model instance
|
||||
$accessory = new Accessory();
|
||||
|
||||
// Update the accessory data
|
||||
$accessory->name = request('name');
|
||||
$accessory->category_id = request('category_id');
|
||||
$accessory->location_id = request('location_id');
|
||||
$accessory->min_amt = request('min_amt');
|
||||
$accessory->company_id = Company::getIdForCurrentUser(request('company_id'));
|
||||
$accessory->order_number = request('order_number');
|
||||
$accessory->manufacturer_id = request('manufacturer_id');
|
||||
$accessory->model_number = request('model_number');
|
||||
$accessory->purchase_date = request('purchase_date');
|
||||
$accessory->purchase_cost = Helper::ParseFloat(request('purchase_cost'));
|
||||
$accessory->qty = request('qty');
|
||||
$accessory->user_id = Auth::user()->id;
|
||||
$accessory->supplier_id = request('supplier_id');
|
||||
|
||||
if ($request->hasFile('image')) {
|
||||
|
||||
if (!config('app.lock_passwords')) {
|
||||
$image = $request->file('image');
|
||||
$ext = $image->getClientOriginalExtension();
|
||||
$file_name = "accessory-".str_random(18).'.'.$ext;
|
||||
$path = public_path('/uploads/accessories');
|
||||
if ($image->getClientOriginalExtension()!='svg') {
|
||||
Image::make($image->getRealPath())->resize(null, 800, function ($constraint) {
|
||||
$constraint->aspectRatio();
|
||||
$constraint->upsize();
|
||||
})->save($path.'/'.$file_name);
|
||||
} else {
|
||||
$image->move($path, $file_name);
|
||||
}
|
||||
$accessory->image = $file_name;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
||||
// Was the accessory created?
|
||||
if ($accessory->save()) {
|
||||
// Redirect to the new accessory page
|
||||
return redirect()->route('accessories.index')->with('success', trans('admin/accessories/message.create.success'));
|
||||
}
|
||||
return redirect()->back()->withInput()->withErrors($accessory->getErrors());
|
||||
}
|
||||
|
||||
/**
|
||||
* Return view for the Accessory update form, prepopulated with existing data
|
||||
*
|
||||
* @author [A. Gianotto] [<snipe@snipe.net>]
|
||||
* @param int $accessoryId
|
||||
* @return View
|
||||
*/
|
||||
public function edit(Request $request, $accessoryId = null)
|
||||
{
|
||||
|
||||
if ($item = Accessory::find($accessoryId)) {
|
||||
$this->authorize($item);
|
||||
$category_type = 'accessory';
|
||||
return view('accessories/edit', compact('item'))->with('category_type', $category_type);
|
||||
}
|
||||
|
||||
return redirect()->route('accessories.index')->with('error', trans('admin/accessories/message.does_not_exist'));
|
||||
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Save edited Accessory from form post
|
||||
*
|
||||
* @author [A. Gianotto] [<snipe@snipe.net>]
|
||||
* @param int $accessoryId
|
||||
* @return Redirect
|
||||
*/
|
||||
public function update(ImageUploadRequest $request, $accessoryId = null)
|
||||
{
|
||||
if (is_null($accessory = Accessory::find($accessoryId))) {
|
||||
return redirect()->route('accessories.index')->with('error', trans('admin/accessories/message.does_not_exist'));
|
||||
}
|
||||
|
||||
$this->authorize($accessory);
|
||||
|
||||
// Update the accessory data
|
||||
$accessory->name = request('name');
|
||||
$accessory->location_id = request('location_id');
|
||||
$accessory->min_amt = request('min_amt');
|
||||
$accessory->category_id = request('category_id');
|
||||
$accessory->company_id = Company::getIdForCurrentUser(request('company_id'));
|
||||
$accessory->manufacturer_id = request('manufacturer_id');
|
||||
$accessory->order_number = request('order_number');
|
||||
$accessory->model_number = request('model_number');
|
||||
$accessory->purchase_date = request('purchase_date');
|
||||
$accessory->purchase_cost = request('purchase_cost');
|
||||
$accessory->qty = request('qty');
|
||||
$accessory->supplier_id = request('supplier_id');
|
||||
|
||||
if ($request->hasFile('image')) {
|
||||
|
||||
if (!config('app.lock_passwords')) {
|
||||
$image = $request->file('image');
|
||||
$ext = $image->getClientOriginalExtension();
|
||||
$file_name = "accessory-".str_random(18).'.'.$ext;
|
||||
$path = public_path('/uploads/accessories');
|
||||
if ($image->getClientOriginalExtension()!='svg') {
|
||||
Image::make($image->getRealPath())->resize(null, 800, function ($constraint) {
|
||||
$constraint->aspectRatio();
|
||||
$constraint->upsize();
|
||||
})->save($path.'/'.$file_name);
|
||||
} else {
|
||||
$image->move($path, $file_name);
|
||||
}
|
||||
if (($accessory->image) && (file_exists($path.'/'.$accessory->image))) {
|
||||
unlink($path.'/'.$accessory->image);
|
||||
}
|
||||
|
||||
$accessory->image = $file_name;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
// Was the accessory updated?
|
||||
if ($accessory->save()) {
|
||||
return redirect()->route('accessories.index')->with('success', trans('admin/accessories/message.update.success'));
|
||||
}
|
||||
return redirect()->back()->withInput()->withErrors($accessory->getErrors());
|
||||
}
|
||||
|
||||
/**
|
||||
* Delete the given accessory.
|
||||
*
|
||||
* @author [A. Gianotto] [<snipe@snipe.net>]
|
||||
* @param int $accessoryId
|
||||
* @return Redirect
|
||||
*/
|
||||
public function destroy(Request $request, $accessoryId)
|
||||
{
|
||||
if (is_null($accessory = Accessory::find($accessoryId))) {
|
||||
return redirect()->route('accessories.index')->with('error', trans('admin/accessories/message.not_found'));
|
||||
}
|
||||
|
||||
$this->authorize($accessory);
|
||||
|
||||
|
||||
if ($accessory->hasUsers() > 0) {
|
||||
return redirect()->route('accessories.index')->with('error', trans('admin/accessories/message.assoc_users', array('count'=> $accessory->hasUsers())));
|
||||
}
|
||||
$accessory->delete();
|
||||
return redirect()->route('accessories.index')->with('success', trans('admin/accessories/message.delete.success'));
|
||||
}
|
||||
|
||||
|
||||
|
||||
/**
|
||||
* Returns a view that invokes the ajax table which contains
|
||||
* the content for the accessory detail view, which is generated in getDataView.
|
||||
*
|
||||
* @author [A. Gianotto] [<snipe@snipe.net>]
|
||||
* @param int $accessoryID
|
||||
* @see AccessoriesController::getDataView() method that generates the JSON response
|
||||
* @since [v1.0]
|
||||
* @return View
|
||||
*/
|
||||
public function show(Request $request, $accessoryID = null)
|
||||
{
|
||||
$accessory = Accessory::find($accessoryID);
|
||||
$this->authorize('view', $accessory);
|
||||
if (isset($accessory->id)) {
|
||||
return view('accessories/view', compact('accessory'));
|
||||
}
|
||||
return redirect()->route('accessories.index')->with('error', trans('admin/accessories/message.does_not_exist', compact('id')));
|
||||
}
|
||||
|
||||
/**
|
||||
* Return the form to checkout an Accessory to a user.
|
||||
*
|
||||
* @author [A. Gianotto] [<snipe@snipe.net>]
|
||||
* @param int $accessoryId
|
||||
* @return View
|
||||
*/
|
||||
public function getCheckout(Request $request, $accessoryId)
|
||||
{
|
||||
// Check if the accessory exists
|
||||
if (is_null($accessory = Accessory::find($accessoryId))) {
|
||||
// Redirect to the accessory management page with error
|
||||
return redirect()->route('accessories.index')->with('error', trans('admin/accessories/message.not_found'));
|
||||
}
|
||||
|
||||
if ($accessory->category) {
|
||||
|
||||
$this->authorize('checkout', $accessory);
|
||||
|
||||
// Get the dropdown of users and then pass it to the checkout view
|
||||
return view('accessories/checkout', compact('accessory'));
|
||||
}
|
||||
|
||||
return redirect()->back()->with('error', 'The category type for this accessory is not valid. Edit the accessory and select a valid accessory category.');
|
||||
|
||||
|
||||
|
||||
}
|
||||
|
||||
/**
|
||||
* Save the Accessory checkout information.
|
||||
*
|
||||
* If Slack is enabled and/or asset acceptance is enabled, it will also
|
||||
* trigger a Slack message and send an email.
|
||||
*
|
||||
* @author [A. Gianotto] [<snipe@snipe.net>]
|
||||
* @param int $accessoryId
|
||||
* @return Redirect
|
||||
*/
|
||||
public function postCheckout(Request $request, $accessoryId)
|
||||
{
|
||||
// Check if the accessory exists
|
||||
if (is_null($accessory = Accessory::find($accessoryId))) {
|
||||
// Redirect to the accessory management page with error
|
||||
return redirect()->route('accessories.index')->with('error', trans('admin/accessories/message.user_not_found'));
|
||||
}
|
||||
|
||||
$this->authorize('checkout', $accessory);
|
||||
|
||||
if (!$user = User::find(Input::get('assigned_to'))) {
|
||||
return redirect()->route('checkout/accessory', $accessory->id)->with('error', trans('admin/accessories/message.checkout.user_does_not_exist'));
|
||||
}
|
||||
|
||||
// Update the accessory data
|
||||
$accessory->assigned_to = e(Input::get('assigned_to'));
|
||||
|
||||
$accessory->users()->attach($accessory->id, [
|
||||
'accessory_id' => $accessory->id,
|
||||
'created_at' => Carbon::now(),
|
||||
'user_id' => Auth::id(),
|
||||
'assigned_to' => $request->get('assigned_to')
|
||||
]);
|
||||
|
||||
$logaction = $accessory->logCheckout(e(Input::get('note')), $user);
|
||||
|
||||
DB::table('accessories_users')->where('assigned_to', '=', $accessory->assigned_to)->where('accessory_id', '=', $accessory->id)->first();
|
||||
|
||||
$data['log_id'] = $logaction->id;
|
||||
$data['eula'] = $accessory->getEula();
|
||||
$data['first_name'] = $user->first_name;
|
||||
$data['item_name'] = $accessory->name;
|
||||
$data['checkout_date'] = $logaction->created_at;
|
||||
$data['item_tag'] = '';
|
||||
$data['expected_checkin'] = '';
|
||||
$data['note'] = $logaction->note;
|
||||
$data['require_acceptance'] = $accessory->requireAcceptance();
|
||||
|
||||
// Redirect to the new accessory page
|
||||
return redirect()->route('accessories.index')->with('success', trans('admin/accessories/message.checkout.success'));
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Check the accessory back into inventory
|
||||
*
|
||||
* @author [A. Gianotto] [<snipe@snipe.net>]
|
||||
* @param Request $request
|
||||
* @param integer $accessoryUserId
|
||||
* @param string $backto
|
||||
* @return View
|
||||
* @internal param int $accessoryId
|
||||
*/
|
||||
public function getCheckin(Request $request, $accessoryUserId = null, $backto = null)
|
||||
{
|
||||
// Check if the accessory exists
|
||||
if (is_null($accessory_user = DB::table('accessories_users')->find($accessoryUserId))) {
|
||||
// Redirect to the accessory management page with error
|
||||
return redirect()->route('accessories.index')->with('error', trans('admin/accessories/message.not_found'));
|
||||
}
|
||||
|
||||
$accessory = Accessory::find($accessory_user->accessory_id);
|
||||
$this->authorize('checkin', $accessory);
|
||||
return view('accessories/checkin', compact('accessory'))->with('backto', $backto);
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Check in the item so that it can be checked out again to someone else
|
||||
*
|
||||
* @uses Accessory::checkin_email() to determine if an email can and should be sent
|
||||
* @author [A. Gianotto] [<snipe@snipe.net>]
|
||||
* @param Request $request
|
||||
* @param integer $accessoryUserId
|
||||
* @param string $backto
|
||||
* @return Redirect
|
||||
* @internal param int $accessoryId
|
||||
*/
|
||||
public function postCheckin(Request $request, $accessoryUserId = null, $backto = null)
|
||||
{
|
||||
// Check if the accessory exists
|
||||
if (is_null($accessory_user = DB::table('accessories_users')->find($accessoryUserId))) {
|
||||
// Redirect to the accessory management page with error
|
||||
return redirect()->route('accessories.index')->with('error', trans('admin/accessories/message.does_not_exist'));
|
||||
}
|
||||
|
||||
$accessory = Accessory::find($accessory_user->accessory_id);
|
||||
|
||||
$this->authorize('checkin', $accessory);
|
||||
|
||||
$return_to = e($accessory_user->assigned_to);
|
||||
$logaction = $accessory->logCheckin(User::find($return_to), e(Input::get('note')));
|
||||
|
||||
// Was the accessory updated?
|
||||
if (DB::table('accessories_users')->where('id', '=', $accessory_user->id)->delete()) {
|
||||
if (!is_null($accessory_user->assigned_to)) {
|
||||
$user = User::find($accessory_user->assigned_to);
|
||||
}
|
||||
|
||||
$data['log_id'] = $logaction->id;
|
||||
$data['first_name'] = e($user->first_name);
|
||||
$data['last_name'] = e($user->last_name);
|
||||
$data['item_name'] = e($accessory->name);
|
||||
$data['checkin_date'] = e($logaction->created_at);
|
||||
$data['item_tag'] = '';
|
||||
$data['note'] = e($logaction->note);
|
||||
|
||||
if ($backto=='user') {
|
||||
return redirect()->route("users.show", $return_to)->with('success', trans('admin/accessories/message.checkin.success'));
|
||||
}
|
||||
return redirect()->route("accessories.show", $accessory->id)->with('success', trans('admin/accessories/message.checkin.success'));
|
||||
}
|
||||
// Redirect to the accessory management page with error
|
||||
return redirect()->route('accessories.index')->with('error', trans('admin/accessories/message.checkin.error'));
|
||||
}
|
||||
|
||||
|
||||
}
|
127
app/Http/Controllers/Account/AcceptanceController.php
Normal file
127
app/Http/Controllers/Account/AcceptanceController.php
Normal file
|
@ -0,0 +1,127 @@
|
|||
<?php
|
||||
namespace App\Http\Controllers\Account;
|
||||
|
||||
use App\Events\CheckoutAccepted;
|
||||
use App\Events\CheckoutDeclined;
|
||||
use App\Events\ItemAccepted;
|
||||
use App\Events\ItemDeclined;
|
||||
use App\Http\Controllers\Controller;
|
||||
use App\Models\CheckoutAcceptance;
|
||||
use App\Models\Company;
|
||||
use App\Models\Contracts\Acceptable;
|
||||
use Illuminate\Http\Request;
|
||||
use Illuminate\Support\Facades\Auth;
|
||||
use Illuminate\Support\Facades\Storage;
|
||||
use Illuminate\Support\Str;
|
||||
|
||||
class AcceptanceController extends Controller {
|
||||
|
||||
/**
|
||||
* Show a listing of pending checkout acceptances for the current user
|
||||
*
|
||||
* @return View
|
||||
*/
|
||||
public function index() {
|
||||
$acceptances = CheckoutAcceptance::forUser(Auth::user())->pending()->get();
|
||||
|
||||
return view('account/accept.index', compact('acceptances'));
|
||||
}
|
||||
|
||||
/**
|
||||
* Shows a form to either accept or decline the checkout acceptance
|
||||
*
|
||||
* @param int $id
|
||||
* @return mixed
|
||||
*/
|
||||
public function create($id) {
|
||||
|
||||
$acceptance = CheckoutAcceptance::find($id);
|
||||
|
||||
if (is_null($acceptance)) {
|
||||
return redirect()->route('account.accept')->with('error', trans('admin/hardware/message.does_not_exist'));
|
||||
}
|
||||
|
||||
if (! $acceptance->isPending()) {
|
||||
return redirect()->route('account.accept')->with('error', trans('admin/users/message.error.asset_already_accepted'));
|
||||
}
|
||||
|
||||
if (! $acceptance->isCheckedOutTo(Auth::user())) {
|
||||
return redirect()->route('account.accept')->with('error', trans('admin/users/message.error.incorrect_user_accepted'));
|
||||
}
|
||||
|
||||
if (!Company::isCurrentUserHasAccess($acceptance->checkoutable)) {
|
||||
return redirect()->route('account.accept')->with('error', trans('general.insufficient_permissions'));
|
||||
}
|
||||
|
||||
return view('account/accept.create', compact('acceptance'));
|
||||
}
|
||||
|
||||
/**
|
||||
* Stores the accept/decline of the checkout acceptance
|
||||
*
|
||||
* @param Request $request
|
||||
* @param int $id
|
||||
* @return Redirect
|
||||
*/
|
||||
public function store(Request $request, $id) {
|
||||
|
||||
$acceptance = CheckoutAcceptance::find($id);
|
||||
|
||||
if (is_null($acceptance)) {
|
||||
return redirect()->route('account.accept')->with('error', trans('admin/hardware/message.does_not_exist'));
|
||||
}
|
||||
|
||||
if (! $acceptance->isPending()) {
|
||||
return redirect()->route('account.accept')->with('error', trans('admin/users/message.error.asset_already_accepted'));
|
||||
}
|
||||
|
||||
if (! $acceptance->isCheckedOutTo(Auth::user())) {
|
||||
return redirect()->route('account.accept')->with('error', trans('admin/users/message.error.incorrect_user_accepted'));
|
||||
}
|
||||
|
||||
if (!Company::isCurrentUserHasAccess($acceptance->checkoutable)) {
|
||||
return redirect()->route('account.accept')->with('error', trans('general.insufficient_permissions'));
|
||||
}
|
||||
|
||||
if (!$request->filled('asset_acceptance')) {
|
||||
return redirect()->back()->with('error', trans('admin/users/message.error.accept_or_decline'));
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the signature and save it
|
||||
*/
|
||||
|
||||
if (!Storage::exists('private_uploads/signatures')) Storage::makeDirectory('private_uploads/signatures', 775);
|
||||
|
||||
|
||||
|
||||
if ($request->filled('signature_output')) {
|
||||
$sig_filename = "siglog-" .Str::uuid() . '-'.date('Y-m-d-his').".png";
|
||||
$data_uri = e($request->input('signature_output'));
|
||||
$encoded_image = explode(",", $data_uri);
|
||||
$decoded_image = base64_decode($encoded_image[1]);
|
||||
Storage::put('private_uploads/signatures/'.$sig_filename, (string)$decoded_image);
|
||||
}
|
||||
|
||||
|
||||
if ($request->input('asset_acceptance') == 'accepted') {
|
||||
|
||||
$acceptance->accept($sig_filename);
|
||||
|
||||
event(new CheckoutAccepted($acceptance));
|
||||
|
||||
$return_msg = trans('admin/users/message.accepted');
|
||||
|
||||
} else {
|
||||
|
||||
$acceptance->decline($sig_filename);
|
||||
|
||||
event(new CheckoutDeclined($acceptance));
|
||||
|
||||
$return_msg = trans('admin/users/message.declined');
|
||||
|
||||
}
|
||||
|
||||
return redirect()->to('account/accept')->with('success', $return_msg);
|
||||
}
|
||||
}
|
|
@ -2,16 +2,17 @@
|
|||
|
||||
namespace App\Http\Controllers\Api;
|
||||
|
||||
use Illuminate\Http\Request;
|
||||
use App\Http\Controllers\Controller;
|
||||
use App\Helpers\Helper;
|
||||
use App\Models\Accessory;
|
||||
use App\Http\Controllers\Controller;
|
||||
use App\Http\Transformers\AccessoriesTransformer;
|
||||
use App\Http\Transformers\SelectlistTransformer;
|
||||
use App\Models\Accessory;
|
||||
use App\Models\Company;
|
||||
use App\Models\User;
|
||||
use Carbon\Carbon;
|
||||
use Auth;
|
||||
use DB;
|
||||
use Illuminate\Http\Request;
|
||||
|
||||
class AccessoriesController extends Controller
|
||||
{
|
||||
|
@ -139,18 +140,37 @@ class AccessoriesController extends Controller
|
|||
* @param int $id
|
||||
* @return \Illuminate\Http\Response
|
||||
*/
|
||||
public function checkedout($id)
|
||||
public function checkedout($id, Request $request)
|
||||
{
|
||||
$this->authorize('view', Accessory::class);
|
||||
|
||||
$accessory = Accessory::findOrFail($id);
|
||||
$accessory = Accessory::with('lastCheckout')->findOrFail($id);
|
||||
if (!Company::isCurrentUserHasAccess($accessory)) {
|
||||
return ['total' => 0, 'rows' => []];
|
||||
}
|
||||
|
||||
$offset = request('offset', 0);
|
||||
$limit = request('limit', 50);
|
||||
|
||||
$accessory->lastCheckoutArray = $accessory->lastCheckout->toArray();
|
||||
$accessory_users = $accessory->users;
|
||||
$total = $accessory_users->count();
|
||||
|
||||
return (new AccessoriesTransformer)->transformCheckedoutAccessory($accessory_users, $total);
|
||||
if($total < $offset){
|
||||
$offset = 0;
|
||||
}
|
||||
|
||||
$accessory_users = $accessory->users()->skip($offset)->take($limit)->get();
|
||||
|
||||
if ($request->filled('search')) {
|
||||
$accessory_users = $accessory->users()
|
||||
->where('first_name', 'like', '%'.$request->input('search').'%')
|
||||
->orWhere('last_name', 'like', '%'.$request->input('search').'%')
|
||||
->get();
|
||||
$total = $accessory_users->count();
|
||||
}
|
||||
|
||||
return (new AccessoriesTransformer)->transformCheckedoutAccessory($accessory, $accessory_users, $total);
|
||||
}
|
||||
|
||||
|
||||
|
@ -165,7 +185,7 @@ class AccessoriesController extends Controller
|
|||
*/
|
||||
public function update(Request $request, $id)
|
||||
{
|
||||
$this->authorize('edit', Accessory::class);
|
||||
$this->authorize('update', Accessory::class);
|
||||
$accessory = Accessory::findOrFail($id);
|
||||
$accessory->fill($request->all());
|
||||
|
||||
|
@ -288,4 +308,31 @@ class AccessoriesController extends Controller
|
|||
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Gets a paginated collection for the select2 menus
|
||||
*
|
||||
* @see \App\Http\Transformers\SelectlistTransformer
|
||||
*
|
||||
*/
|
||||
public function selectlist(Request $request)
|
||||
{
|
||||
|
||||
$accessories = Accessory::select([
|
||||
'accessories.id',
|
||||
'accessories.name'
|
||||
]);
|
||||
|
||||
if ($request->filled('search')) {
|
||||
$accessories = $accessories->where('accessories.name', 'LIKE', '%'.$request->get('search').'%');
|
||||
}
|
||||
|
||||
$accessories = $accessories->orderBy('name', 'ASC')->paginate(50);
|
||||
|
||||
|
||||
return (new SelectlistTransformer)->transformSelectlist($accessories);
|
||||
}
|
||||
|
||||
|
||||
|
||||
}
|
||||
|
|
|
@ -9,7 +9,6 @@ use App\Models\AssetMaintenance;
|
|||
use App\Models\Company;
|
||||
use Auth;
|
||||
use Carbon\Carbon;
|
||||
use Gate;
|
||||
use Illuminate\Http\Request;
|
||||
use Illuminate\Support\Facades\Input;
|
||||
|
||||
|
@ -34,10 +33,10 @@ class AssetMaintenancesController extends Controller
|
|||
*/
|
||||
public function index(Request $request)
|
||||
{
|
||||
$maintenances = AssetMaintenance::with('asset', 'supplier', 'asset.company', 'admin');
|
||||
$maintenances = AssetMaintenance::with('asset', 'asset.model','asset.location', 'supplier', 'asset.company', 'admin');
|
||||
|
||||
if (Input::has('search')) {
|
||||
$maintenances = $maintenances->TextSearch(e($request->input('search')));
|
||||
if ($request->filled('search')) {
|
||||
$maintenances = $maintenances->TextSearch($request->input('search'));
|
||||
}
|
||||
|
||||
if ($request->filled('asset_id')) {
|
||||
|
|
|
@ -1,15 +1,15 @@
|
|||
<?php
|
||||
namespace App\Http\Controllers\Api;
|
||||
|
||||
use App\Models\AssetModel;
|
||||
use App\Models\Asset;
|
||||
use App\Http\Controllers\Controller;
|
||||
use App\Helpers\Helper;
|
||||
use Illuminate\Http\Request;
|
||||
use App\Http\Controllers\Controller;
|
||||
use App\Http\Transformers\AssetModelsTransformer;
|
||||
use App\Http\Transformers\AssetsTransformer;
|
||||
use App\Http\Transformers\SelectlistTransformer;
|
||||
|
||||
use App\Models\Asset;
|
||||
use App\Models\AssetModel;
|
||||
use Illuminate\Http\Request;
|
||||
use Illuminate\Support\Facades\Storage;
|
||||
|
||||
/**
|
||||
* This class controls all actions related to asset models for
|
||||
|
@ -180,7 +180,7 @@ class AssetModelsController extends Controller
|
|||
|
||||
if ($assetmodel->image) {
|
||||
try {
|
||||
unlink(public_path().'/uploads/models/'.$assetmodel->image);
|
||||
Storage::disk('public')->delete('assetmodels/'.$assetmodel->image);
|
||||
} catch (\Exception $e) {
|
||||
\Log::info($e);
|
||||
}
|
||||
|
@ -237,7 +237,7 @@ class AssetModelsController extends Controller
|
|||
$assetmodel->use_text .= ' (#'.e($assetmodel->model_number).')';
|
||||
}
|
||||
|
||||
$assetmodel->use_image = ($settings->modellistCheckedValue('image') && ($assetmodel->image)) ? url('/').'/uploads/models/'.$assetmodel->image : null;
|
||||
$assetmodel->use_image = ($settings->modellistCheckedValue('image') && ($assetmodel->image)) ? Storage::disk('public')->url('assetmodels/'.e($assetmodel->image)) : null;
|
||||
}
|
||||
|
||||
return (new SelectlistTransformer)->transformSelectlist($assetmodels);
|
||||
|
|
|
@ -1,38 +1,31 @@
|
|||
<?php
|
||||
namespace App\Http\Controllers\Api;
|
||||
|
||||
use Illuminate\Support\Facades\Gate;
|
||||
use App\Helpers\Helper;
|
||||
use App\Http\Controllers\Controller;
|
||||
use App\Http\Requests\AssetRequest;
|
||||
use App\Http\Requests\AssetCheckoutRequest;
|
||||
use App\Http\Transformers\AssetsTransformer;
|
||||
use App\Http\Transformers\LicensesTransformer;
|
||||
use App\Http\Transformers\SelectlistTransformer;
|
||||
use App\Models\Asset;
|
||||
use App\Models\AssetModel;
|
||||
use App\Models\Company;
|
||||
use App\Models\CustomField;
|
||||
use App\Models\License;
|
||||
use App\Models\Location;
|
||||
use App\Models\Setting;
|
||||
use App\Models\User;
|
||||
use Artisan;
|
||||
use Auth;
|
||||
use Carbon\Carbon;
|
||||
use Config;
|
||||
use DB;
|
||||
use Gate;
|
||||
use Illuminate\Http\Request;
|
||||
use Input;
|
||||
use Lang;
|
||||
use Log;
|
||||
use Mail;
|
||||
use Paginator;
|
||||
use Response;
|
||||
use Slack;
|
||||
use Str;
|
||||
use TCPDF;
|
||||
use Validator;
|
||||
use View;
|
||||
use App\Http\Transformers\SelectlistTransformer;
|
||||
|
||||
|
||||
/**
|
||||
* This class controls all actions related to assets for
|
||||
|
@ -173,7 +166,7 @@ class AssetsController extends Controller
|
|||
// I am sad. :(
|
||||
switch ($request->input('status')) {
|
||||
case 'Deleted':
|
||||
$assets->withTrashed()->Deleted();
|
||||
$assets->onlyTrashed();
|
||||
break;
|
||||
case 'Pending':
|
||||
$assets->join('status_labels AS status_alias',function ($join) {
|
||||
|
@ -288,9 +281,9 @@ class AssetsController extends Controller
|
|||
break;
|
||||
}
|
||||
|
||||
|
||||
$total = $assets->count();
|
||||
$assets = $assets->skip($offset)->take($limit)->get();
|
||||
// dd($assets);
|
||||
return (new AssetsTransformer)->transformAssets($assets, $total);
|
||||
}
|
||||
|
||||
|
@ -305,7 +298,7 @@ class AssetsController extends Controller
|
|||
*/
|
||||
public function showByTag($tag)
|
||||
{
|
||||
if ($asset = Asset::with('assetstatus')->with('assignedTo')->withTrashed()->where('asset_tag',$tag)->first()) {
|
||||
if ($asset = Asset::with('assetstatus')->with('assignedTo')->where('asset_tag',$tag)->first()) {
|
||||
$this->authorize('view', $asset);
|
||||
return (new AssetsTransformer)->transformAsset($asset);
|
||||
}
|
||||
|
@ -326,8 +319,7 @@ class AssetsController extends Controller
|
|||
$this->authorize('index', Asset::class);
|
||||
if ($assets = Asset::with('assetstatus')->with('assignedTo')
|
||||
->withTrashed()->where('serial',$serial)->get()) {
|
||||
|
||||
return (new AssetsTransformer)->transformAssets($assets, $assets->count());
|
||||
return (new AssetsTransformer)->transformAssets($assets, $assets->count());
|
||||
}
|
||||
return response()->json(Helper::formatStandardApiResponse('error', null, 'Asset not found'), 200);
|
||||
|
||||
|
@ -344,14 +336,22 @@ class AssetsController extends Controller
|
|||
*/
|
||||
public function show($id)
|
||||
{
|
||||
if ($asset = Asset::with('assetstatus')->with('assignedTo')->withTrashed()->withCount('checkins as checkins_count', 'checkouts as checkouts_count', 'userRequests as userRequests_count')->findOrFail($id)) {
|
||||
if ($asset = Asset::with('assetstatus')->with('assignedTo')->withTrashed()
|
||||
->withCount('checkins as checkins_count', 'checkouts as checkouts_count', 'userRequests as user_requests_count')->findOrFail($id)) {
|
||||
$this->authorize('view', $asset);
|
||||
return (new AssetsTransformer)->transformAsset($asset);
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
|
||||
public function licenses($id)
|
||||
{
|
||||
$this->authorize('view', Asset::class);
|
||||
$this->authorize('view', License::class);
|
||||
$asset = Asset::where('id', $id)->withTrashed()->first();
|
||||
$licenses = $asset->licenses()->get();
|
||||
return (new LicensesTransformer())->transformLicenses($licenses, $licenses->count());
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets a paginated collection for the select2 menus
|
||||
|
@ -372,7 +372,7 @@ class AssetsController extends Controller
|
|||
'assets.assigned_to',
|
||||
'assets.assigned_type',
|
||||
'assets.status_id'
|
||||
])->with('model', 'assetstatus', 'assignedTo')->NotArchived(),'company_id', 'assets');
|
||||
])->with('model', 'assetstatus', 'assignedTo')->NotArchived(), 'company_id', 'assets');
|
||||
|
||||
if ($request->filled('assetStatusType') && $request->input('assetStatusType') === 'RTD') {
|
||||
$assets = $assets->RTD();
|
||||
|
@ -418,7 +418,7 @@ class AssetsController extends Controller
|
|||
* @since [v4.0]
|
||||
* @return JsonResponse
|
||||
*/
|
||||
public function store(AssetRequest $request)
|
||||
public function store(Request $request)
|
||||
{
|
||||
|
||||
$this->authorize('create', Asset::class);
|
||||
|
@ -446,6 +446,22 @@ class AssetsController extends Controller
|
|||
$asset->requestable = $request->get('requestable', 0);
|
||||
$asset->rtd_location_id = $request->get('rtd_location_id', null);
|
||||
|
||||
if ($request->has('image_source') && $request->input('image_source') != "") {
|
||||
$saved_image_path = Helper::processUploadedImage(
|
||||
$request->input('image_source'), 'uploads/assets/'
|
||||
);
|
||||
|
||||
if (!$saved_image_path) {
|
||||
return response()->json(Helper::formatStandardApiResponse(
|
||||
'error',
|
||||
null,
|
||||
trans('admin/hardware/message.create.error')
|
||||
), 200);
|
||||
}
|
||||
|
||||
$asset->image = $saved_image_path;
|
||||
}
|
||||
|
||||
// Update custom fields in the database.
|
||||
// Validation for these fields is handled through the AssetRequest form request
|
||||
$model = AssetModel::find($request->get('model_id'));
|
||||
|
@ -473,6 +489,11 @@ class AssetsController extends Controller
|
|||
if (isset($target)) {
|
||||
$asset->checkOut($target, Auth::user(), date('Y-m-d H:i:s'), '', 'Checked out on asset creation', e($request->get('name')));
|
||||
}
|
||||
|
||||
if ($asset->image) {
|
||||
$asset->image = $asset->getImageUrl();
|
||||
}
|
||||
|
||||
return response()->json(Helper::formatStandardApiResponse('success', $asset, trans('admin/hardware/message.create.success')));
|
||||
}
|
||||
|
||||
|
@ -493,15 +514,40 @@ class AssetsController extends Controller
|
|||
$this->authorize('update', Asset::class);
|
||||
|
||||
if ($asset = Asset::find($id)) {
|
||||
|
||||
$asset->fill($request->all());
|
||||
|
||||
($request->filled('model_id')) ?
|
||||
$asset->model()->associate(AssetModel::find($request->get('model_id'))) : null;
|
||||
($request->filled('rtd_location_id')) ?
|
||||
$asset->location_id = $request->get('rtd_location_id') : '';
|
||||
($request->filled('company_id')) ?
|
||||
$asset->company_id = Company::getIdForCurrentUser($request->get('company_id')) : null;
|
||||
$asset->company_id = Company::getIdForCurrentUser($request->get('company_id')) : '';
|
||||
|
||||
($request->filled('rtd_location_id')) ?
|
||||
$asset->location_id = $request->get('rtd_location_id') : null;
|
||||
|
||||
|
||||
if ($request->filled('image_source')) {
|
||||
if ($request->input('image_source') == "") {
|
||||
($request->filled('rtd_location_id')) ?
|
||||
$asset->location_id = $request->get('rtd_location_id') : null;
|
||||
$asset->image = null;
|
||||
} else {
|
||||
$saved_image_path = Helper::processUploadedImage(
|
||||
$request->input('image_source'), 'uploads/assets/'
|
||||
);
|
||||
|
||||
if (!$saved_image_path) {
|
||||
return response()->json(Helper::formatStandardApiResponse(
|
||||
'error',
|
||||
null,
|
||||
trans('admin/hardware/message.update.error')
|
||||
), 200);
|
||||
}
|
||||
|
||||
$asset->image = $saved_image_path;
|
||||
}
|
||||
}
|
||||
|
||||
// Update custom fields
|
||||
if (($model = AssetModel::find($asset->model_id)) && (isset($model->fieldset))) {
|
||||
|
@ -522,9 +568,9 @@ class AssetsController extends Controller
|
|||
if ($asset->save()) {
|
||||
|
||||
if (($request->filled('assigned_user')) && ($target = User::find($request->get('assigned_user')))) {
|
||||
$location = $target->location_id;
|
||||
$location = $target->location_id;
|
||||
} elseif (($request->filled('assigned_asset')) && ($target = Asset::find($request->get('assigned_asset')))) {
|
||||
$location = $target->location_id;
|
||||
$location = $target->location_id;
|
||||
} elseif (($request->filled('assigned_location')) && ($target = Location::find($request->get('assigned_location')))) {
|
||||
$location = $target->id;
|
||||
}
|
||||
|
@ -533,6 +579,10 @@ class AssetsController extends Controller
|
|||
$asset->checkOut($target, Auth::user(), date('Y-m-d H:i:s'), '', 'Checked out on asset update', e($request->get('name')), $location);
|
||||
}
|
||||
|
||||
if ($asset->image) {
|
||||
$asset->image = $asset->getImageUrl();
|
||||
}
|
||||
|
||||
return response()->json(Helper::formatStandardApiResponse('success', $asset, trans('admin/hardware/message.update.success')));
|
||||
}
|
||||
return response()->json(Helper::formatStandardApiResponse('error', null, $asset->getErrors()), 200);
|
||||
|
@ -724,13 +774,27 @@ class AssetsController extends Controller
|
|||
return response()->json(Helper::formatStandardApiResponse('error', null, $validator->errors()->all()));
|
||||
}
|
||||
|
||||
$settings = Setting::getSettings();
|
||||
$dt = Carbon::now()->addMonths($settings->audit_interval)->toDateString();
|
||||
|
||||
$asset = Asset::where('asset_tag','=', $request->input('asset_tag'))->first();
|
||||
|
||||
|
||||
if ($asset) {
|
||||
// We don't want to log this as a normal update, so let's bypass that
|
||||
$asset->unsetEventDispatcher();
|
||||
$asset->next_audit_date = $request->input('next_audit_date');
|
||||
$asset->next_audit_date = $dt;
|
||||
|
||||
if ($request->filled('next_audit_date')) {
|
||||
$asset->next_audit_date = $request->input('next_audit_date');
|
||||
}
|
||||
|
||||
// Check to see if they checked the box to update the physical location,
|
||||
// not just note it in the audit notes
|
||||
if ($request->input('update_location')=='1') {
|
||||
$asset->location_id = $request->input('location_id');
|
||||
}
|
||||
|
||||
$asset->last_audit_date = date('Y-m-d h:i:s');
|
||||
|
||||
if ($asset->save()) {
|
||||
|
@ -738,7 +802,7 @@ class AssetsController extends Controller
|
|||
return response()->json(Helper::formatStandardApiResponse('success', [
|
||||
'asset_tag'=> e($asset->asset_tag),
|
||||
'note'=> e($request->input('note')),
|
||||
'next_audit_date' => Helper::getFormattedDateObject($log->calcNextAuditDate())
|
||||
'next_audit_date' => Helper::getFormattedDateObject($asset->next_audit_date)
|
||||
], trans('admin/hardware/message.audit.success')));
|
||||
}
|
||||
}
|
||||
|
|
|
@ -2,12 +2,13 @@
|
|||
|
||||
namespace App\Http\Controllers\Api;
|
||||
|
||||
use Illuminate\Http\Request;
|
||||
use App\Http\Controllers\Controller;
|
||||
use App\Helpers\Helper;
|
||||
use App\Models\Category;
|
||||
use App\Http\Controllers\Controller;
|
||||
use App\Http\Transformers\CategoriesTransformer;
|
||||
use App\Http\Transformers\SelectlistTransformer;
|
||||
use App\Models\Category;
|
||||
use Illuminate\Http\Request;
|
||||
use Illuminate\Support\Facades\Storage;
|
||||
|
||||
class CategoriesController extends Controller
|
||||
{
|
||||
|
@ -117,15 +118,15 @@ class CategoriesController extends Controller
|
|||
public function destroy($id)
|
||||
{
|
||||
$this->authorize('delete', Category::class);
|
||||
$category = Category::findOrFail($id);
|
||||
$category = Category::withCount('models as models_count', 'accessories as accessories_count','consumables as consumables_count','components as components_count')->findOrFail($id);
|
||||
|
||||
if ($category->has_models() > 0) {
|
||||
if ($category->models_count > 0) {
|
||||
return response()->json(Helper::formatStandardApiResponse('error', null, trans('admin/categories/message.assoc_items', ['asset_type'=>'model'])));
|
||||
} elseif ($category->accessories()->count() > 0) {
|
||||
} elseif ($category->accessories_count > 0) {
|
||||
return response()->json(Helper::formatStandardApiResponse('error', null, trans('admin/categories/message.assoc_items', ['asset_type'=>'accessory'])));
|
||||
} elseif ($category->consumables()->count() > 0) {
|
||||
} elseif ($category->consumables_count > 0) {
|
||||
return response()->json(Helper::formatStandardApiResponse('error', null, trans('admin/categories/message.assoc_items', ['asset_type'=>'consumable'])));
|
||||
} elseif ($category->components()->count() > 0) {
|
||||
} elseif ($category->components_count > 0) {
|
||||
return response()->json(Helper::formatStandardApiResponse('error', null, trans('admin/categories/message.assoc_items', ['asset_type'=>'component'])));
|
||||
}
|
||||
$category->delete();
|
||||
|
@ -161,7 +162,7 @@ class CategoriesController extends Controller
|
|||
// This lets us have more flexibility in special cases like assets, where
|
||||
// they may not have a ->name value but we want to display something anyway
|
||||
foreach ($categories as $category) {
|
||||
$category->use_image = ($category->image) ? url('/').'/uploads/categories/'.$category->image : null;
|
||||
$category->use_image = ($category->image) ? Storage::disk('public')->url('categories/'.$category->image, $category->image) : null;
|
||||
}
|
||||
|
||||
return (new SelectlistTransformer)->transformSelectlist($categories);
|
||||
|
|
|
@ -2,12 +2,13 @@
|
|||
|
||||
namespace App\Http\Controllers\Api;
|
||||
|
||||
use App\Http\Transformers\CompaniesTransformer;
|
||||
use Illuminate\Http\Request;
|
||||
use App\Http\Controllers\Controller;
|
||||
use App\Helpers\Helper;
|
||||
use App\Models\Company;
|
||||
use App\Http\Controllers\Controller;
|
||||
use App\Http\Transformers\CompaniesTransformer;
|
||||
use App\Http\Transformers\SelectlistTransformer;
|
||||
use App\Models\Company;
|
||||
use Illuminate\Http\Request;
|
||||
use Illuminate\Support\Facades\Storage;
|
||||
|
||||
class CompaniesController extends Controller
|
||||
{
|
||||
|
@ -181,7 +182,7 @@ class CompaniesController extends Controller
|
|||
// This lets us have more flexibility in special cases like assets, where
|
||||
// they may not have a ->name value but we want to display something anyway
|
||||
foreach ($companies as $company) {
|
||||
$company->use_image = ($company->image) ? url('/').'/uploads/companies/'.$company->image : null;
|
||||
$company->use_image = ($company->image) ? Storage::disk('public')->url('companies/'.$company->image, $company->image) : null;
|
||||
}
|
||||
|
||||
return (new SelectlistTransformer)->transformSelectlist($companies);
|
||||
|
|
|
@ -2,14 +2,12 @@
|
|||
|
||||
namespace App\Http\Controllers\Api;
|
||||
|
||||
use Illuminate\Http\Request;
|
||||
use App\Http\Controllers\Controller;
|
||||
use App\Http\Transformers\AssetsTransformer;
|
||||
use App\Http\Transformers\ComponentsTransformer;
|
||||
use App\Http\Transformers\ComponentsAssetsTransformer;
|
||||
use App\Models\Component;
|
||||
use App\Models\Company;
|
||||
use App\Helpers\Helper;
|
||||
use App\Http\Controllers\Controller;
|
||||
use App\Http\Transformers\ComponentsTransformer;
|
||||
use App\Models\Company;
|
||||
use App\Models\Component;
|
||||
use Illuminate\Http\Request;
|
||||
|
||||
class ComponentsController extends Controller
|
||||
{
|
||||
|
|
|
@ -2,12 +2,13 @@
|
|||
|
||||
namespace App\Http\Controllers\Api;
|
||||
|
||||
use Illuminate\Http\Request;
|
||||
use App\Helpers\Helper;
|
||||
use App\Http\Controllers\Controller;
|
||||
use App\Http\Transformers\ConsumablesTransformer;
|
||||
use App\Http\Transformers\SelectlistTransformer;
|
||||
use App\Models\Company;
|
||||
use App\Models\Consumable;
|
||||
use App\Http\Transformers\ConsumablesTransformer;
|
||||
use App\Helpers\Helper;
|
||||
use Illuminate\Http\Request;
|
||||
|
||||
class ConsumablesController extends Controller
|
||||
{
|
||||
|
@ -159,7 +160,7 @@ class ConsumablesController extends Controller
|
|||
* Returns a JSON response containing details on the users associated with this consumable.
|
||||
*
|
||||
* @author [A. Gianotto] [<snipe@snipe.net>]
|
||||
* @see ConsumablesController::getView() method that returns the form.
|
||||
* @see \App\Http\Controllers\Consumables\ConsumablesController::getView() method that returns the form.
|
||||
* @since [v1.0]
|
||||
* @param int $consumableId
|
||||
* @return array
|
||||
|
@ -194,4 +195,28 @@ class ConsumablesController extends Controller
|
|||
$data = array('total' => $consumableCount, 'rows' => $rows);
|
||||
return $data;
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets a paginated collection for the select2 menus
|
||||
*
|
||||
* @see \App\Http\Transformers\SelectlistTransformer
|
||||
*
|
||||
*/
|
||||
public function selectlist(Request $request)
|
||||
{
|
||||
|
||||
$consumables = Consumable::select([
|
||||
'consumables.id',
|
||||
'consumables.name'
|
||||
]);
|
||||
|
||||
if ($request->filled('search')) {
|
||||
$consumables = $consumables->where('consumables.name', 'LIKE', '%'.$request->get('search').'%');
|
||||
}
|
||||
|
||||
$consumables = $consumables->orderBy('name', 'ASC')->paginate(50);
|
||||
|
||||
|
||||
return (new SelectlistTransformer)->transformSelectlist($consumables);
|
||||
}
|
||||
}
|
||||
|
|
|
@ -9,7 +9,6 @@ use App\Models\CustomField;
|
|||
use App\Models\CustomFieldset;
|
||||
use Illuminate\Http\Request;
|
||||
use Validator;
|
||||
use Illuminate\Validation\Rule;
|
||||
|
||||
class CustomFieldsController extends Controller
|
||||
{
|
||||
|
@ -59,9 +58,9 @@ class CustomFieldsController extends Controller
|
|||
{
|
||||
$this->authorize('update', CustomField::class);
|
||||
$field = CustomField::findOrFail($id);
|
||||
|
||||
|
||||
/**
|
||||
* Updated values for the field,
|
||||
* Updated values for the field,
|
||||
* without the "field_encrypted" flag, preventing the change of encryption status
|
||||
* @var array
|
||||
*/
|
||||
|
|
|
@ -1,22 +1,14 @@
|
|||
<?php
|
||||
namespace App\Http\Controllers\Api;
|
||||
|
||||
use View;
|
||||
use App\Models\CustomFieldset;
|
||||
use App\Models\CustomField;
|
||||
use Input;
|
||||
use Validator;
|
||||
use Redirect;
|
||||
use App\Models\AssetModel;
|
||||
use Lang;
|
||||
use Auth;
|
||||
use Illuminate\Http\Request;
|
||||
use Log;
|
||||
use App\Http\Controllers\Controller;
|
||||
use App\Helpers\Helper;
|
||||
use App\Http\Transformers\CustomFieldsTransformer;
|
||||
use App\Http\Controllers\Controller;
|
||||
use App\Http\Transformers\CustomFieldsetsTransformer;
|
||||
use App\Http\Requests\AssetRequest;
|
||||
use App\Http\Transformers\CustomFieldsTransformer;
|
||||
use App\Models\CustomFieldset;
|
||||
use Illuminate\Http\Request;
|
||||
use Redirect;
|
||||
use View;
|
||||
|
||||
/**
|
||||
* This controller handles all actions related to Custom Asset Fieldsets for
|
||||
|
|
|
@ -2,13 +2,14 @@
|
|||
|
||||
namespace App\Http\Controllers\Api;
|
||||
|
||||
use Illuminate\Http\Request;
|
||||
use App\Http\Controllers\Controller;
|
||||
use App\Models\Department;
|
||||
use App\Http\Transformers\DepartmentsTransformer;
|
||||
use App\Helpers\Helper;
|
||||
use Auth;
|
||||
use App\Http\Controllers\Controller;
|
||||
use App\Http\Transformers\DepartmentsTransformer;
|
||||
use App\Http\Transformers\SelectlistTransformer;
|
||||
use App\Models\Department;
|
||||
use Auth;
|
||||
use Illuminate\Http\Request;
|
||||
use Illuminate\Support\Facades\Storage;
|
||||
|
||||
class DepartmentsController extends Controller
|
||||
{
|
||||
|
@ -103,14 +104,36 @@ class DepartmentsController extends Controller
|
|||
return (new DepartmentsTransformer)->transformDepartment($department);
|
||||
}
|
||||
|
||||
/**
|
||||
* Update the specified resource in storage.
|
||||
*
|
||||
* @author [A. Gianotto] [<snipe@snipe.net>]
|
||||
* @since [v5.0]
|
||||
* @param \Illuminate\Http\Request $request
|
||||
* @param int $id
|
||||
* @return \Illuminate\Http\Response
|
||||
*/
|
||||
public function update(Request $request, $id)
|
||||
{
|
||||
$this->authorize('update', Department::class);
|
||||
$department = Department::findOrFail($id);
|
||||
$department->fill($request->all());
|
||||
|
||||
if ($department->save()) {
|
||||
return response()->json(Helper::formatStandardApiResponse('success', $department, trans('admin/departments/message.update.success')));
|
||||
}
|
||||
|
||||
return response()->json(Helper::formatStandardApiResponse('error', null, $department->getErrors()));
|
||||
}
|
||||
|
||||
|
||||
|
||||
/**
|
||||
* Validates and deletes selected location.
|
||||
* Validates and deletes selected department.
|
||||
*
|
||||
* @author [A. Gianotto] [<snipe@snipe.net>]
|
||||
* @param int $locationId
|
||||
* @since [v1.0]
|
||||
* @since [v4.0]
|
||||
* @return \Illuminate\Http\RedirectResponse
|
||||
*/
|
||||
public function destroy($id)
|
||||
|
@ -155,7 +178,7 @@ class DepartmentsController extends Controller
|
|||
// This lets us have more flexibility in special cases like assets, where
|
||||
// they may not have a ->name value but we want to display something anyway
|
||||
foreach ($departments as $department) {
|
||||
$department->use_image = ($department->image) ? url('/').'/uploads/departments/'.$department->image : null;
|
||||
$department->use_image = ($department->image) ? Storage::disk('public')->url('departments/'.$department->image, $department->image) : null;
|
||||
}
|
||||
|
||||
return (new SelectlistTransformer)->transformSelectlist($departments);
|
||||
|
|
|
@ -2,11 +2,11 @@
|
|||
|
||||
namespace App\Http\Controllers\Api;
|
||||
|
||||
use Illuminate\Http\Request;
|
||||
use App\Http\Controllers\Controller;
|
||||
use App\Helpers\Helper;
|
||||
use App\Models\Depreciation;
|
||||
use App\Http\Controllers\Controller;
|
||||
use App\Http\Transformers\DepreciationsTransformer;
|
||||
use App\Models\Depreciation;
|
||||
use Illuminate\Http\Request;
|
||||
|
||||
class DepreciationsController extends Controller
|
||||
{
|
||||
|
@ -113,10 +113,10 @@ class DepreciationsController extends Controller
|
|||
public function destroy($id)
|
||||
{
|
||||
$this->authorize('delete', Depreciation::class);
|
||||
$depreciation = Depreciation::findOrFail($id);
|
||||
$depreciation = Depreciation::withCount('models as models_count')->findOrFail($id);
|
||||
$this->authorize('delete', $depreciation);
|
||||
|
||||
if ($depreciation->has_models() > 0) {
|
||||
if ($depreciation->models_count > 0) {
|
||||
return response()->json(Helper::formatStandardApiResponse('error', trans('admin/depreciations/message.assoc_users')));
|
||||
}
|
||||
|
||||
|
|
|
@ -2,11 +2,11 @@
|
|||
|
||||
namespace App\Http\Controllers\Api;
|
||||
|
||||
use Illuminate\Http\Request;
|
||||
use App\Http\Controllers\Controller;
|
||||
use App\Helpers\Helper;
|
||||
use App\Models\Group;
|
||||
use App\Http\Controllers\Controller;
|
||||
use App\Http\Transformers\GroupsTransformer;
|
||||
use App\Models\Group;
|
||||
use Illuminate\Http\Request;
|
||||
|
||||
class GroupsController extends Controller
|
||||
{
|
||||
|
|
|
@ -6,15 +6,15 @@ use App\Helpers\Helper;
|
|||
use App\Http\Controllers\Controller;
|
||||
use App\Http\Requests\ItemImportRequest;
|
||||
use App\Http\Transformers\ImportsTransformer;
|
||||
use App\Models\Asset;
|
||||
use App\Models\Company;
|
||||
use App\Models\Import;
|
||||
use Illuminate\Http\Request;
|
||||
use Artisan;
|
||||
use Illuminate\Support\Facades\Input;
|
||||
use Illuminate\Support\Facades\Session;
|
||||
use Illuminate\Support\Facades\Storage;
|
||||
use League\Csv\Reader;
|
||||
use Symfony\Component\HttpFoundation\File\Exception\FileException;
|
||||
use Artisan;
|
||||
use App\Models\Asset;
|
||||
|
||||
class ImportController extends Controller
|
||||
{
|
||||
|
@ -112,7 +112,7 @@ class ImportController extends Controller
|
|||
/**
|
||||
* Processes the specified Import.
|
||||
*
|
||||
* @param \App\Import $import
|
||||
* @param int $import_id
|
||||
* @return \Illuminate\Http\Response
|
||||
*/
|
||||
public function process(ItemImportRequest $request, $import_id)
|
||||
|
@ -155,19 +155,26 @@ class ImportController extends Controller
|
|||
/**
|
||||
* Remove the specified resource from storage.
|
||||
*
|
||||
* @param \App\Import $import
|
||||
* @param int $import_id
|
||||
* @return \Illuminate\Http\Response
|
||||
*/
|
||||
public function destroy($import_id)
|
||||
{
|
||||
$this->authorize('import');
|
||||
$import = Import::find($import_id);
|
||||
try {
|
||||
unlink(config('app.private_uploads').'/imports/'.$import->file_path);
|
||||
$import->delete();
|
||||
return response()->json(Helper::formatStandardApiResponse('success', null, trans('admin/hardware/message.import.file_delete_success')));
|
||||
} catch (\Exception $e) {
|
||||
return response()->json(Helper::formatStandardApiResponse('error', null, trans('admin/hardware/message.import.file_delete_error')), 500);
|
||||
$this->authorize('create', Asset::class);
|
||||
|
||||
if ($import = Import::find($import_id)) {
|
||||
try {
|
||||
// Try to delete the file
|
||||
Storage::delete('imports/'.$import->file_path);
|
||||
$import->delete();
|
||||
return response()->json(Helper::formatStandardApiResponse('success', null, trans('admin/hardware/message.import.file_delete_success')));
|
||||
|
||||
} catch (\Exception $e) {
|
||||
// If the file delete didn't work, remove it from the database anyway and return a warning
|
||||
$import->delete();
|
||||
return response()->json(Helper::formatStandardApiResponse('warning', null, trans('admin/hardware/message.import.file_not_deleted_warning')));
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
|
|
|
@ -6,6 +6,7 @@ use App\Helpers\Helper;
|
|||
use App\Http\Controllers\Controller;
|
||||
use App\Http\Transformers\LicenseSeatsTransformer;
|
||||
use App\Http\Transformers\LicensesTransformer;
|
||||
use App\Http\Transformers\SelectlistTransformer;
|
||||
use App\Models\Company;
|
||||
use App\Models\License;
|
||||
use App\Models\LicenseSeat;
|
||||
|
@ -153,7 +154,7 @@ class LicensesController extends Controller
|
|||
public function show($id)
|
||||
{
|
||||
$this->authorize('view', License::class);
|
||||
$license = License::findOrFail($id);
|
||||
$license = License::withCount('freeSeats')->findOrFail($id);
|
||||
$license = $license->load('assignedusers', 'licenseSeats.user', 'licenseSeats.asset');
|
||||
return (new LicensesTransformer)->transformLicense($license);
|
||||
}
|
||||
|
@ -233,9 +234,14 @@ class LicensesController extends Controller
|
|||
$offset = (($seats) && (request('offset') > $seats->count())) ? 0 : request('offset', 0);
|
||||
|
||||
$limit = request('limit', 50);
|
||||
$order = $request->input('order') === 'asc' ? 'asc' : 'desc';
|
||||
|
||||
$order = $request->input('order') === 'asc' ? 'asc' : 'desc';
|
||||
$total = $seats->count();
|
||||
|
||||
if($total < $offset){
|
||||
$offset = 0;
|
||||
}
|
||||
|
||||
$seats = $seats->skip($offset)->take($limit)->get();
|
||||
|
||||
if ($seats) {
|
||||
|
@ -248,5 +254,29 @@ class LicensesController extends Controller
|
|||
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Gets a paginated collection for the select2 menus
|
||||
*
|
||||
* @see \App\Http\Transformers\SelectlistTransformer
|
||||
*/
|
||||
public function selectlist(Request $request)
|
||||
{
|
||||
|
||||
$licenses = License::select([
|
||||
'licenses.id',
|
||||
'licenses.name'
|
||||
]);
|
||||
|
||||
if ($request->filled('search')) {
|
||||
$licenses = $licenses->where('licenses.name', 'LIKE', '%'.$request->get('search').'%');
|
||||
}
|
||||
|
||||
$licenses = $licenses->orderBy('name', 'ASC')->paginate(50);
|
||||
|
||||
|
||||
return (new SelectlistTransformer)->transformSelectlist($licenses);
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
|
|
|
@ -2,14 +2,15 @@
|
|||
|
||||
namespace App\Http\Controllers\Api;
|
||||
|
||||
use Illuminate\Http\Request;
|
||||
use App\Http\Controllers\Controller;
|
||||
use App\Helpers\Helper;
|
||||
use App\Models\Location;
|
||||
use App\Http\Controllers\Controller;
|
||||
use App\Http\Transformers\LocationsTransformer;
|
||||
use App\Http\Transformers\SelectlistTransformer;
|
||||
use App\Models\Location;
|
||||
use Illuminate\Pagination\LengthAwarePaginator;
|
||||
use Illuminate\Support\Collection;
|
||||
use Illuminate\Http\Request;
|
||||
use Illuminate\Support\Facades\Storage;
|
||||
|
||||
class LocationsController extends Controller
|
||||
{
|
||||
|
@ -240,8 +241,8 @@ class LocationsController extends Controller
|
|||
|
||||
$locations_with_children = [];
|
||||
foreach ($locations as $location) {
|
||||
if(!array_key_exists($location->parent_id, $locations_with_children)) {
|
||||
$locations_with_children[$location->parent_id] = [];
|
||||
$location->use_text = $location->name;
|
||||
$location->use_image = ($location->image) ? Storage::disk('public')->url('locations/'.$location->image, $location->image): null;
|
||||
}
|
||||
$locations_with_children[$location->parent_id][] = $location;
|
||||
}
|
||||
|
|
|
@ -2,13 +2,13 @@
|
|||
|
||||
namespace App\Http\Controllers\Api;
|
||||
|
||||
use Illuminate\Http\Request;
|
||||
use App\Http\Controllers\Controller;
|
||||
use App\Helpers\Helper;
|
||||
use App\Models\Manufacturer;
|
||||
use App\Http\Transformers\DatatablesTransformer;
|
||||
use App\Http\Controllers\Controller;
|
||||
use App\Http\Transformers\ManufacturersTransformer;
|
||||
use App\Http\Transformers\SelectlistTransformer;
|
||||
use App\Models\Manufacturer;
|
||||
use Illuminate\Http\Request;
|
||||
use Illuminate\Support\Facades\Storage;
|
||||
|
||||
class ManufacturersController extends Controller
|
||||
{
|
||||
|
@ -123,11 +123,21 @@ class ManufacturersController extends Controller
|
|||
*/
|
||||
public function destroy($id)
|
||||
{
|
||||
|
||||
$this->authorize('delete', Manufacturer::class);
|
||||
$manufacturer = Manufacturer::findOrFail($id);
|
||||
$manufacturer = Manufacturer::withCount('assets as assets_count', 'licenses as licenses_count', 'consumables as consumables_count', 'accessories as accessories_count', 'models as models_count' )->findOrFail($id);
|
||||
$this->authorize('delete', $manufacturer);
|
||||
$manufacturer->delete();
|
||||
return response()->json(Helper::formatStandardApiResponse('success', null, trans('admin/manufacturers/message.delete.success')));
|
||||
|
||||
if (($manufacturer->assets_count == 0) && ($manufacturer->licenses_count==0) && ($manufacturer->consumables_count==0) && ($manufacturer->accessories_count==0) && ($manufacturer->models_count==0) && ($manufacturer->deleted_at=='')) {
|
||||
$manufacturer->delete();
|
||||
return response()->json(Helper::formatStandardApiResponse('success', null, trans('admin/manufacturers/message.delete.success')));
|
||||
}
|
||||
|
||||
return response()->json(Helper::formatStandardApiResponse('error', null, trans('admin/manufacturers/message.delete.error')));
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
}
|
||||
|
||||
|
@ -159,7 +169,7 @@ class ManufacturersController extends Controller
|
|||
// they may not have a ->name value but we want to display something anyway
|
||||
foreach ($manufacturers as $manufacturer) {
|
||||
$manufacturer->use_text = $manufacturer->name;
|
||||
$manufacturer->use_image = ($manufacturer->image) ? url('/').'/uploads/manufacturers/'.$manufacturer->image : null;
|
||||
$manufacturer->use_image = ($manufacturer->image) ? Storage::disk('public')->url('manufacturers/'.$manufacturer->image, $manufacturer->image) : null;
|
||||
}
|
||||
|
||||
return (new SelectlistTransformer)->transformSelectlist($manufacturers);
|
||||
|
|
449
app/Http/Controllers/Api/PredefinedKitsController.php
Normal file
449
app/Http/Controllers/Api/PredefinedKitsController.php
Normal file
|
@ -0,0 +1,449 @@
|
|||
<?php
|
||||
|
||||
namespace App\Http\Controllers\Api;
|
||||
|
||||
use App\Helpers\Helper;
|
||||
use App\Http\Controllers\Controller;
|
||||
use App\Http\Transformers\PredefinedKitsTransformer;
|
||||
use App\Models\PredefinedKit;
|
||||
use Illuminate\Http\Request;
|
||||
|
||||
/**
|
||||
* @author [D. Minaev.] [<dmitriy.minaev.v@gmail.com>]
|
||||
*/
|
||||
class PredefinedKitsController extends Controller
|
||||
{
|
||||
/**
|
||||
* Display a listing of the resource.
|
||||
*
|
||||
* @return \Illuminate\Http\Response
|
||||
*/
|
||||
public function index(Request $request)
|
||||
{
|
||||
$this->authorize('view', PredefinedKit::class);
|
||||
$allowed_columns = ['id', 'name'];
|
||||
|
||||
$kits = PredefinedKit::query();
|
||||
|
||||
if ($request->filled('search')) {
|
||||
$kits = $kits->TextSearch($request->input('search'));
|
||||
}
|
||||
|
||||
$offset = $request->input('offset', 0);
|
||||
$limit = $request->input('limit', 50);
|
||||
$order = $request->input('order') === 'asc' ? 'asc' : 'desc';
|
||||
$sort = in_array($request->input('sort'), $allowed_columns) ? $request->input('sort') : 'assets_count';
|
||||
$kits->orderBy($sort, $order);
|
||||
|
||||
$total = $kits->count();
|
||||
$kits = $kits->skip($offset)->take($limit)->get();
|
||||
return (new PredefinedKitsTransformer)->transformPredefinedKits($kits, $total);
|
||||
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Store a newly created resource in storage.
|
||||
*
|
||||
* @param \Illuminate\Http\Request $request
|
||||
* @return \Illuminate\Http\Response
|
||||
*/
|
||||
public function store(Request $request)
|
||||
{
|
||||
$this->authorize('create', PredefinedKit::class);
|
||||
$kit = new PredefinedKit;
|
||||
$kit->fill($request->all());
|
||||
|
||||
if ($kit->save()) {
|
||||
return response()->json(Helper::formatStandardApiResponse('success', $kit, trans('admin/kits/general.create_success')));
|
||||
}
|
||||
return response()->json(Helper::formatStandardApiResponse('error', null, $kit->getErrors()));
|
||||
|
||||
}
|
||||
|
||||
/**
|
||||
* Display the specified resource.
|
||||
*
|
||||
* @param int $id
|
||||
* @return \Illuminate\Http\Response
|
||||
*/
|
||||
public function show($id)
|
||||
{
|
||||
$this->authorize('view', PredefinedKit::class);
|
||||
$kit = PredefinedKit::findOrFail($id);
|
||||
return (new PredefinedKitsTransformer)->transformPredefinedKit($kit);
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Update the specified resource in storage.
|
||||
*
|
||||
* @param \Illuminate\Http\Request $request
|
||||
* @param int $id kit id
|
||||
* @return \Illuminate\Http\Response
|
||||
*/
|
||||
public function update(Request $request, $id)
|
||||
{
|
||||
$this->authorize('update', PredefinedKit::class);
|
||||
$kit = PredefinedKit::findOrFail($id);
|
||||
$kit->fill($request->all());
|
||||
|
||||
if ($kit->save()) {
|
||||
return response()->json(Helper::formatStandardApiResponse('success', $kit, trans('admin/kits/general.update_success'))); // TODO: trans
|
||||
}
|
||||
|
||||
return response()->json(Helper::formatStandardApiResponse('error', null, $kit->getErrors()));
|
||||
}
|
||||
|
||||
/**
|
||||
* Remove the specified resource from storage.
|
||||
*
|
||||
* @param int $id
|
||||
* @return \Illuminate\Http\Response
|
||||
*/
|
||||
public function destroy($id)
|
||||
{
|
||||
$this->authorize('delete', PredefinedKit::class);
|
||||
$kit = PredefinedKit::findOrFail($id);
|
||||
|
||||
// Delete childs
|
||||
$kit->models()->detach();
|
||||
$kit->licenses()->detach();
|
||||
$kit->consumables()->detach();
|
||||
$kit->accessories()->detach();
|
||||
|
||||
$kit->delete();
|
||||
return response()->json(Helper::formatStandardApiResponse('success', null, trans('admin/kits/general.delete_success'))); // TODO: trans
|
||||
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Gets a paginated collection for the select2 menus
|
||||
*
|
||||
* @see \App\Http\Transformers\SelectlistTransformer
|
||||
*
|
||||
*/
|
||||
public function selectlist(Request $request)
|
||||
{
|
||||
|
||||
$kits = PredefinedKit::select([
|
||||
'id',
|
||||
'name'
|
||||
]);
|
||||
|
||||
if ($request->filled('search')) {
|
||||
$kits = $kits->where('name', 'LIKE', '%'.$request->get('search').'%');
|
||||
}
|
||||
|
||||
$kits = $kits->orderBy('name', 'ASC')->paginate(50);
|
||||
|
||||
return (new SelectlistTransformer)->transformSelectlist($kits);
|
||||
|
||||
}
|
||||
|
||||
/**
|
||||
* Display the specified resource.
|
||||
*
|
||||
* @param int $id
|
||||
* @return \Illuminate\Http\Response
|
||||
*/
|
||||
public function indexLicenses($kit_id) {
|
||||
$this->authorize('view', PredefinedKit::class);
|
||||
$kit = PredefinedKit::findOrFail($kit_id);
|
||||
$licenses = $kit->licenses;
|
||||
return (new PredefinedKitsTransformer)->transformElements($licenses, $licenses->count());
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Store the specified resource.
|
||||
*
|
||||
* @param int $id
|
||||
* @return \Illuminate\Http\Response
|
||||
*/
|
||||
public function storeLicense(Request $request, $kit_id)
|
||||
{
|
||||
$this->authorize('update', PredefinedKit::class);
|
||||
|
||||
$kit = PredefinedKit::findOrFail($kit_id);
|
||||
$quantity = $request->input('quantity', 1);
|
||||
if( $quantity < 1) {
|
||||
$quantity = 1;
|
||||
}
|
||||
|
||||
$license_id = $request->get('license');
|
||||
$relation = $kit->licenses();
|
||||
if( $relation->find($license_id) ) {
|
||||
return response()->json(Helper::formatStandardApiResponse('error', null, ['license' => 'License already attached to kit']));
|
||||
}
|
||||
|
||||
$relation->attach( $license_id, ['quantity' => $quantity]);
|
||||
return response()->json(Helper::formatStandardApiResponse('success', $kit, 'License added successfull')); // TODO: trans
|
||||
}
|
||||
|
||||
/**
|
||||
* Update the specified resource in storage.
|
||||
*
|
||||
* @param \Illuminate\Http\Request $request
|
||||
* @param int $kit_id
|
||||
* @return \Illuminate\Http\Response
|
||||
*/
|
||||
public function updateLicense(Request $request, $kit_id, $license_id)
|
||||
{
|
||||
$this->authorize('update', PredefinedKit::class);
|
||||
$kit = PredefinedKit::findOrFail($kit_id);
|
||||
$quantity = $request->input('quantity', 1);
|
||||
if( $quantity < 1) {
|
||||
$quantity = 1;
|
||||
}
|
||||
$kit->licenses()->syncWithoutDetaching([$license_id => ['quantity' => $quantity]]);
|
||||
|
||||
return response()->json(Helper::formatStandardApiResponse('success', $kit, 'License updated')); // TODO: trans
|
||||
}
|
||||
|
||||
/**
|
||||
* Remove the specified resource from storage.
|
||||
*
|
||||
* @param int $kit_id
|
||||
* @return \Illuminate\Http\Response
|
||||
*/
|
||||
public function detachLicense($kit_id, $license_id)
|
||||
{
|
||||
$this->authorize('update', PredefinedKit::class);
|
||||
$kit = PredefinedKit::findOrFail($kit_id);
|
||||
|
||||
$kit->licenses()->detach($license_id);
|
||||
return response()->json(Helper::formatStandardApiResponse('success', $kit, trans('admin/kits/general.delete_success')));
|
||||
}
|
||||
|
||||
/**
|
||||
* Display the specified resource.
|
||||
*
|
||||
* @param int $kit_id
|
||||
* @return \Illuminate\Http\Response
|
||||
*/
|
||||
public function indexModels($kit_id) {
|
||||
$this->authorize('view', PredefinedKit::class);
|
||||
$kit = PredefinedKit::findOrFail($kit_id);
|
||||
$models = $kit->models;
|
||||
return (new PredefinedKitsTransformer)->transformElements($models, $models->count());
|
||||
}
|
||||
|
||||
/**
|
||||
* Store the specified resource.
|
||||
*
|
||||
* @param int $id
|
||||
* @return \Illuminate\Http\Response
|
||||
*/
|
||||
public function storeModel(Request $request, $kit_id)
|
||||
{
|
||||
|
||||
|
||||
$this->authorize('update', PredefinedKit::class);
|
||||
|
||||
$kit = PredefinedKit::findOrFail($kit_id);
|
||||
|
||||
$model_id = $request->get('model');
|
||||
$quantity = $request->input('quantity', 1);
|
||||
if( $quantity < 1) {
|
||||
$quantity = 1;
|
||||
}
|
||||
|
||||
$relation = $kit->models();
|
||||
if( $relation->find($model_id) ) {
|
||||
return response()->json(Helper::formatStandardApiResponse('error', null, ['model' => 'Model already attached to kit']));
|
||||
}
|
||||
$relation->attach($model_id, ['quantity' => $quantity]);
|
||||
|
||||
return response()->json(Helper::formatStandardApiResponse('success', $kit, 'Model added successfull'));
|
||||
}
|
||||
|
||||
/**
|
||||
* Update the specified resource in storage.
|
||||
*
|
||||
* @param \Illuminate\Http\Request $request
|
||||
* @param int $kit_id
|
||||
* @return \Illuminate\Http\Response
|
||||
*/
|
||||
public function updateModel(Request $request, $kit_id, $model_id)
|
||||
{
|
||||
$this->authorize('update', PredefinedKit::class);
|
||||
$kit = PredefinedKit::findOrFail($kit_id);
|
||||
$quantity = $request->input('quantity', 1);
|
||||
if( $quantity < 1) {
|
||||
$quantity = 1;
|
||||
}
|
||||
$kit->models()->syncWithoutDetaching([$model_id => ['quantity' => $quantity]]);
|
||||
|
||||
return response()->json(Helper::formatStandardApiResponse('success', $kit, 'License updated')); // TODO: trans
|
||||
}
|
||||
|
||||
/**
|
||||
* Remove the specified resource from storage.
|
||||
*
|
||||
* @param int $kit_id
|
||||
* @return \Illuminate\Http\Response
|
||||
*/
|
||||
public function detachModel($kit_id, $model_id)
|
||||
{
|
||||
$this->authorize('update', PredefinedKit::class);
|
||||
$kit = PredefinedKit::findOrFail($kit_id);
|
||||
|
||||
$kit->models()->detach($model_id);
|
||||
return response()->json(Helper::formatStandardApiResponse('success', $kit, trans('admin/kits/general.model_removed_success')));
|
||||
}
|
||||
|
||||
|
||||
|
||||
/**
|
||||
* Display the specified resource.
|
||||
*
|
||||
* @param int $kit_id
|
||||
* @return \Illuminate\Http\Response
|
||||
*/
|
||||
public function indexConsumables($kit_id) {
|
||||
$this->authorize('view', PredefinedKit::class);
|
||||
$kit = PredefinedKit::findOrFail($kit_id);
|
||||
$consumables = $kit->consumables;
|
||||
return (new PredefinedKitsTransformer)->transformElements($consumables, $consumables->count());
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Store the specified resource.
|
||||
*
|
||||
* @param int $id
|
||||
* @return \Illuminate\Http\Response
|
||||
*/
|
||||
public function storeConsumable(Request $request, $kit_id)
|
||||
{
|
||||
$this->authorize('update', PredefinedKit::class);
|
||||
|
||||
$kit = PredefinedKit::findOrFail($kit_id);
|
||||
$quantity = $request->input('quantity', 1);
|
||||
if( $quantity < 1) {
|
||||
$quantity = 1;
|
||||
}
|
||||
|
||||
$consumable_id = $request->get('consumable');
|
||||
$relation = $kit->consumables();
|
||||
if( $relation->find($consumable_id) ) {
|
||||
return response()->json(Helper::formatStandardApiResponse('error', null, ['consumable' => 'Consumable already attached to kit']));
|
||||
}
|
||||
|
||||
$relation->attach( $consumable_id, ['quantity' => $quantity]);
|
||||
return response()->json(Helper::formatStandardApiResponse('success', $kit, 'Consumable added successfull')); // TODO: trans
|
||||
}
|
||||
|
||||
/**
|
||||
* Update the specified resource in storage.
|
||||
*
|
||||
* @param \Illuminate\Http\Request $request
|
||||
* @param int $kit_id
|
||||
* @return \Illuminate\Http\Response
|
||||
*/
|
||||
public function updateConsumable(Request $request, $kit_id, $consumable_id)
|
||||
{
|
||||
$this->authorize('update', PredefinedKit::class);
|
||||
$kit = PredefinedKit::findOrFail($kit_id);
|
||||
$quantity = $request->input('quantity', 1);
|
||||
if( $quantity < 1) {
|
||||
$quantity = 1;
|
||||
}
|
||||
$kit->consumables()->syncWithoutDetaching([$consumable_id => ['quantity' => $quantity]]);
|
||||
|
||||
return response()->json(Helper::formatStandardApiResponse('success', $kit, 'Consumable updated')); // TODO: trans
|
||||
}
|
||||
|
||||
/**
|
||||
* Remove the specified resource from storage.
|
||||
*
|
||||
* @param int $kit_id
|
||||
* @return \Illuminate\Http\Response
|
||||
*/
|
||||
public function detachConsumable($kit_id, $consumable_id)
|
||||
{
|
||||
$this->authorize('update', PredefinedKit::class);
|
||||
$kit = PredefinedKit::findOrFail($kit_id);
|
||||
|
||||
$kit->consumables()->detach($consumable_id);
|
||||
return response()->json(Helper::formatStandardApiResponse('success', $kit, 'Delete was successfull')); // TODO: trans
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Display the specified resource.
|
||||
*
|
||||
* @param int $kit_id
|
||||
* @return \Illuminate\Http\Response
|
||||
*/
|
||||
public function indexAccessories($kit_id) {
|
||||
$this->authorize('view', PredefinedKit::class);
|
||||
$kit = PredefinedKit::findOrFail($kit_id);
|
||||
$accessories = $kit->accessories;
|
||||
return (new PredefinedKitsTransformer)->transformElements($accessories, $accessories->count());
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Store the specified resource.
|
||||
*
|
||||
* @param int $kit_id
|
||||
* @return \Illuminate\Http\Response
|
||||
*/
|
||||
public function storeAccessory(Request $request, $kit_id)
|
||||
{
|
||||
$this->authorize('update', PredefinedKit::class);
|
||||
|
||||
$kit = PredefinedKit::findOrFail($kit_id);
|
||||
$quantity = $request->input('quantity', 1);
|
||||
if( $quantity < 1) {
|
||||
$quantity = 1;
|
||||
}
|
||||
|
||||
$accessory_id = $request->get('accessory');
|
||||
$relation = $kit->accessories();
|
||||
if( $relation->find($accessory_id) ) {
|
||||
return response()->json(Helper::formatStandardApiResponse('error', null, ['accessory' => 'Accessory already attached to kit']));
|
||||
}
|
||||
|
||||
$relation->attach( $accessory_id, ['quantity' => $quantity]);
|
||||
return response()->json(Helper::formatStandardApiResponse('success', $kit, 'Accessory added successfull')); // TODO: trans
|
||||
}
|
||||
|
||||
/**
|
||||
* Update the specified resource in storage.
|
||||
*
|
||||
* @param \Illuminate\Http\Request $request
|
||||
* @param int $kit_id
|
||||
* @return \Illuminate\Http\Response
|
||||
*/
|
||||
public function updateAccessory(Request $request, $kit_id, $accessory_id)
|
||||
{
|
||||
$this->authorize('update', PredefinedKit::class);
|
||||
$kit = PredefinedKit::findOrFail($kit_id);
|
||||
$quantity = $request->input('quantity', 1);
|
||||
if( $quantity < 1) {
|
||||
$quantity = 1;
|
||||
}
|
||||
$kit->accessories()->syncWithoutDetaching([$accessory_id => ['quantity' => $quantity]]);
|
||||
|
||||
return response()->json(Helper::formatStandardApiResponse('success', $kit, 'Accessory updated')); // TODO: trans
|
||||
}
|
||||
|
||||
/**
|
||||
* Remove the specified resource from storage.
|
||||
*
|
||||
* @param int $kit_id
|
||||
* @return \Illuminate\Http\Response
|
||||
*/
|
||||
public function detachAccessory($kit_id, $accessory_id)
|
||||
{
|
||||
$this->authorize('update', PredefinedKit::class);
|
||||
$kit = PredefinedKit::findOrFail($kit_id);
|
||||
|
||||
$kit->accessories()->detach($accessory_id);
|
||||
return response()->json(Helper::formatStandardApiResponse('success', $kit, 'Delete was successfull')); // TODO: trans
|
||||
}
|
||||
}
|
|
@ -2,11 +2,10 @@
|
|||
|
||||
namespace App\Http\Controllers\Api;
|
||||
|
||||
use App\Models\CheckoutRequest;
|
||||
use App\Http\Controllers\Controller;
|
||||
use Auth;
|
||||
use App\Helpers\Helper;
|
||||
|
||||
use App\Http\Controllers\Controller;
|
||||
use App\Models\CheckoutRequest;
|
||||
use Auth;
|
||||
|
||||
class ProfileController extends Controller
|
||||
{
|
||||
|
|
|
@ -2,10 +2,10 @@
|
|||
|
||||
namespace App\Http\Controllers\Api;
|
||||
|
||||
use Illuminate\Http\Request;
|
||||
use App\Http\Controllers\Controller;
|
||||
use App\Models\Actionlog;
|
||||
use App\Http\Transformers\ActionlogsTransformer;
|
||||
use App\Models\Actionlog;
|
||||
use Illuminate\Http\Request;
|
||||
|
||||
class ReportsController extends Controller
|
||||
{
|
||||
|
|
|
@ -2,104 +2,88 @@
|
|||
|
||||
namespace App\Http\Controllers\Api;
|
||||
|
||||
use Illuminate\Http\Request;
|
||||
use App\Http\Controllers\Controller;
|
||||
use App\Models\Ldap;
|
||||
use Validator;
|
||||
use App\Http\Transformers\LoginAttemptsTransformer;
|
||||
use App\Models\Setting;
|
||||
use Mail;
|
||||
use App\Notifications\SlackTest;
|
||||
use Notification;
|
||||
use App\Notifications\MailTest;
|
||||
use App\Notifications\SlackTest;
|
||||
use App\Services\LdapAd;
|
||||
use Illuminate\Http\JsonResponse;
|
||||
use Illuminate\Http\Request;
|
||||
use Illuminate\Support\Facades\DB;
|
||||
use Illuminate\Support\Facades\Log;
|
||||
use Illuminate\Support\Facades\Notification;
|
||||
|
||||
class SettingsController extends Controller
|
||||
{
|
||||
|
||||
|
||||
public function ldaptest()
|
||||
/**
|
||||
* Test the ldap settings
|
||||
*
|
||||
* @author Wes Hulette <jwhulette@gmail.com>
|
||||
*
|
||||
* @since 5.0.0
|
||||
*
|
||||
* @param App\Models\LdapAd $ldap
|
||||
*
|
||||
* @return \Illuminate\Http\JsonResponse
|
||||
*/
|
||||
public function ldapAdSettingsTest(LdapAd $ldap): JsonResponse
|
||||
{
|
||||
|
||||
if (Setting::getSettings()->ldap_enabled!='1') {
|
||||
\Log::debug('LDAP is not enabled cannot test.');
|
||||
if(!$ldap->init()) {
|
||||
Log::info('LDAP is not enabled cannot test.');
|
||||
return response()->json(['message' => 'LDAP is not enabled, cannot test.'], 400);
|
||||
}
|
||||
|
||||
\Log::debug('Preparing to test LDAP connection');
|
||||
// The connect, bind and resulting users message
|
||||
$message = [];
|
||||
|
||||
Log::info('Preparing to test LDAP user login');
|
||||
// Test user can connect to the LDAP server
|
||||
try {
|
||||
$connection = Ldap::connectToLdap();
|
||||
try {
|
||||
\Log::debug('attempting to bind to LDAP for LDAP test');
|
||||
Ldap::bindAdminToLdap($connection);
|
||||
return response()->json(['message' => 'It worked!'], 200);
|
||||
} catch (\Exception $e) {
|
||||
\Log::debug('Bind failed');
|
||||
return response()->json(['message' => $e->getMessage()], 400);
|
||||
//return response()->json(['message' => $e->getMessage()], 500);
|
||||
$ldap->testLdapAdUserConnection();
|
||||
$message['login'] = [
|
||||
'message' => 'Successfully connected to LDAP server.'
|
||||
];
|
||||
} catch (\Exception $ex) {
|
||||
return response()->json([
|
||||
'message' => 'Error logging into LDAP server, error: ' . $ex->getMessage() . ' - Verify your that your username and password are correct'
|
||||
}
|
||||
} catch (\Exception $e) {
|
||||
\Log::debug('Connection failed but we cannot debug it any further on our end.');
|
||||
return response()->json(['message' => $e->getMessage()], 600);
|
||||
], 400);
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
|
||||
public function ldaptestlogin(Request $request)
|
||||
{
|
||||
|
||||
if (Setting::getSettings()->ldap_enabled!='1') {
|
||||
\Log::debug('LDAP is not enabled. Cannot test.');
|
||||
return response()->json(['message' => 'LDAP is not enabled, cannot test.'], 400);
|
||||
}
|
||||
|
||||
|
||||
$rules = array(
|
||||
'ldaptest_user' => 'required',
|
||||
'ldaptest_password' => 'required'
|
||||
);
|
||||
|
||||
$validator = Validator::make($request->all(), $rules);
|
||||
if ($validator->fails()) {
|
||||
\Log::debug('LDAP Validation test failed.');
|
||||
$validation_errors = implode(' ',$validator->errors()->all());
|
||||
return response()->json(['message' => $validator->errors()->all()], 400);
|
||||
}
|
||||
|
||||
|
||||
\Log::debug('Preparing to test LDAP login');
|
||||
Log::info('Preparing to test LDAP bind connection');
|
||||
// Test user can bind to the LDAP server
|
||||
try {
|
||||
$connection = Ldap::connectToLdap();
|
||||
try {
|
||||
Ldap::bindAdminToLdap($connection);
|
||||
\Log::debug('Attempting to bind to LDAP for LDAP test');
|
||||
try {
|
||||
$ldap_user = Ldap::findAndBindUserLdap($request->input('ldaptest_user'), $request->input('ldaptest_password'));
|
||||
if ($ldap_user) {
|
||||
\Log::debug('It worked! '. $request->input('ldaptest_user').' successfully binded to LDAP.');
|
||||
return response()->json(['message' => 'It worked! '. $request->input('ldaptest_user').' successfully binded to LDAP.'], 200);
|
||||
}
|
||||
return response()->json(['message' => 'Login Failed. '. $request->input('ldaptest_user').' did not successfully bind to LDAP.'], 400);
|
||||
|
||||
} catch (\Exception $e) {
|
||||
\Log::debug('LDAP login failed');
|
||||
return response()->json(['message' => $e->getMessage()], 400);
|
||||
}
|
||||
|
||||
} catch (\Exception $e) {
|
||||
\Log::debug('Bind failed');
|
||||
return response()->json(['message' => $e->getMessage()], 400);
|
||||
//return response()->json(['message' => $e->getMessage()], 500);
|
||||
}
|
||||
} catch (\Exception $e) {
|
||||
\Log::debug('Connection failed');
|
||||
return response()->json(['message' => $e->getMessage()], 500);
|
||||
$ldap->testLdapAdBindConnection();
|
||||
$message['bind'] = [
|
||||
'message' => 'Successfully binded to LDAP server.'
|
||||
];
|
||||
} catch (\Exception $ex) {
|
||||
return response()->json([
|
||||
'message' => 'Error binding to LDAP server, error: ' . $ex->getMessage()
|
||||
], 400);
|
||||
}
|
||||
|
||||
Log::info('Preparing to get sample user set from LDAP directory');
|
||||
// Get a sample of 10 users so user can verify the data is correct
|
||||
try {
|
||||
$users = $ldap->testUserImportSync();
|
||||
$message['user_sync'] = [
|
||||
'users' => $users
|
||||
];
|
||||
} catch (\Exception $ex) {
|
||||
$message['user_sync'] = [
|
||||
'message' => 'Error getting users from LDAP directory, error: ' . $ex->getMessage()
|
||||
];
|
||||
return response()->json($message, 400);
|
||||
}
|
||||
|
||||
return response()->json($message, 200);
|
||||
}
|
||||
|
||||
|
||||
public function slacktest()
|
||||
{
|
||||
|
||||
|
@ -143,6 +127,30 @@ class SettingsController extends Controller
|
|||
|
||||
}
|
||||
|
||||
/**
|
||||
* Get a list of login attempts
|
||||
*
|
||||
* @author [A. Gianotto] [<snipe@snipe.net>]
|
||||
* @since [v5.0.0]
|
||||
* @param \Illuminate\Http\Request $request
|
||||
* @return array
|
||||
*/
|
||||
public function showLoginAttempts(Request $request)
|
||||
{
|
||||
$allowed_columns = ['id', 'username', 'remote_ip', 'user_agent','successful','created_at'];
|
||||
|
||||
$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';
|
||||
|
||||
$total = $login_attempts->count();
|
||||
$login_attempts->orderBy($sort, $order);
|
||||
$login_attempt_results = $login_attempts->skip(request('offset', 0))->take(request('limit', 20))->get();
|
||||
|
||||
return (new LoginAttemptsTransformer)->transformLoginAttempts($login_attempt_results, $total);
|
||||
|
||||
}
|
||||
|
||||
|
||||
|
||||
}
|
||||
|
|
|
@ -2,13 +2,13 @@
|
|||
|
||||
namespace App\Http\Controllers\Api;
|
||||
|
||||
use Illuminate\Http\Request;
|
||||
use App\Http\Controllers\Controller;
|
||||
use App\Helpers\Helper;
|
||||
use App\Models\Statuslabel;
|
||||
use App\Models\Asset;
|
||||
use App\Http\Transformers\StatuslabelsTransformer;
|
||||
use App\Http\Controllers\Controller;
|
||||
use App\Http\Transformers\AssetsTransformer;
|
||||
use App\Http\Transformers\StatuslabelsTransformer;
|
||||
use App\Models\Asset;
|
||||
use App\Models\Statuslabel;
|
||||
use Illuminate\Http\Request;
|
||||
|
||||
class StatuslabelsController extends Controller
|
||||
{
|
||||
|
@ -207,11 +207,11 @@ class StatuslabelsController extends Controller
|
|||
{
|
||||
$this->authorize('view', Statuslabel::class);
|
||||
$this->authorize('index', Asset::class);
|
||||
$assets = Asset::where('status_id','=',$id);
|
||||
$assets = Asset::where('status_id','=',$id)->with('assignedTo');
|
||||
|
||||
$allowed_columns = [
|
||||
'id',
|
||||
'name'
|
||||
'name',
|
||||
];
|
||||
|
||||
$offset = request('offset', 0);
|
||||
|
@ -241,8 +241,6 @@ class StatuslabelsController extends Controller
|
|||
*/
|
||||
public function checkIfDeployable($id) {
|
||||
$statuslabel = Statuslabel::findOrFail($id);
|
||||
$this->authorize('view', Asset::class);
|
||||
|
||||
if ($statuslabel->getStatuslabelType()=='deployable') {
|
||||
return '1';
|
||||
}
|
||||
|
|
|
@ -2,13 +2,13 @@
|
|||
|
||||
namespace App\Http\Controllers\Api;
|
||||
|
||||
use Illuminate\Http\Request;
|
||||
use App\Http\Controllers\Controller;
|
||||
use App\Helpers\Helper;
|
||||
use App\Models\Supplier;
|
||||
use App\Http\Transformers\SuppliersTransformer;
|
||||
use App\Http\Controllers\Controller;
|
||||
use App\Http\Transformers\SelectlistTransformer;
|
||||
|
||||
use App\Http\Transformers\SuppliersTransformer;
|
||||
use App\Models\Supplier;
|
||||
use Illuminate\Http\Request;
|
||||
use Illuminate\Support\Facades\Storage;
|
||||
|
||||
class SuppliersController extends Controller
|
||||
{
|
||||
|
@ -22,7 +22,7 @@ class SuppliersController extends Controller
|
|||
public function index(Request $request)
|
||||
{
|
||||
$this->authorize('view', Supplier::class);
|
||||
$allowed_columns = ['id','name','address','phone','contact','fax','email','image','assets_count','licenses_count', 'accessories_count'];
|
||||
$allowed_columns = ['id','name','address','phone','contact','fax','email','image','assets_count','licenses_count', 'accessories_count','url'];
|
||||
|
||||
$suppliers = Supplier::select(
|
||||
array('id','name','address','address2','city','state','country','fax', 'phone','email','contact','created_at','updated_at','deleted_at','image','notes')
|
||||
|
@ -167,7 +167,7 @@ class SuppliersController extends Controller
|
|||
// they may not have a ->name value but we want to display something anyway
|
||||
foreach ($suppliers as $supplier) {
|
||||
$supplier->use_text = $supplier->name;
|
||||
$supplier->use_image = ($supplier->image) ? url('/').'/uploads/suppliers/'.$supplier->image : null;
|
||||
$supplier->use_image = ($supplier->image) ? Storage::disk('public')->url('suppliers/'.$supplier->image, $supplier->image) : null;
|
||||
}
|
||||
|
||||
return (new SelectlistTransformer)->transformSelectlist($suppliers);
|
||||
|
|
|
@ -2,17 +2,19 @@
|
|||
|
||||
namespace App\Http\Controllers\Api;
|
||||
|
||||
use Illuminate\Http\Request;
|
||||
use App\Http\Controllers\Controller;
|
||||
use App\Http\Transformers\UsersTransformer;
|
||||
use App\Models\Company;
|
||||
use App\Models\User;
|
||||
use App\Helpers\Helper;
|
||||
use App\Http\Controllers\Controller;
|
||||
use App\Http\Requests\SaveUserRequest;
|
||||
use App\Models\Asset;
|
||||
use App\Http\Transformers\AssetsTransformer;
|
||||
use App\Http\Transformers\SelectlistTransformer;
|
||||
use App\Http\Transformers\AccessoriesTransformer;
|
||||
use App\Http\Transformers\AssetsTransformer;
|
||||
use App\Http\Transformers\LicensesTransformer;
|
||||
use App\Http\Transformers\SelectlistTransformer;
|
||||
use App\Http\Transformers\UsersTransformer;
|
||||
use App\Models\Asset;
|
||||
use App\Models\Company;
|
||||
use App\Models\License;
|
||||
use App\Models\User;
|
||||
use Illuminate\Http\Request;
|
||||
|
||||
class UsersController extends Controller
|
||||
{
|
||||
|
@ -206,6 +208,7 @@ class UsersController extends Controller
|
|||
$tmp_pass = substr(str_shuffle("0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ"), 0, 20);
|
||||
$user->password = bcrypt($request->get('password', $tmp_pass));
|
||||
|
||||
|
||||
if ($user->save()) {
|
||||
if ($request->filled('groups')) {
|
||||
$user->groups()->sync($request->input('groups'));
|
||||
|
@ -247,6 +250,16 @@ class UsersController extends Controller
|
|||
$this->authorize('update', User::class);
|
||||
|
||||
$user = User::findOrFail($id);
|
||||
|
||||
// This is a janky hack to prevent people from changing admin demo user data on the public demo.
|
||||
// The $ids 1 and 2 are special since they are seeded as superadmins in the demo seeder.
|
||||
// Thanks, jerks. You are why we can't have nice things. - snipe
|
||||
|
||||
if ((($id == 1) || ($id == 2)) && (config('app.lock_passwords'))) {
|
||||
return response()->json(Helper::formatStandardApiResponse('error', null, 'Permission denied. You cannot update user information via API on the demo.'));
|
||||
}
|
||||
|
||||
|
||||
$user->fill($request->all());
|
||||
|
||||
if ($user->id == $request->input('manager_id')) {
|
||||
|
@ -315,8 +328,16 @@ class UsersController extends Controller
|
|||
return response()->json(Helper::formatStandardApiResponse('error', null, 'This user still has ' . $user->managedLocations()->count() . ' locations that they manage.'));
|
||||
}
|
||||
|
||||
|
||||
if ($user->delete()) {
|
||||
|
||||
// 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);
|
||||
}
|
||||
}
|
||||
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')));
|
||||
|
@ -356,6 +377,26 @@ class UsersController extends Controller
|
|||
}
|
||||
|
||||
/**
|
||||
|
||||
* Return JSON containing a list of licenses assigned to a user.
|
||||
*
|
||||
* @author [N. Mathar] [<snipe@snipe.net>]
|
||||
* @since [v5.0]
|
||||
* @param $userId
|
||||
* @return string JSON
|
||||
*/
|
||||
public function licenses($id)
|
||||
{
|
||||
$this->authorize('view', User::class);
|
||||
$this->authorize('view', License::class);
|
||||
$user = User::where('id', $id)->withTrashed()->first();
|
||||
$licenses = $user->licenses()->get();
|
||||
return (new LicensesTransformer())->transformLicenses($licenses, $licenses->count());
|
||||
}
|
||||
|
||||
/**
|
||||
|
||||
|
||||
* Reset the user's two-factor status
|
||||
*
|
||||
* @author [A. Gianotto] [<snipe@snipe.net>]
|
||||
|
|
|
@ -1,26 +1,17 @@
|
|||
<?php
|
||||
namespace App\Http\Controllers;
|
||||
|
||||
use App\Helpers\Helper;
|
||||
use App\Models\Asset;
|
||||
use App\Models\AssetMaintenance;
|
||||
use Carbon\Carbon;
|
||||
use App\Models\Company;
|
||||
use DB;
|
||||
use Input;
|
||||
use Lang;
|
||||
use Log;
|
||||
use Mail;
|
||||
use Response;
|
||||
use Auth;
|
||||
use Carbon\Carbon;
|
||||
use Illuminate\Http\Request;
|
||||
use Slack;
|
||||
use Str;
|
||||
use TCPDF;
|
||||
use Validator;
|
||||
use View;
|
||||
use App\Models\Setting;
|
||||
use App\Models\Asset;
|
||||
use App\Helpers\Helper;
|
||||
use Auth;
|
||||
use Gate;
|
||||
use Illuminate\Http\Request;
|
||||
|
||||
/**
|
||||
* This controller handles all actions related to Asset Maintenance for
|
||||
|
@ -165,6 +156,7 @@ class AssetMaintenancesController extends Controller
|
|||
} elseif (!$assetMaintenance->asset) {
|
||||
return redirect()->route('maintenances.index')
|
||||
->with('error', 'The asset associated with this maintenance does not exist.');
|
||||
|
||||
} elseif (!Company::isCurrentUserHasAccess($assetMaintenance->asset)) {
|
||||
return static::getInsufficientPermissionsRedirect();
|
||||
}
|
||||
|
|
|
@ -1,25 +1,13 @@
|
|||
<?php
|
||||
namespace App\Http\Controllers;
|
||||
|
||||
use App\Models\CustomField;
|
||||
use Image;
|
||||
use Input;
|
||||
use Lang;
|
||||
use App\Models\AssetModel;
|
||||
use Redirect;
|
||||
use Auth;
|
||||
use DB;
|
||||
use Str;
|
||||
use Validator;
|
||||
use View;
|
||||
use App\Models\Asset;
|
||||
use App\Models\Company;
|
||||
use Config;
|
||||
use App\Helpers\Helper;
|
||||
use Illuminate\Http\Request;
|
||||
use App\Http\Requests\ImageUploadRequest;
|
||||
|
||||
use Symfony\Component\HttpFoundation\JsonResponse;
|
||||
use App\Models\AssetModel;
|
||||
use Illuminate\Support\Facades\Auth;
|
||||
use Illuminate\Support\Facades\Input;
|
||||
use Illuminate\Support\Facades\View;
|
||||
use Redirect;
|
||||
|
||||
/**
|
||||
* This class controls all actions related to asset models for
|
||||
|
@ -31,13 +19,14 @@ use Symfony\Component\HttpFoundation\JsonResponse;
|
|||
class AssetModelsController extends Controller
|
||||
{
|
||||
/**
|
||||
* Returns a view that invokes the ajax tables which actually contains
|
||||
* the content for the accessories listing, which is generated in getDatatable.
|
||||
*
|
||||
* @author [A. Gianotto] [<snipe@snipe.net>]
|
||||
* @since [v1.0]
|
||||
* @return View
|
||||
*/
|
||||
* Returns a view that invokes the ajax tables which actually contains
|
||||
* the content for the accessories listing, which is generated in getDatatable.
|
||||
*
|
||||
* @author [A. Gianotto] [<snipe@snipe.net>]
|
||||
* @since [v1.0]
|
||||
* @return View
|
||||
* @throws \Illuminate\Auth\Access\AuthorizationException
|
||||
*/
|
||||
public function index()
|
||||
{
|
||||
$this->authorize('index', AssetModel::class);
|
||||
|
@ -45,29 +34,31 @@ class AssetModelsController extends Controller
|
|||
}
|
||||
|
||||
/**
|
||||
* Returns a view containing the asset model creation form.
|
||||
*
|
||||
* @author [A. Gianotto] [<snipe@snipe.net>]
|
||||
* @since [v1.0]
|
||||
* @return View
|
||||
*/
|
||||
* Returns a view containing the asset model creation form.
|
||||
*
|
||||
* @author [A. Gianotto] [<snipe@snipe.net>]
|
||||
* @since [v1.0]
|
||||
* @return View
|
||||
* @throws \Illuminate\Auth\Access\AuthorizationException
|
||||
*/
|
||||
public function create()
|
||||
{
|
||||
$this->authorize('create', AssetModel::class);
|
||||
$category_type = 'asset';
|
||||
return view('models/edit')->with('category_type',$category_type)
|
||||
->with('depreciation_list', Helper::depreciationList())
|
||||
->with('item', new AssetModel);
|
||||
return view('models/edit')->with('category_type', 'asset')
|
||||
->with('depreciation_list', Helper::depreciationList())
|
||||
->with('item', new AssetModel);
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Validate and process the new Asset Model data.
|
||||
*
|
||||
* @author [A. Gianotto] [<snipe@snipe.net>]
|
||||
* @since [v1.0]
|
||||
* @return Redirect
|
||||
*/
|
||||
* Validate and process the new Asset Model data.
|
||||
*
|
||||
* @author [A. Gianotto] [<snipe@snipe.net>]
|
||||
* @since [v1.0]
|
||||
* @param ImageUploadRequest $request
|
||||
* @return Redirect
|
||||
* @throws \Illuminate\Auth\Access\AuthorizationException
|
||||
*/
|
||||
public function store(ImageUploadRequest $request)
|
||||
{
|
||||
|
||||
|
@ -90,23 +81,7 @@ class AssetModelsController extends Controller
|
|||
$model->fieldset_id = e($request->input('custom_fieldset'));
|
||||
}
|
||||
|
||||
if (Input::file('image')) {
|
||||
|
||||
$image = Input::file('image');
|
||||
$file_name = str_slug($image->getClientOriginalName()) . "." . $image->getClientOriginalExtension();
|
||||
$path = app('models_upload_path');
|
||||
|
||||
if ($image->getClientOriginalExtension()!='svg') {
|
||||
Image::make($image->getRealPath())->resize(800, null, function ($constraint) {
|
||||
$constraint->aspectRatio();
|
||||
$constraint->upsize();
|
||||
})->save($path.'/'.$file_name);
|
||||
} else {
|
||||
$image->move($path, $file_name);
|
||||
}
|
||||
$model->image = $file_name;
|
||||
|
||||
}
|
||||
$model = $request->handleImages($model);
|
||||
|
||||
// Was it created?
|
||||
if ($model->save()) {
|
||||
|
@ -121,13 +96,14 @@ class AssetModelsController extends Controller
|
|||
}
|
||||
|
||||
/**
|
||||
* Returns a view containing the asset model edit form.
|
||||
*
|
||||
* @author [A. Gianotto] [<snipe@snipe.net>]
|
||||
* @since [v1.0]
|
||||
* @param int $modelId
|
||||
* @return View
|
||||
*/
|
||||
* Returns a view containing the asset model edit form.
|
||||
*
|
||||
* @author [A. Gianotto] [<snipe@snipe.net>]
|
||||
* @since [v1.0]
|
||||
* @param int $modelId
|
||||
* @return View
|
||||
* @throws \Illuminate\Auth\Access\AuthorizationException
|
||||
*/
|
||||
public function edit($modelId = null)
|
||||
{
|
||||
$this->authorize('update', AssetModel::class);
|
||||
|
@ -144,14 +120,16 @@ class AssetModelsController extends Controller
|
|||
|
||||
|
||||
/**
|
||||
* Validates and processes form data from the edit
|
||||
* Asset Model form based on the model ID passed.
|
||||
*
|
||||
* @author [A. Gianotto] [<snipe@snipe.net>]
|
||||
* @since [v1.0]
|
||||
* @param int $modelId
|
||||
* @return Redirect
|
||||
*/
|
||||
* Validates and processes form data from the edit
|
||||
* Asset Model form based on the model ID passed.
|
||||
*
|
||||
* @author [A. Gianotto] [<snipe@snipe.net>]
|
||||
* @since [v1.0]
|
||||
* @param ImageUploadRequest $request
|
||||
* @param int $modelId
|
||||
* @return Redirect
|
||||
* @throws \Illuminate\Auth\Access\AuthorizationException
|
||||
*/
|
||||
public function update(ImageUploadRequest $request, $modelId = null)
|
||||
{
|
||||
$this->authorize('update', AssetModel::class);
|
||||
|
@ -182,37 +160,7 @@ class AssetModelsController extends Controller
|
|||
}
|
||||
}
|
||||
|
||||
$old_image = $model->image;
|
||||
|
||||
// Set the model's image property to null if the image is being deleted
|
||||
if ($request->input('image_delete') == 1) {
|
||||
$model->image = null;
|
||||
}
|
||||
|
||||
if ($request->file('image')) {
|
||||
$image = $request->file('image');
|
||||
$file_name = $model->id.'-'.str_slug($image->getClientOriginalName()) . "." . $image->getClientOriginalExtension();
|
||||
|
||||
if ($image->getClientOriginalExtension()!='svg') {
|
||||
Image::make($image->getRealPath())->resize(800, null, function ($constraint) {
|
||||
$constraint->aspectRatio();
|
||||
$constraint->upsize();
|
||||
})->save(app('models_upload_path').$file_name);
|
||||
} else {
|
||||
$image->move(app('models_upload_path'), $file_name);
|
||||
}
|
||||
$model->image = $file_name;
|
||||
|
||||
}
|
||||
|
||||
if ((($request->file('image')) && (isset($old_image)) && ($old_image!='')) || ($request->input('image_delete') == 1)) {
|
||||
try {
|
||||
unlink(app('models_upload_path').$old_image);
|
||||
} catch (\Exception $e) {
|
||||
\Log::info($e);
|
||||
}
|
||||
}
|
||||
|
||||
$model = $request->handleImages($model);
|
||||
|
||||
if ($model->save()) {
|
||||
return redirect()->route("models.index")->with('success', trans('admin/models/message.update.success'));
|
||||
|
@ -221,14 +169,15 @@ class AssetModelsController extends Controller
|
|||
}
|
||||
|
||||
/**
|
||||
* Validate and delete the given Asset Model. An Asset Model
|
||||
* cannot be deleted if there are associated assets.
|
||||
*
|
||||
* @author [A. Gianotto] [<snipe@snipe.net>]
|
||||
* @since [v1.0]
|
||||
* @param int $modelId
|
||||
* @return Redirect
|
||||
*/
|
||||
* Validate and delete the given Asset Model. An Asset Model
|
||||
* cannot be deleted if there are associated assets.
|
||||
*
|
||||
* @author [A. Gianotto] [<snipe@snipe.net>]
|
||||
* @since [v1.0]
|
||||
* @param int $modelId
|
||||
* @return Redirect
|
||||
* @throws \Illuminate\Auth\Access\AuthorizationException
|
||||
*/
|
||||
public function destroy($modelId)
|
||||
{
|
||||
$this->authorize('delete', AssetModel::class);
|
||||
|
@ -244,7 +193,7 @@ class AssetModelsController extends Controller
|
|||
|
||||
if ($model->image) {
|
||||
try {
|
||||
unlink(public_path().'/uploads/models/'.$model->image);
|
||||
Storage::disk('public')->delete('models/'.$model->image);
|
||||
} catch (\Exception $e) {
|
||||
\Log::info($e);
|
||||
}
|
||||
|
@ -259,13 +208,14 @@ class AssetModelsController extends Controller
|
|||
|
||||
|
||||
/**
|
||||
* Restore a given Asset Model (mark as un-deleted)
|
||||
*
|
||||
* @author [A. Gianotto] [<snipe@snipe.net>]
|
||||
* @since [v1.0]
|
||||
* @param int $modelId
|
||||
* @return Redirect
|
||||
*/
|
||||
* Restore a given Asset Model (mark as un-deleted)
|
||||
*
|
||||
* @author [A. Gianotto] [<snipe@snipe.net>]
|
||||
* @since [v1.0]
|
||||
* @param int $modelId
|
||||
* @return Redirect
|
||||
* @throws \Illuminate\Auth\Access\AuthorizationException
|
||||
*/
|
||||
public function getRestore($modelId = null)
|
||||
{
|
||||
$this->authorize('create', AssetModel::class);
|
||||
|
@ -273,16 +223,8 @@ class AssetModelsController extends Controller
|
|||
$model = AssetModel::withTrashed()->find($modelId);
|
||||
|
||||
if (isset($model->id)) {
|
||||
|
||||
// Restore the model
|
||||
$model->restore();
|
||||
|
||||
// Prepare the success message
|
||||
$success = trans('admin/models/message.restore.success');
|
||||
|
||||
// Redirect back
|
||||
return redirect()->route('models.index')->with('success', $success);
|
||||
|
||||
return redirect()->route('models.index')->with('success', trans('admin/models/message.restore.success'));
|
||||
}
|
||||
return redirect()->back()->with('error', trans('admin/models/message.not_found'));
|
||||
|
||||
|
@ -290,13 +232,14 @@ class AssetModelsController extends Controller
|
|||
|
||||
|
||||
/**
|
||||
* Get the model information to present to the model view page
|
||||
*
|
||||
* @author [A. Gianotto] [<snipe@snipe.net>]
|
||||
* @since [v1.0]
|
||||
* @param int $modelId
|
||||
* @return View
|
||||
*/
|
||||
* Get the model information to present to the model view page
|
||||
*
|
||||
* @author [A. Gianotto] [<snipe@snipe.net>]
|
||||
* @since [v1.0]
|
||||
* @param int $modelId
|
||||
* @return View
|
||||
* @throws \Illuminate\Auth\Access\AuthorizationException
|
||||
*/
|
||||
public function show($modelId = null)
|
||||
{
|
||||
$this->authorize('view', AssetModel::class);
|
||||
|
@ -305,11 +248,8 @@ class AssetModelsController extends Controller
|
|||
if (isset($model->id)) {
|
||||
return view('models/view', compact('model'));
|
||||
}
|
||||
// Prepare the error message
|
||||
$error = trans('admin/models/message.does_not_exist', compact('id'));
|
||||
|
||||
// Redirect to the user management page
|
||||
return redirect()->route('models.index')->with('error', $error);
|
||||
return redirect()->route('models.index')->with('error', trans('admin/models/message.does_not_exist'));
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -331,12 +271,10 @@ class AssetModelsController extends Controller
|
|||
$model->id = null;
|
||||
|
||||
// Show the page
|
||||
$view = View::make('models/edit');
|
||||
$view->with('depreciation_list', Helper::depreciationList());
|
||||
$view->with('item', $model);
|
||||
$view->with('clone_model', $model_to_clone);
|
||||
return $view;
|
||||
|
||||
return view('models/edit')
|
||||
->with('depreciation_list', Helper::depreciationList())
|
||||
->with('item', $model)
|
||||
->with('clone_model', $model_to_clone);
|
||||
}
|
||||
|
||||
|
||||
|
@ -350,8 +288,7 @@ class AssetModelsController extends Controller
|
|||
*/
|
||||
public function getCustomFields($modelId)
|
||||
{
|
||||
$model = AssetModel::find($modelId);
|
||||
return view("models.custom_fields_form")->with("model", $model);
|
||||
return view("models.custom_fields_form")->with("model", AssetModel::find($modelId));
|
||||
}
|
||||
|
||||
|
||||
|
|
|
@ -1,25 +1,29 @@
|
|||
<?php
|
||||
|
||||
namespace App\Http\Controllers;
|
||||
namespace App\Http\Controllers\Assets;
|
||||
|
||||
use App\Events\CheckoutableCheckedIn;
|
||||
use App\Helpers\Helper;
|
||||
use App\Http\Controllers\Controller;
|
||||
use App\Http\Requests\AssetCheckinRequest;
|
||||
use App\Models\Asset;
|
||||
use Illuminate\Http\Request;
|
||||
use Illuminate\Support\Facades\Auth;
|
||||
use Illuminate\Support\Facades\Redirect;
|
||||
use Illuminate\Support\Facades\View;
|
||||
|
||||
class AssetCheckinController extends Controller
|
||||
{
|
||||
|
||||
/**
|
||||
* Returns a view that presents a form to check an asset back into inventory.
|
||||
*
|
||||
* @author [A. Gianotto] [<snipe@snipe.net>]
|
||||
* @param int $assetId
|
||||
* @param string $backto
|
||||
* @since [v1.0]
|
||||
* @return View
|
||||
*/
|
||||
* Returns a view that presents a form to check an asset back into inventory.
|
||||
*
|
||||
* @author [A. Gianotto] [<snipe@snipe.net>]
|
||||
* @param int $assetId
|
||||
* @param string $backto
|
||||
* @return View
|
||||
* @throws \Illuminate\Auth\Access\AuthorizationException
|
||||
* @since [v1.0]
|
||||
*/
|
||||
public function create($assetId, $backto = null)
|
||||
{
|
||||
// Check if the asset exists
|
||||
|
@ -40,6 +44,7 @@ class AssetCheckinController extends Controller
|
|||
* @param int $assetId
|
||||
* @param null $backto
|
||||
* @return Redirect
|
||||
* @throws \Illuminate\Auth\Access\AuthorizationException
|
||||
* @since [v1.0]
|
||||
*/
|
||||
public function store(AssetCheckinRequest $request, $assetId = null, $backto = null)
|
||||
|
@ -77,21 +82,15 @@ class AssetCheckinController extends Controller
|
|||
$asset->location_id = e($request->get('location_id'));
|
||||
}
|
||||
|
||||
$checkin_at = date('Y-m-d');
|
||||
if($request->filled('checkin_at')){
|
||||
$checkin_at = $request->input('checkin_at');
|
||||
}
|
||||
|
||||
// Was the asset updated?
|
||||
if ($asset->save()) {
|
||||
$logaction = $asset->logCheckin($target, e(request('note')));
|
||||
|
||||
$data['log_id'] = $logaction->id;
|
||||
$data['first_name'] = get_class($target) == User::class ? $target->first_name : '';
|
||||
$data['last_name'] = get_class($target) == User::class ? $target->last_name : '';
|
||||
$data['item_name'] = $asset->present()->name();
|
||||
$data['checkin_date'] = $logaction->created_at;
|
||||
$data['item_tag'] = $asset->asset_tag;
|
||||
$data['item_serial'] = $asset->serial;
|
||||
$data['note'] = $logaction->note;
|
||||
$data['manufacturer_name'] = $asset->model->manufacturer->name;
|
||||
$data['model_name'] = $asset->model->name;
|
||||
$data['model_number'] = $asset->model->model_number;
|
||||
|
||||
event(new CheckoutableCheckedIn($asset, $target, Auth::user(), $request->input('note'), $checkin_at));
|
||||
|
||||
if ((isset($user)) && ($backto =='user')) {
|
||||
return redirect()->route("users.show", $user->id)->with('success', trans('admin/hardware/message.checkin.success'));
|
|
@ -1,15 +1,14 @@
|
|||
<?php
|
||||
|
||||
namespace App\Http\Controllers;
|
||||
namespace App\Http\Controllers\Assets;
|
||||
|
||||
|
||||
use App\Exceptions\CheckoutNotAllowed;
|
||||
use App\Http\Controllers\CheckInOutRequest;
|
||||
use App\Http\Controllers\Controller;
|
||||
use App\Http\Requests\AssetCheckoutRequest;
|
||||
use App\Models\Asset;
|
||||
use App\Models\Location;
|
||||
use App\Models\User;
|
||||
use Illuminate\Database\Eloquent\ModelNotFoundException;
|
||||
use Illuminate\Http\Request;
|
||||
use Illuminate\Support\Facades\Auth;
|
||||
|
||||
class AssetCheckoutController extends Controller
|
|
@ -1,13 +1,14 @@
|
|||
<?php
|
||||
|
||||
namespace App\Http\Controllers;
|
||||
namespace App\Http\Controllers\Assets;
|
||||
|
||||
use App\Helpers\Helper;
|
||||
|
||||
use App\Http\Controllers\Controller;
|
||||
use App\Http\Requests\AssetFileRequest;
|
||||
use App\Models\Actionlog;
|
||||
use App\Models\Asset;
|
||||
use Illuminate\Http\Request;
|
||||
use Illuminate\Support\Facades\Response;
|
||||
use Illuminate\Support\Facades\Storage;
|
||||
|
||||
class AssetFilesController extends Controller
|
||||
{
|
||||
|
@ -19,6 +20,7 @@ class AssetFilesController extends Controller
|
|||
* @param int $assetId
|
||||
* @return Redirect
|
||||
* @since [v1.0]
|
||||
* @throws \Illuminate\Auth\Access\AuthorizationException
|
||||
*/
|
||||
public function store(AssetFileRequest $request, $assetId = null)
|
||||
{
|
||||
|
@ -28,15 +30,15 @@ class AssetFilesController extends Controller
|
|||
|
||||
$this->authorize('update', $asset);
|
||||
|
||||
$destinationPath = config('app.private_uploads').'/assets';
|
||||
|
||||
if ($request->hasFile('file')) {
|
||||
|
||||
if (!Storage::exists('private_uploads/assets')) Storage::makeDirectory('private_uploads/assets', 775);
|
||||
|
||||
foreach ($request->file('file') as $file) {
|
||||
$extension = $file->getClientOriginalExtension();
|
||||
$filename = 'hardware-'.$asset->id.'-'.str_random(8);
|
||||
$filename .= '-'.str_slug(basename($file->getClientOriginalName(), '.'.$extension)).'.'.$extension;
|
||||
$file->move($destinationPath, $filename);
|
||||
$asset->logUpload($filename, e($request->get('notes')));
|
||||
$file_name = 'hardware-'.$asset->id.'-'.str_random(8).'-'.str_slug(basename($file->getClientOriginalName(), '.'.$extension)).'.'.$extension;
|
||||
Storage::put('private_uploads/assets/'.$file_name, file_get_contents($file));
|
||||
$asset->logUpload($file_name, e($request->get('notes')));
|
||||
}
|
||||
return redirect()->back()->with('success', trans('admin/hardware/message.upload.success'));
|
||||
}
|
||||
|
@ -45,14 +47,15 @@ class AssetFilesController extends Controller
|
|||
}
|
||||
|
||||
/**
|
||||
* Check for permissions and display the file.
|
||||
*
|
||||
* @author [A. Gianotto] [<snipe@snipe.net>]
|
||||
* @param int $assetId
|
||||
* @param int $fileId
|
||||
* @since [v1.0]
|
||||
* @return View
|
||||
*/
|
||||
* Check for permissions and display the file.
|
||||
*
|
||||
* @author [A. Gianotto] [<snipe@snipe.net>]
|
||||
* @param int $assetId
|
||||
* @param int $fileId
|
||||
* @since [v1.0]
|
||||
* @return View
|
||||
* @throws \Illuminate\Auth\Access\AuthorizationException
|
||||
*/
|
||||
public function show($assetId = null, $fileId = null, $download = true)
|
||||
{
|
||||
$asset = Asset::find($assetId);
|
||||
|
@ -65,24 +68,25 @@ class AssetFilesController extends Controller
|
|||
->header('Content-Type', 'text/plain');
|
||||
}
|
||||
|
||||
$file = $log->get_src('assets');
|
||||
$file = 'private_uploads/assets/'.$log->filename;
|
||||
\Log::debug('Checking for '.$file);
|
||||
|
||||
if ($log->action_type =='audit') {
|
||||
$file = $log->get_src('audits');
|
||||
$file = 'private_uploads/audits/'.$log->filename;
|
||||
}
|
||||
|
||||
if (!file_exists($file)) {
|
||||
if (!Storage::exists($file)) {
|
||||
return response('File '.$file.' not found on server', 404)
|
||||
->header('Content-Type', 'text/plain');
|
||||
}
|
||||
|
||||
if ($download != 'true') {
|
||||
if ($contents = file_get_contents($file)) {
|
||||
return Response::make($contents)->header('Content-Type', mime_content_type($file));
|
||||
if ($contents = file_get_contents(Storage::url($file))) {
|
||||
return Response::make(Storage::url($file)->header('Content-Type', mime_content_type($file)));
|
||||
}
|
||||
return JsonResponse::create(["error" => "Failed validation: "], 500);
|
||||
}
|
||||
return Response::download($file);
|
||||
return Storage::download($file);
|
||||
}
|
||||
// Prepare the error message
|
||||
$error = trans('admin/hardware/message.does_not_exist', ['id' => $fileId]);
|
||||
|
@ -92,35 +96,35 @@ class AssetFilesController extends Controller
|
|||
}
|
||||
|
||||
/**
|
||||
* Delete the associated file
|
||||
*
|
||||
* @author [A. Gianotto] [<snipe@snipe.net>]
|
||||
* @param int $assetId
|
||||
* @param int $fileId
|
||||
* @since [v1.0]
|
||||
* @return View
|
||||
*/
|
||||
* Delete the associated file
|
||||
*
|
||||
* @author [A. Gianotto] [<snipe@snipe.net>]
|
||||
* @param int $assetId
|
||||
* @param int $fileId
|
||||
* @since [v1.0]
|
||||
* @return View
|
||||
* @throws \Illuminate\Auth\Access\AuthorizationException
|
||||
*/
|
||||
public function destroy($assetId = null, $fileId = null)
|
||||
{
|
||||
$asset = Asset::find($assetId);
|
||||
$this->authorize('update', $asset);
|
||||
$destinationPath = config('app.private_uploads').'/imports/assets';
|
||||
$rel_path = 'storage/private_uploads/assets';
|
||||
|
||||
// the asset is valid
|
||||
if (isset($asset->id)) {
|
||||
$this->authorize('update', $asset);
|
||||
|
||||
$log = Actionlog::find($fileId);
|
||||
if ($log) {
|
||||
$full_filename = $destinationPath.'/'.$log->filename;
|
||||
if (file_exists($full_filename)) {
|
||||
unlink($destinationPath.'/'.$log->filename);
|
||||
if (file_exists(base_path().'/'.$rel_path.'/'.$log->filename)) {
|
||||
Storage::disk('public')->delete($rel_path.'/'.$log->filename);
|
||||
}
|
||||
$log->delete();
|
||||
return redirect()->back()->with('success', trans('admin/hardware/message.deletefile.success'));
|
||||
}
|
||||
return redirect()->back()->with('error', 'Could not find matching upload log.');
|
||||
|
||||
$log->delete();
|
||||
return redirect()->back()
|
||||
->with('success', trans('admin/hardware/message.deletefile.success'));
|
||||
}
|
||||
|
||||
// Redirect to the hardware management page
|
|
@ -1,44 +1,34 @@
|
|||
<?php
|
||||
namespace App\Http\Controllers;
|
||||
namespace App\Http\Controllers\Assets;
|
||||
|
||||
use App\Helpers\Helper;
|
||||
use App\Http\Requests\AssetCheckinRequest;
|
||||
use App\Http\Requests\AssetCheckoutRequest;
|
||||
use App\Http\Requests\AssetFileRequest;
|
||||
use App\Http\Requests\AssetRequest;
|
||||
use App\Http\Requests\ItemImportRequest;
|
||||
use App\Http\Controllers\Controller;
|
||||
use App\Http\Requests\ImageUploadRequest;
|
||||
use App\Models\Actionlog;
|
||||
use App\Models\Asset;
|
||||
use App\Models\AssetModel;
|
||||
use App\Models\CheckoutRequest;
|
||||
use App\Models\Company;
|
||||
use App\Models\CustomField;
|
||||
use App\Models\Import;
|
||||
use App\Models\Location;
|
||||
use App\Models\Setting;
|
||||
use App\Models\User;
|
||||
use Artisan;
|
||||
use Auth;
|
||||
use Carbon\Carbon;
|
||||
use Config;
|
||||
use DB;
|
||||
use Gate;
|
||||
use Illuminate\Http\Request;
|
||||
use Image;
|
||||
use Illuminate\Support\Facades\Cache;
|
||||
use Illuminate\Support\Facades\Storage;
|
||||
use Input;
|
||||
use Lang;
|
||||
use League\Csv\Reader;
|
||||
use Log;
|
||||
use Mail;
|
||||
use League\Csv\Statement;
|
||||
use Paginator;
|
||||
use Redirect;
|
||||
use Response;
|
||||
use Slack;
|
||||
use Str;
|
||||
use Symfony\Component\HttpFoundation\File\Exception\FileException;
|
||||
use TCPDF;
|
||||
use Validator;
|
||||
use View;
|
||||
use App\Models\CheckoutRequest;
|
||||
|
||||
/**
|
||||
* This class controls all actions related to assets for
|
||||
|
@ -66,7 +56,9 @@ class AssetsController extends Controller
|
|||
* @author [A. Gianotto] [<snipe@snipe.net>]
|
||||
* @see AssetController::getDatatable() method that generates the JSON response
|
||||
* @since [v1.0]
|
||||
* @param Request $request
|
||||
* @return View
|
||||
* @throws \Illuminate\Auth\Access\AuthorizationException
|
||||
*/
|
||||
public function index(Request $request)
|
||||
{
|
||||
|
@ -110,75 +102,63 @@ class AssetsController extends Controller
|
|||
* @since [v1.0]
|
||||
* @return Redirect
|
||||
*/
|
||||
public function store(AssetRequest $request)
|
||||
public function store(ImageUploadRequest $request)
|
||||
{
|
||||
$this->authorize(Asset::class);
|
||||
|
||||
// Handle asset tags - there could be one, or potentially many.
|
||||
// This is only necessary on create, not update, since bulk editing is handled
|
||||
// differently
|
||||
$asset_tags = $request->input('asset_tags');
|
||||
|
||||
$asset = new Asset();
|
||||
$asset->model()->associate(AssetModel::find($request->input('model_id')));
|
||||
$success = false;
|
||||
$serials = $request->input('serials');
|
||||
|
||||
$asset->name = $request->input('name');
|
||||
$asset->serial = $request->input('serial');
|
||||
$asset->company_id = Company::getIdForCurrentUser($request->input('company_id'));
|
||||
$asset->model_id = $request->input('model_id');
|
||||
$asset->order_number = $request->input('order_number');
|
||||
$asset->notes = $request->input('notes');
|
||||
$asset->asset_tag = $request->input('asset_tag');
|
||||
$asset->user_id = Auth::id();
|
||||
$asset->archived = '0';
|
||||
$asset->physical = '1';
|
||||
$asset->depreciate = '0';
|
||||
$asset->status_id = request('status_id', 0);
|
||||
$asset->warranty_months = request('warranty_months', null);
|
||||
$asset->purchase_cost = Helper::ParseFloat($request->get('purchase_cost'));
|
||||
$asset->purchase_date = request('purchase_date', null);
|
||||
$asset->assigned_to = request('assigned_to', null);
|
||||
$asset->supplier_id = request('supplier_id', 0);
|
||||
$asset->requestable = request('requestable', 0);
|
||||
$asset->rtd_location_id = request('rtd_location_id', null);
|
||||
for ($a = 1; $a <= count($asset_tags); $a++) {
|
||||
|
||||
if ($asset->assigned_to=='') {
|
||||
$asset->location_id = $request->input('rtd_location_id', null);
|
||||
}
|
||||
$asset = new Asset();
|
||||
$asset->model()->associate(AssetModel::find($request->input('model_id')));
|
||||
$asset->name = $request->input('name');
|
||||
|
||||
// Check for a corresponding serial
|
||||
if (($serials) && (array_key_exists($a, $serials))) {
|
||||
$asset->serial = $serials[$a];
|
||||
}
|
||||
|
||||
if (($asset_tags) && (array_key_exists($a, $asset_tags))) {
|
||||
$asset->asset_tag = $asset_tags[$a];
|
||||
}
|
||||
|
||||
$asset->company_id = Company::getIdForCurrentUser($request->input('company_id'));
|
||||
$asset->model_id = $request->input('model_id');
|
||||
$asset->order_number = $request->input('order_number');
|
||||
$asset->notes = $request->input('notes');
|
||||
$asset->user_id = Auth::id();
|
||||
$asset->archived = '0';
|
||||
$asset->physical = '1';
|
||||
$asset->depreciate = '0';
|
||||
$asset->status_id = request('status_id', 0);
|
||||
$asset->warranty_months = request('warranty_months', null);
|
||||
$asset->purchase_cost = Helper::ParseFloat($request->get('purchase_cost'));
|
||||
$asset->purchase_date = request('purchase_date', null);
|
||||
$asset->assigned_to = request('assigned_to', null);
|
||||
$asset->supplier_id = request('supplier_id', 0);
|
||||
$asset->requestable = request('requestable', 0);
|
||||
$asset->rtd_location_id = request('rtd_location_id', null);
|
||||
|
||||
if (!empty($settings->audit_interval)) {
|
||||
$asset->next_audit_date = Carbon::now()->addMonths($settings->audit_interval)->toDateString();
|
||||
}
|
||||
|
||||
if ($asset->assigned_to=='') {
|
||||
$asset->location_id = $request->input('rtd_location_id', null);
|
||||
}
|
||||
|
||||
// Create the image (if one was chosen.)
|
||||
if ($request->filled('image')) {
|
||||
$image = $request->input('image');
|
||||
|
||||
// After modification, the image is prefixed by mime info like the following:
|
||||
// data:image/jpeg;base64,; This causes the image library to be unhappy, so we need to remove it.
|
||||
$header = explode(';', $image, 2)[0];
|
||||
// Grab the image type from the header while we're at it.
|
||||
$extension = substr($header, strpos($header, '/')+1);
|
||||
// Start reading the image after the first comma, postceding the base64.
|
||||
$image = substr($image, strpos($image, ',')+1);
|
||||
|
||||
$file_name = str_random(25).".".$extension;
|
||||
|
||||
$directory= public_path('uploads/assets/');
|
||||
// Check if the uploads directory exists. If not, try to create it.
|
||||
if (!file_exists($directory)) {
|
||||
mkdir($directory, 0755, true);
|
||||
}
|
||||
$path = public_path('uploads/assets/'.$file_name);
|
||||
try {
|
||||
Image::make($image)->resize(800, 800, function ($constraint) {
|
||||
$constraint->aspectRatio();
|
||||
$constraint->upsize();
|
||||
})->save($path);
|
||||
$asset->image = $file_name;
|
||||
} catch (\Exception $e) {
|
||||
\Input::flash();
|
||||
$messageBag = new \Illuminate\Support\MessageBag();
|
||||
$messageBag->add('image', $e->getMessage());
|
||||
\Session()->flash('errors', \Session::get('errors', new \Illuminate\Support\ViewErrorBag)
|
||||
->put('default', $messageBag));
|
||||
return response()->json(['image' => $e->getMessage()], 422);
|
||||
}
|
||||
if ($request->has('image')) {
|
||||
$asset = $request->handleImages($asset);
|
||||
}
|
||||
|
||||
|
||||
// Update custom fields in the database.
|
||||
// Validation for these fields is handled through the AssetRequest form request
|
||||
$model = AssetModel::find($request->get('model_id'));
|
||||
|
@ -195,31 +175,39 @@ class AssetsController extends Controller
|
|||
}
|
||||
}
|
||||
|
||||
// Was the asset created?
|
||||
if ($asset->save()) {
|
||||
// Validate the asset before saving
|
||||
if ($asset->isValid() && $asset->save()) {
|
||||
|
||||
if (request('assigned_user')) {
|
||||
$target = User::find(request('assigned_user'));
|
||||
$location = $target->location_id;
|
||||
} elseif (request('assigned_asset')) {
|
||||
$target = Asset::find(request('assigned_asset'));
|
||||
$location = $target->location_id;
|
||||
} elseif (request('assigned_location')) {
|
||||
$target = Location::find(request('assigned_location'));
|
||||
$location = $target->id;
|
||||
}
|
||||
|
||||
if (isset($target)) {
|
||||
$asset->checkOut($target, Auth::user(), date('Y-m-d H:i:s'), '', 'Checked out on asset creation', e($request->get('name')), $location);
|
||||
}
|
||||
|
||||
$success = true;
|
||||
|
||||
|
||||
if (request('assigned_user')) {
|
||||
$target = User::find(request('assigned_user'));
|
||||
$location = $target->location_id;
|
||||
} elseif (request('assigned_asset')) {
|
||||
$target = Asset::find(request('assigned_asset'));
|
||||
$location = $target->location_id;
|
||||
} elseif (request('assigned_location')) {
|
||||
$target = Location::find(request('assigned_location'));
|
||||
$location = $target->id;
|
||||
}
|
||||
|
||||
if (isset($target)) {
|
||||
$asset->checkOut($target, Auth::user(), date('Y-m-d H:i:s'), '', 'Checked out on asset creation', e($request->get('name')), $location);
|
||||
}
|
||||
// Redirect to the asset listing page
|
||||
\Session::flash('success', trans('admin/hardware/message.create.success'));
|
||||
return response()->json(['redirect_url' => route('hardware.index')]);
|
||||
}
|
||||
\Input::flash();
|
||||
\Session::flash('errors', $asset->getErrors());
|
||||
return response()->json(['errors' => $asset->getErrors()], 500);
|
||||
|
||||
if ($success) {
|
||||
// Redirect to the asset listing page
|
||||
return redirect()->route('hardware.index')
|
||||
->with('success', trans('admin/hardware/message.create.success'));
|
||||
}
|
||||
|
||||
return redirect()->back()->withInput()->withErrors($asset->getErrors());
|
||||
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -297,7 +285,7 @@ class AssetsController extends Controller
|
|||
* @return Redirect
|
||||
*/
|
||||
|
||||
public function update(AssetRequest $request, $assetId = null)
|
||||
public function update(ImageUploadRequest $request, $assetId = null)
|
||||
{
|
||||
// Check if the asset exists
|
||||
if (!$asset = Asset::find($assetId)) {
|
||||
|
@ -333,47 +321,18 @@ class AssetsController extends Controller
|
|||
|
||||
|
||||
// Update the asset data
|
||||
$asset_tag = $request->input('asset_tags');
|
||||
$serial = $request->input('serials');
|
||||
$asset->name = $request->input('name');
|
||||
$asset->serial = $request->input('serial');
|
||||
$asset->serial = $serial[1];
|
||||
$asset->company_id = Company::getIdForCurrentUser($request->input('company_id'));
|
||||
$asset->model_id = $request->input('model_id');
|
||||
$asset->order_number = $request->input('order_number');
|
||||
$asset->asset_tag = $request->input('asset_tag');
|
||||
$asset->asset_tag = $asset_tag[1];
|
||||
$asset->notes = $request->input('notes');
|
||||
$asset->physical = '1';
|
||||
|
||||
// Update the image
|
||||
if ($request->filled('image')) {
|
||||
$image = $request->input('image');
|
||||
// See postCreate for more explaination of the following.
|
||||
$header = explode(';', $image, 2)[0];
|
||||
$extension = substr($header, strpos($header, '/')+1);
|
||||
$image = substr($image, strpos($image, ',')+1);
|
||||
|
||||
$directory= public_path('uploads/assets/');
|
||||
// Check if the uploads directory exists. If not, try to create it.
|
||||
if (!file_exists($directory)) {
|
||||
mkdir($directory, 0755, true);
|
||||
}
|
||||
|
||||
$file_name = str_random(25).".".$extension;
|
||||
$path = public_path('uploads/assets/'.$file_name);
|
||||
try {
|
||||
Image::make($image)->resize(800, 800, function ($constraint) {
|
||||
$constraint->aspectRatio();
|
||||
$constraint->upsize();
|
||||
})->save($path);
|
||||
$asset->image = $file_name;
|
||||
} catch (\Exception $e) {
|
||||
\Input::flash();
|
||||
$messageBag = new \Illuminate\Support\MessageBag();
|
||||
$messageBag->add('image', $e->getMessage());
|
||||
\Session()->flash('errors', \Session::get('errors', new \Illuminate\Support\ViewErrorBag)
|
||||
->put('default', $messageBag));
|
||||
return response()->json(['image' => $e->getMessage()], 422);
|
||||
}
|
||||
$asset->image = $file_name;
|
||||
}
|
||||
$asset = $request->handleImages($asset);
|
||||
|
||||
// Update custom fields in the database.
|
||||
// Validation for these fields is handlded through the AssetRequest form request
|
||||
|
@ -394,13 +353,12 @@ class AssetsController extends Controller
|
|||
|
||||
|
||||
if ($asset->save()) {
|
||||
// Redirect to the new asset page
|
||||
\Session::flash('success', trans('admin/hardware/message.update.success'));
|
||||
return response()->json(['redirect_url' => route("hardware.show", $assetId)]);
|
||||
return redirect()->route("hardware.show", $assetId)
|
||||
->with('success', trans('admin/hardware/message.update.success'));
|
||||
}
|
||||
\Input::flash();
|
||||
\Session::flash('errors', $asset->getErrors());
|
||||
return response()->json(['errors' => $asset->getErrors()], 500);
|
||||
|
||||
return redirect()->back()->withInput()->withErrors()->with('error', trans('admin/hardware/message.does_not_exist'));
|
||||
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -425,6 +383,14 @@ class AssetsController extends Controller
|
|||
->where('id', $asset->id)
|
||||
->update(array('assigned_to' => null));
|
||||
|
||||
if ($asset->image) {
|
||||
try {
|
||||
Storage::disk('public')->delete('assets'.'/'.$asset->image);
|
||||
} catch (\Exception $e) {
|
||||
\Log::debug($e);
|
||||
}
|
||||
}
|
||||
|
||||
$asset->delete();
|
||||
|
||||
return redirect()->route('hardware.index')->with('success', trans('admin/hardware/message.delete.success'));
|
||||
|
@ -515,6 +481,29 @@ class AssetsController extends Controller
|
|||
}
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Return a label for an individual asset.
|
||||
*
|
||||
* @author [L. Swartzendruber] [<logan.swartzendruber@gmail.com>
|
||||
* @param int $assetId
|
||||
* @return View
|
||||
*/
|
||||
public function getLabel($assetId = null)
|
||||
{
|
||||
if (isset($assetId)) {
|
||||
$asset = Asset::find($assetId);
|
||||
$this->authorize('view', $asset);
|
||||
|
||||
return view('hardware/labels')
|
||||
->with('assets', Asset::find($asset))
|
||||
->with('settings', Setting::getSettings())
|
||||
->with('bulkedit', false)
|
||||
->with('count', 0);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Returns a view that presents a form to clone an asset.
|
||||
*
|
||||
|
@ -554,7 +543,7 @@ class AssetsController extends Controller
|
|||
*/
|
||||
public function getImportHistory()
|
||||
{
|
||||
$this->authorize('checkout', Asset::class);
|
||||
$this->authorize('admin');
|
||||
return view('hardware/history');
|
||||
}
|
||||
|
||||
|
@ -578,7 +567,6 @@ class AssetsController extends Controller
|
|||
if (!ini_get("auto_detect_line_endings")) {
|
||||
ini_set("auto_detect_line_endings", '1');
|
||||
}
|
||||
|
||||
$csv = Reader::createFromPath(Input::file('user_import_csv'));
|
||||
$csv->setHeaderOffset(0);
|
||||
$results = $csv->getRecords();
|
||||
|
@ -586,8 +574,6 @@ class AssetsController extends Controller
|
|||
$status = array();
|
||||
$status['error'] = array();
|
||||
$status['success'] = array();
|
||||
|
||||
|
||||
foreach ($results as $row) {
|
||||
if (is_array($row)) {
|
||||
$row = array_change_key_case($row, CASE_LOWER);
|
||||
|
@ -596,29 +582,23 @@ class AssetsController extends Controller
|
|||
$item[$asset_tag] = array();
|
||||
}
|
||||
$batch_counter = count($item[$asset_tag]);
|
||||
|
||||
$item[$asset_tag][$batch_counter]['checkout_date'] = Carbon::parse(Helper::array_smart_fetch($row, "checkout date"))->format('Y-m-d H:i:s');
|
||||
$item[$asset_tag][$batch_counter]['checkin_date'] = Carbon::parse(Helper::array_smart_fetch($row, "checkin date"))->format('Y-m-d H:i:s');
|
||||
\Log::debug($item[$asset_tag][$batch_counter]['checkin_date']);
|
||||
|
||||
$item[$asset_tag][$batch_counter]['asset_tag'] = Helper::array_smart_fetch($row, "asset tag");
|
||||
$item[$asset_tag][$batch_counter]['name'] = Helper::array_smart_fetch($row, "name");
|
||||
$item[$asset_tag][$batch_counter]['email'] = Helper::array_smart_fetch($row, "email");
|
||||
|
||||
if ($asset = Asset::where('asset_tag', '=', $asset_tag)->first()) {
|
||||
$item[$asset_tag][$batch_counter]['asset_id'] = $asset->id;
|
||||
|
||||
$base_username = User::generateFormattedNameFromFullName(Setting::getSettings()->username_format, $item[$asset_tag][$batch_counter]['name']);
|
||||
$user = User::where('username', '=', $base_username['username']);
|
||||
$user_query = ' on username '.$base_username['username'];
|
||||
|
||||
if ($request->input('match_firstnamelastname')=='1') {
|
||||
$firstnamedotlastname = User::generateFormattedNameFromFullName('firstname.lastname', $item[$asset_tag][$batch_counter]['name']);
|
||||
$item[$asset_tag][$batch_counter]['username'][] = $firstnamedotlastname['username'];
|
||||
$user->orWhere('username', '=', $firstnamedotlastname['username']);
|
||||
$user_query .= ', or on username '.$firstnamedotlastname['username'];
|
||||
}
|
||||
|
||||
if ($request->input('match_flastname')=='1') {
|
||||
$flastname = User::generateFormattedNameFromFullName('filastname', $item[$asset_tag][$batch_counter]['name']);
|
||||
$item[$asset_tag][$batch_counter]['username'][] = $flastname['username'];
|
||||
|
@ -638,12 +618,10 @@ class AssetsController extends Controller
|
|||
$user_query .= ', or on username '.$user_email;
|
||||
}
|
||||
}
|
||||
|
||||
// A matching user was found
|
||||
if ($user = $user->first()) {
|
||||
$item[$asset_tag][$batch_counter]['checkedout_to'] = $user->id;
|
||||
$item[$asset_tag][$batch_counter]['user_id'] = $user->id;
|
||||
|
||||
Actionlog::firstOrCreate(array(
|
||||
'item_id' => $asset->id,
|
||||
'item_type' => Asset::class,
|
||||
|
@ -654,9 +632,7 @@ class AssetsController extends Controller
|
|||
'created_at' => $item[$asset_tag][$batch_counter]['checkout_date'],
|
||||
'action_type' => 'checkout',
|
||||
));
|
||||
|
||||
$asset->assigned_to = $user->id;
|
||||
|
||||
if ($asset->save()) {
|
||||
$status['success'][]['asset'][$asset_tag]['msg'] = 'Asset successfully matched for '.Helper::array_smart_fetch($row, "name").$user_query.' on '.$item[$asset_tag][$batch_counter]['checkout_date'];
|
||||
} else {
|
||||
|
@ -672,19 +648,16 @@ class AssetsController extends Controller
|
|||
}
|
||||
}
|
||||
}
|
||||
|
||||
// Loop through and backfill the checkins
|
||||
foreach ($item as $key => $asset_batch) {
|
||||
$total_in_batch = count($asset_batch);
|
||||
for ($x = 0; $x < $total_in_batch; $x++) {
|
||||
$next = $x + 1;
|
||||
|
||||
// Only do this if a matching user was found
|
||||
if ((array_key_exists('checkedout_to', $asset_batch[$x])) && ($asset_batch[$x]['checkedout_to']!='')) {
|
||||
if (($total_in_batch > 1) && ($x < $total_in_batch) && (array_key_exists($next, $asset_batch))) {
|
||||
$checkin_date = Carbon::parse($asset_batch[$next]['checkin_date'])->format('Y-m-d H:i:s');
|
||||
$asset_batch[$x]['real_checkin'] = $checkin_date;
|
||||
|
||||
\Log::debug($asset_batch[$next]['checkin_date']);
|
||||
\Log::debug($checkin_date);
|
||||
Actionlog::firstOrCreate(array(
|
||||
|
@ -703,6 +676,11 @@ class AssetsController extends Controller
|
|||
return view('hardware/history')->with('status', $status);
|
||||
}
|
||||
|
||||
public function sortByName(array $recordA, array $recordB): int
|
||||
{
|
||||
return strcmp($recordB['Full Name'], $recordA['Full Name']);
|
||||
}
|
||||
|
||||
/**
|
||||
* Retore a deleted asset.
|
||||
*
|
||||
|
@ -763,7 +741,7 @@ class AssetsController extends Controller
|
|||
}
|
||||
|
||||
|
||||
public function auditStore(AssetFileRequest $request, $id)
|
||||
public function auditStore(Request $request, $id)
|
||||
{
|
||||
$this->authorize('audit', Asset::class);
|
||||
|
||||
|
@ -786,24 +764,28 @@ class AssetsController extends Controller
|
|||
$asset->next_audit_date = $request->input('next_audit_date');
|
||||
$asset->last_audit_date = date('Y-m-d h:i:s');
|
||||
|
||||
// Check to see if they checked the box to update the physical location,
|
||||
// not just note it in the audit notes
|
||||
if ($request->input('update_location')=='1') {
|
||||
\Log::debug('update location in audit');
|
||||
$asset->location_id = $request->input('location_id');
|
||||
}
|
||||
|
||||
|
||||
if ($asset->save()) {
|
||||
|
||||
|
||||
$filename = '';
|
||||
|
||||
$file_name = '';
|
||||
// Upload an image, if attached
|
||||
if ($request->hasFile('image')) {
|
||||
$file = $request->file('image');
|
||||
try {
|
||||
$destinationPath = config('app.private_uploads').'/audits';
|
||||
$extension = $file->getClientOriginalExtension();
|
||||
$filename = 'audit-'.$asset->id.'-'.str_slug(basename($file->getClientOriginalName(), '.'.$extension)).'.'.$extension;
|
||||
$file->move($destinationPath, $filename);
|
||||
} catch (\Exception $e) {
|
||||
\Log::info($e);
|
||||
}
|
||||
$path = 'private_uploads/audits';
|
||||
if (!Storage::exists($path)) Storage::makeDirectory($path, 775);
|
||||
$upload = $image = $request->file('image');
|
||||
$ext = $image->getClientOriginalExtension();
|
||||
$file_name = 'audit-'.str_random(18).'.'.$ext;
|
||||
Storage::putFileAs($path, $upload, $file_name);
|
||||
}
|
||||
|
||||
$asset->logAudit($request->input('note'), $request->input('location_id'), $filename);
|
||||
|
||||
$asset->logAudit($request->input('note'), $request->input('location_id'), $file_name);
|
||||
return redirect()->to("hardware")->with('success', trans('admin/hardware/message.audit.success'));
|
||||
}
|
||||
}
|
|
@ -1,12 +1,12 @@
|
|||
<?php
|
||||
|
||||
namespace App\Http\Controllers;
|
||||
namespace App\Http\Controllers\Assets;
|
||||
|
||||
use App\Helpers\Helper;
|
||||
use App\Http\Controllers\CheckInOutRequest;
|
||||
use App\Http\Controllers\Controller;
|
||||
use App\Models\Asset;
|
||||
use App\Models\Setting;
|
||||
use App\Models\User;
|
||||
use Illuminate\Http\Request;
|
||||
use Illuminate\Support\Facades\Auth;
|
||||
use Illuminate\Support\Facades\DB;
|
||||
|
@ -14,6 +14,7 @@ use Illuminate\Support\Facades\DB;
|
|||
class BulkAssetsController extends Controller
|
||||
{
|
||||
use CheckInOutRequest;
|
||||
|
||||
/**
|
||||
* Display the bulk edit page.
|
||||
*
|
||||
|
@ -21,6 +22,7 @@ class BulkAssetsController extends Controller
|
|||
* @return View
|
||||
* @internal param int $assetId
|
||||
* @since [v2.0]
|
||||
* @throws \Illuminate\Auth\Access\AuthorizationException
|
||||
*/
|
||||
public function edit(Request $request)
|
||||
{
|
||||
|
@ -38,6 +40,7 @@ class BulkAssetsController extends Controller
|
|||
return view('hardware/labels')
|
||||
->with('assets', Asset::find($asset_ids))
|
||||
->with('settings', Setting::getSettings())
|
||||
->with('bulkedit', true)
|
||||
->with('count', 0);
|
||||
case 'delete':
|
||||
$assets = Asset::with('assignedTo', 'location')->find($asset_ids);
|
||||
|
@ -130,10 +133,11 @@ class BulkAssetsController extends Controller
|
|||
* @var Array
|
||||
*/
|
||||
private $update_array;
|
||||
|
||||
/**
|
||||
* Adds parameter to update array for an item if it exists in request
|
||||
* @param String $field field name
|
||||
* @return this Model for Chaining
|
||||
* @param String $field field name
|
||||
* @return BulkAssetsController Model for Chaining
|
||||
*/
|
||||
protected function conditionallyAddItem($field)
|
||||
{
|
||||
|
@ -147,7 +151,9 @@ class BulkAssetsController extends Controller
|
|||
* Save bulk deleted.
|
||||
*
|
||||
* @author [A. Gianotto] [<snipe@snipe.net>]
|
||||
* @param Request $request
|
||||
* @return View
|
||||
* @throws \Illuminate\Auth\Access\AuthorizationException
|
||||
* @internal param array $assets
|
||||
* @since [v2.0]
|
||||
*/
|
|
@ -49,27 +49,28 @@ class ForgotPasswordController extends Controller
|
|||
*/
|
||||
public function sendResetLinkEmail(Request $request)
|
||||
{
|
||||
$this->validate($request, ['email' => 'required|email']);
|
||||
$this->validate($request, ['username' => 'required'], ['username.required' => 'Please enter your username.']);
|
||||
|
||||
// We will send the password reset link to this user. Once we have attempted
|
||||
// to send the link, we will examine the response then see the message we
|
||||
// need to show to the user. Finally, we'll send out a proper response.
|
||||
|
||||
// Make sure the user is active, and their password is not controlled via LDAP
|
||||
$response = $this->broker()->sendResetLink(
|
||||
array_merge(
|
||||
$request->only('email'),
|
||||
['activated' => '1']
|
||||
$request->only('username'),
|
||||
['activated' => '1'],
|
||||
['ldap_import' => '0']
|
||||
)
|
||||
);
|
||||
|
||||
if ($response === \Password::RESET_LINK_SENT) {
|
||||
return redirect()->route('login')->with('status', trans($response));
|
||||
\Log::info('Password reset attempt: User '.$request->input('username').' found, password reset sent');
|
||||
} else {
|
||||
\Log::info('Password reset attempt: User '.$request->input('username').' not found or user is inactive');
|
||||
}
|
||||
|
||||
// If an error was returned by the password broker, we will get this message
|
||||
// translated so we can notify a user of the problem. We'll redirect back
|
||||
// to where the users came from so they can attempt this process again.
|
||||
return back()->withErrors(
|
||||
['email' => trans($response)]
|
||||
);
|
||||
|
||||
|
||||
// Regardless of response, we do not want to disclose the status of a user account,
|
||||
// so we give them a generic "If this exists, we're TOTALLY gonna email you" response
|
||||
return redirect()->route('login')->with('success',trans('passwords.sent'));
|
||||
}
|
||||
}
|
||||
|
|
|
@ -2,20 +2,21 @@
|
|||
|
||||
namespace App\Http\Controllers\Auth;
|
||||
|
||||
use Validator;
|
||||
use App\Http\Controllers\Controller;
|
||||
use Illuminate\Foundation\Auth\ThrottlesLogins;
|
||||
use App\Models\Setting;
|
||||
use App\Models\Ldap;
|
||||
use App\Models\User;
|
||||
use Auth;
|
||||
use Config;
|
||||
use App\Services\LdapAd;
|
||||
use Com\Tecnick\Barcode\Barcode;
|
||||
use Google2FA;
|
||||
use Illuminate\Foundation\Auth\ThrottlesLogins;
|
||||
use Illuminate\Http\Request;
|
||||
use Input;
|
||||
use Redirect;
|
||||
use Illuminate\Support\Carbon;
|
||||
use Illuminate\Support\Facades\Auth;
|
||||
use Illuminate\Support\Facades\Input;
|
||||
use Illuminate\Support\Facades\Session;
|
||||
use Illuminate\Support\Facades\Validator;
|
||||
use Log;
|
||||
use View;
|
||||
use PragmaRX\Google2FA\Google2FA;
|
||||
use Redirect;
|
||||
|
||||
/**
|
||||
* This controller handles authentication for the user, including local
|
||||
|
@ -39,15 +40,24 @@ class LoginController extends Controller
|
|||
*/
|
||||
protected $redirectTo = '/';
|
||||
|
||||
/**
|
||||
* @var LdapAd
|
||||
*/
|
||||
protected $ldap;
|
||||
|
||||
/**
|
||||
* Create a new authentication controller instance.
|
||||
*
|
||||
* @param LdapAd $ldap
|
||||
*
|
||||
* @return void
|
||||
*/
|
||||
public function __construct()
|
||||
public function __construct(LdapAd $ldap)
|
||||
{
|
||||
parent::__construct();
|
||||
$this->middleware('guest', ['except' => ['logout','postTwoFactorAuth','getTwoFactorAuth','getTwoFactorEnroll']]);
|
||||
\Session::put('backUrl', \URL::previous());
|
||||
Session::put('backUrl', \URL::previous());
|
||||
$this->ldap = $ldap;
|
||||
}
|
||||
|
||||
function showLoginForm(Request $request)
|
||||
|
@ -64,11 +74,35 @@ class LoginController extends Controller
|
|||
return view('auth.login');
|
||||
}
|
||||
|
||||
/**
|
||||
* Log in a user by LDAP
|
||||
*
|
||||
* @author Wes Hulette <jwhulette@gmail.com>
|
||||
*
|
||||
* @since 5.0.0
|
||||
*
|
||||
* @param Request $request
|
||||
*
|
||||
* @return User
|
||||
*
|
||||
* @throws \Exception
|
||||
*/
|
||||
private function loginViaLdap(Request $request): User
|
||||
{
|
||||
try {
|
||||
return $this->ldap->ldapLogin($request->input('username'), $request->input('password'));
|
||||
} catch (\Exception $ex) {
|
||||
LOG::debug("LDAP user login: " . $ex->getMessage());
|
||||
throw new \Exception($ex->getMessage());
|
||||
}
|
||||
}
|
||||
|
||||
private function loginViaRemoteUser(Request $request)
|
||||
{
|
||||
$remote_user = $request->server('REMOTE_USER');
|
||||
$header_name = Setting::getSettings()->login_remote_user_header_name ?: 'REMOTE_USER';
|
||||
$remote_user = $request->server($header_name);
|
||||
if (Setting::getSettings()->login_remote_user_enabled == "1" && isset($remote_user) && !empty($remote_user)) {
|
||||
Log::debug("Authenticatiing via REMOTE_USER.");
|
||||
Log::debug("Authenticating via HTTP header $header_name.");
|
||||
|
||||
$pos = strpos($remote_user, '\\');
|
||||
if ($pos > 0) {
|
||||
|
@ -85,53 +119,6 @@ class LoginController extends Controller
|
|||
}
|
||||
}
|
||||
|
||||
private function loginViaLdap(Request $request)
|
||||
{
|
||||
Log::debug("Binding user to LDAP.");
|
||||
$ldap_user = Ldap::findAndBindUserLdap($request->input('username'), $request->input('password'));
|
||||
if (!$ldap_user) {
|
||||
Log::debug("LDAP user ".$request->input('username')." not found in LDAP or could not bind");
|
||||
throw new \Exception("Could not find user in LDAP directory");
|
||||
} else {
|
||||
Log::debug("LDAP user ".$request->input('username')." successfully bound to LDAP");
|
||||
}
|
||||
|
||||
// Check if the user already exists in the database and was imported via LDAP
|
||||
$user = User::where('username', '=', Input::get('username'))->whereNull('deleted_at')->where('ldap_import', '=', 1)->where('activated', '=', '1')->first();
|
||||
Log::debug("Local auth lookup complete");
|
||||
|
||||
// The user does not exist in the database. Try to get them from LDAP.
|
||||
// If user does not exist and authenticates successfully with LDAP we
|
||||
// will create it on the fly and sign in with default permissions
|
||||
if (!$user) {
|
||||
Log::debug("Local user ".Input::get('username')." does not exist");
|
||||
Log::debug("Creating local user ".Input::get('username'));
|
||||
|
||||
if ($user = Ldap::createUserFromLdap($ldap_user)) { //this handles passwords on its own
|
||||
Log::debug("Local user created.");
|
||||
} else {
|
||||
Log::debug("Could not create local user.");
|
||||
throw new \Exception("Could not create local user");
|
||||
}
|
||||
// If the user exists and they were imported from LDAP already
|
||||
} else {
|
||||
Log::debug("Local user ".$request->input('username')." exists in database. Updating existing user against LDAP.");
|
||||
|
||||
$ldap_attr = Ldap::parseAndMapLdapAttributes($ldap_user);
|
||||
|
||||
if (Setting::getSettings()->ldap_pw_sync=='1') {
|
||||
$user->password = bcrypt($request->input('password'));
|
||||
}
|
||||
|
||||
$user->email = $ldap_attr['email'];
|
||||
$user->first_name = $ldap_attr['firstname'];
|
||||
$user->last_name = $ldap_attr['lastname'];
|
||||
$user->save();
|
||||
} // End if(!user)
|
||||
return $user;
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Account sign in form processing.
|
||||
*
|
||||
|
@ -160,9 +147,10 @@ class LoginController extends Controller
|
|||
$user = null;
|
||||
|
||||
// Should we even check for LDAP users?
|
||||
if (Setting::getSettings()->ldap_enabled=='1') {
|
||||
Log::debug("LDAP is enabled.");
|
||||
if ($this->ldap->init()) {
|
||||
LOG::debug("LDAP is enabled.");
|
||||
try {
|
||||
LOG::debug("Attempting to log user in by LDAP authentication.");
|
||||
$user = $this->loginViaLdap($request);
|
||||
Auth::login($user, true);
|
||||
|
||||
|
@ -227,15 +215,27 @@ class LoginController extends Controller
|
|||
return redirect()->route('two-factor')->with('error', trans('auth/message.two_factor.already_enrolled'));
|
||||
}
|
||||
|
||||
$google2fa = new Google2FA();
|
||||
$secret = $google2fa->generateSecretKey();
|
||||
$secret = Google2FA::generateSecretKey();
|
||||
$user->two_factor_secret = $secret;
|
||||
$user->save();
|
||||
|
||||
$barcode = new \Com\Tecnick\Barcode\Barcode();
|
||||
$barcode_obj = $barcode->getBarcodeObj('QRCODE', 'otpauth://totp/'.urlencode($settings->site_name).':'.urlencode($user->username).'?secret='.urlencode($secret).'&issuer=Snipe-IT&period=30', 300, 300, 'black', array(-2, -2, -2, -2));
|
||||
return view('auth.two_factor_enroll')->with('barcode_obj', $barcode_obj);
|
||||
$barcode = new Barcode();
|
||||
$barcode_obj =
|
||||
$barcode->getBarcodeObj(
|
||||
'QRCODE',
|
||||
sprintf(
|
||||
'otpauth://totp/%s:%s?secret=%s&issuer=Snipe-IT&period=30',
|
||||
urlencode($settings->site_name),
|
||||
urlencode($user->username),
|
||||
urlencode($secret)
|
||||
),
|
||||
300,
|
||||
300,
|
||||
'black',
|
||||
[-2, -2, -2, -2]
|
||||
);
|
||||
|
||||
return view('auth.two_factor_enroll')->with('barcode_obj', $barcode_obj);
|
||||
}
|
||||
|
||||
|
||||
|
@ -266,6 +266,8 @@ class LoginController extends Controller
|
|||
/**
|
||||
* Two factor code submission
|
||||
*
|
||||
* @param Request $request
|
||||
*
|
||||
* @return Redirect
|
||||
*/
|
||||
public function postTwoFactorAuth(Request $request)
|
||||
|
@ -279,11 +281,14 @@ class LoginController extends Controller
|
|||
return redirect()->route('two-factor')->with('error', trans('auth/message.two_factor.code_required'));
|
||||
}
|
||||
|
||||
if (!$request->has('two_factor_secret')) {
|
||||
return redirect()->route('two-factor')->with('error', 'Two-factor code is required.');
|
||||
}
|
||||
|
||||
$user = Auth::user();
|
||||
$google2fa = new Google2FA();
|
||||
$secret = $request->input('two_factor_secret');
|
||||
|
||||
if ($google2fa->verifyKey($user->two_factor_secret, $secret)) {
|
||||
if (Google2FA::verifyKey($user->two_factor_secret, $secret)) {
|
||||
$user->two_factor_enrolled = 1;
|
||||
$user->save();
|
||||
$request->session()->put('2fa_authed', 'true');
|
||||
|
@ -299,6 +304,8 @@ class LoginController extends Controller
|
|||
/**
|
||||
* Logout page.
|
||||
*
|
||||
* @param Request $request
|
||||
*
|
||||
* @return Redirect
|
||||
*/
|
||||
public function logout(Request $request)
|
||||
|
|
|
@ -3,7 +3,6 @@
|
|||
namespace App\Http\Controllers\Auth;
|
||||
|
||||
use App\Http\Controllers\Controller;
|
||||
use Illuminate\Foundation\Auth\ResetsPasswords;
|
||||
|
||||
class RegisterController extends Controller
|
||||
{
|
||||
|
|
|
@ -4,7 +4,6 @@ namespace App\Http\Controllers\Auth;
|
|||
|
||||
use App\Http\Controllers\Controller;
|
||||
use Illuminate\Foundation\Auth\ResetsPasswords;
|
||||
use App\Models\User;
|
||||
use Illuminate\Http\Request;
|
||||
|
||||
class ResetPasswordController extends Controller
|
||||
|
@ -39,7 +38,36 @@ class ResetPasswordController extends Controller
|
|||
$this->middleware('guest');
|
||||
}
|
||||
|
||||
|
||||
protected function rules()
|
||||
{
|
||||
return [
|
||||
'token' => 'required',
|
||||
'username' => 'required',
|
||||
'password' => 'required|confirmed|min:6',
|
||||
];
|
||||
}
|
||||
|
||||
|
||||
protected function credentials(Request $request)
|
||||
{
|
||||
return $request->only(
|
||||
'username', 'password', 'password_confirmation', 'token'
|
||||
);
|
||||
}
|
||||
|
||||
|
||||
public function showResetForm(Request $request, $token = null)
|
||||
{
|
||||
return view('auth.passwords.reset')->with(
|
||||
['token' => $token, 'username' => $request->input('username')]
|
||||
);
|
||||
}
|
||||
|
||||
protected function sendResetFailedResponse(Request $request, $response)
|
||||
{
|
||||
return redirect()->back()
|
||||
->withInput(['username'=>$request->input('username')])
|
||||
->withErrors(['username' => trans($response)]);
|
||||
}
|
||||
|
||||
}
|
||||
|
|
138
app/Http/Controllers/BulkAssetModelsController.php
Normal file
138
app/Http/Controllers/BulkAssetModelsController.php
Normal file
|
@ -0,0 +1,138 @@
|
|||
<?php
|
||||
|
||||
namespace App\Http\Controllers;
|
||||
|
||||
use App\Helpers\Helper;
|
||||
use App\Models\AssetModel;
|
||||
use Illuminate\Http\Request;
|
||||
use Illuminate\Support\Facades\Input;
|
||||
use Illuminate\Support\Facades\Redirect;
|
||||
|
||||
class BulkAssetModelsController extends Controller
|
||||
{
|
||||
/**
|
||||
* Returns a view that allows the user to bulk edit model attrbutes
|
||||
*
|
||||
* @author [A. Gianotto] [<snipe@snipe.net>]
|
||||
* @since [v1.7]
|
||||
* @param Request $request
|
||||
* @return \Illuminate\Contracts\View\View
|
||||
*/
|
||||
public function edit(Request $request)
|
||||
{
|
||||
$models_raw_array = Input::get('ids');
|
||||
|
||||
// Make sure some IDs have been selected
|
||||
if ((is_array($models_raw_array)) && (count($models_raw_array) > 0)) {
|
||||
|
||||
$models = AssetModel::whereIn('id', $models_raw_array)
|
||||
->withCount('assets as assets_count')
|
||||
->orderBy('assets_count', 'ASC')
|
||||
->get();
|
||||
|
||||
// If deleting....
|
||||
if ($request->input('bulk_actions')=='delete') {
|
||||
$valid_count = 0;
|
||||
foreach ($models as $model) {
|
||||
if ($model->assets_count == 0) {
|
||||
$valid_count++;
|
||||
}
|
||||
}
|
||||
return view('models/bulk-delete', compact('models'))->with('valid_count', $valid_count);
|
||||
|
||||
// Otherwise display the bulk edit screen
|
||||
}
|
||||
|
||||
$nochange = ['NC' => 'No Change'];
|
||||
return view('models/bulk-edit', compact('models'))
|
||||
->with('fieldset_list', $nochange + Helper::customFieldsetList())
|
||||
->with('depreciation_list', $nochange + Helper::depreciationList());
|
||||
}
|
||||
|
||||
return redirect()->route('models.index')
|
||||
->with('error', 'You must select at least one model to edit.');
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns a view that allows the user to bulk edit model attrbutes
|
||||
*
|
||||
* @author [A. Gianotto] [<snipe@snipe.net>]
|
||||
* @since [v1.7]
|
||||
* @param Request $request
|
||||
* @return \Illuminate\Contracts\View\View
|
||||
*/
|
||||
public function update(Request $request)
|
||||
{
|
||||
|
||||
$models_raw_array = Input::get('ids');
|
||||
$update_array = array();
|
||||
|
||||
if (($request->filled('manufacturer_id') && ($request->input('manufacturer_id')!='NC'))) {
|
||||
$update_array['manufacturer_id'] = $request->input('manufacturer_id');
|
||||
}
|
||||
if (($request->filled('category_id') && ($request->input('category_id')!='NC'))) {
|
||||
$update_array['category_id'] = $request->input('category_id');
|
||||
}
|
||||
if ($request->input('fieldset_id')!='NC') {
|
||||
$update_array['fieldset_id'] = $request->input('fieldset_id');
|
||||
}
|
||||
if ($request->input('depreciation_id')!='NC') {
|
||||
$update_array['depreciation_id'] = $request->input('depreciation_id');
|
||||
}
|
||||
|
||||
|
||||
|
||||
if (count($update_array) > 0) {
|
||||
AssetModel::whereIn('id', $models_raw_array)->update($update_array);
|
||||
return redirect()->route('models.index')
|
||||
->with('success', trans('admin/models/message.bulkedit.success'));
|
||||
}
|
||||
|
||||
return redirect()->route('models.index')
|
||||
->with('warning', trans('admin/models/message.bulkedit.error'));
|
||||
|
||||
}
|
||||
|
||||
/**
|
||||
* Validate and delete the given Asset Models. An Asset Model
|
||||
* cannot be deleted if there are associated assets.
|
||||
*
|
||||
* @author [A. Gianotto] [<snipe@snipe.net>]
|
||||
* @since [v1.0]
|
||||
* @return Redirect
|
||||
*/
|
||||
public function destroy()
|
||||
{
|
||||
$models_raw_array = Input::get('ids');
|
||||
|
||||
if ((is_array($models_raw_array)) && (count($models_raw_array) > 0)) {
|
||||
|
||||
$models = AssetModel::whereIn('id', $models_raw_array)->withCount('assets as assets_count')->get();
|
||||
|
||||
$del_error_count = 0;
|
||||
$del_count = 0;
|
||||
|
||||
foreach ($models as $model) {
|
||||
if ($model->assets_count > 0) {
|
||||
$del_error_count++;
|
||||
} else {
|
||||
$model->delete();
|
||||
$del_count++;
|
||||
}
|
||||
}
|
||||
|
||||
if ($del_error_count == 0) {
|
||||
return redirect()->route('models.index')
|
||||
->with('success', trans('admin/models/message.bulkdelete.success',['success_count'=> $del_count] ));
|
||||
}
|
||||
|
||||
return redirect()->route('models.index')
|
||||
->with('warning', trans('admin/models/message.bulkdelete.success_partial', ['fail_count'=>$del_error_count, 'success_count'=> $del_count]));
|
||||
}
|
||||
|
||||
return redirect()->route('models.index')
|
||||
->with('error', trans('admin/models/message.bulkdelete.error'));
|
||||
|
||||
}
|
||||
|
||||
}
|
|
@ -2,21 +2,11 @@
|
|||
namespace App\Http\Controllers;
|
||||
|
||||
use App\Helpers\Helper;
|
||||
use App\Models\Category as Category;
|
||||
use App\Models\Company;
|
||||
use App\Models\CustomField;
|
||||
use App\Models\Setting;
|
||||
use Auth;
|
||||
use DB;
|
||||
use Illuminate\Http\Request;
|
||||
use Illuminate\Support\Facades\Gate;
|
||||
use Input;
|
||||
use Lang;
|
||||
use Redirect;
|
||||
use Str;
|
||||
use View;
|
||||
use Image;
|
||||
use App\Http\Requests\ImageUploadRequest;
|
||||
use App\Models\Category as Category;
|
||||
use Auth;
|
||||
use Illuminate\Support\Facades\Storage;
|
||||
use Str;
|
||||
|
||||
/**
|
||||
* This class controls all actions related to Categories for
|
||||
|
@ -29,13 +19,14 @@ class CategoriesController extends Controller
|
|||
{
|
||||
|
||||
/**
|
||||
* Returns a view that invokes the ajax tables which actually contains
|
||||
* the content for the categories listing, which is generated in getDatatable.
|
||||
*
|
||||
* @author [A. Gianotto] [<snipe@snipe.net>]
|
||||
* @see CategoriesController::getDatatable() method that generates the JSON response
|
||||
* @since [v1.0]
|
||||
* @return \Illuminate\Contracts\View\View
|
||||
* Returns a view that invokes the ajax tables which actually contains
|
||||
* the content for the categories listing, which is generated in getDatatable.
|
||||
*
|
||||
* @author [A. Gianotto] [<snipe@snipe.net>]
|
||||
* @see CategoriesController::getDatatable() method that generates the JSON response
|
||||
* @since [v1.0]
|
||||
* @return \Illuminate\Contracts\View\View
|
||||
* @throws \Illuminate\Auth\Access\AuthorizationException
|
||||
*/
|
||||
public function index()
|
||||
{
|
||||
|
@ -46,30 +37,32 @@ class CategoriesController extends Controller
|
|||
|
||||
|
||||
/**
|
||||
* Returns a form view to create a new category.
|
||||
*
|
||||
* @author [A. Gianotto] [<snipe@snipe.net>]
|
||||
* @see CategoriesController::store() method that stores the data
|
||||
* @since [v1.0]
|
||||
* @return \Illuminate\Contracts\View\View
|
||||
* Returns a form view to create a new category.
|
||||
*
|
||||
* @author [A. Gianotto] [<snipe@snipe.net>]
|
||||
* @see CategoriesController::store() method that stores the data
|
||||
* @since [v1.0]
|
||||
* @return \Illuminate\Contracts\View\View
|
||||
* @throws \Illuminate\Auth\Access\AuthorizationException
|
||||
*/
|
||||
public function create()
|
||||
{
|
||||
// Show the page
|
||||
$this->authorize('create', Category::class);
|
||||
$category_types= Helper::categoryTypeList();
|
||||
return view('categories/edit')->with('item', new Category)
|
||||
->with('category_types', $category_types);
|
||||
->with('category_types', Helper::categoryTypeList());
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Validates and stores the new category data.
|
||||
*
|
||||
* @author [A. Gianotto] [<snipe@snipe.net>]
|
||||
* @see CategoriesController::create() method that makes the form.
|
||||
* @since [v1.0]
|
||||
* @return \Illuminate\Http\RedirectResponse
|
||||
* Validates and stores the new category data.
|
||||
*
|
||||
* @author [A. Gianotto] [<snipe@snipe.net>]
|
||||
* @see CategoriesController::create() method that makes the form.
|
||||
* @since [v1.0]
|
||||
* @param ImageUploadRequest $request
|
||||
* @return \Illuminate\Http\RedirectResponse
|
||||
* @throws \Illuminate\Auth\Access\AuthorizationException
|
||||
*/
|
||||
public function store(ImageUploadRequest $request)
|
||||
{
|
||||
|
@ -83,17 +76,7 @@ class CategoriesController extends Controller
|
|||
$category->checkin_email = $request->input('checkin_email', '0');
|
||||
$category->user_id = Auth::id();
|
||||
|
||||
if ($request->file('image')) {
|
||||
$image = $request->file('image');
|
||||
$file_name = str_random(25).".".$image->getClientOriginalExtension();
|
||||
$path = public_path('uploads/categories/'.$file_name);
|
||||
Image::make($image->getRealPath())->resize(800, null, function ($constraint) {
|
||||
$constraint->aspectRatio();
|
||||
$constraint->upsize();
|
||||
})->save($path);
|
||||
$category->image = $file_name;
|
||||
}
|
||||
|
||||
$category = $request->handleImages($category);
|
||||
|
||||
if ($category->save()) {
|
||||
return redirect()->route('categories.index')->with('success', trans('admin/categories/message.create.success'));
|
||||
|
@ -103,24 +86,23 @@ class CategoriesController extends Controller
|
|||
}
|
||||
|
||||
/**
|
||||
* Returns a view that makes a form to update a category.
|
||||
*
|
||||
* @author [A. Gianotto] [<snipe@snipe.net>]
|
||||
* @see CategoriesController::postEdit() method saves the data
|
||||
* @param int $categoryId
|
||||
* @since [v1.0]
|
||||
* @return \Illuminate\Contracts\View\View
|
||||
* Returns a view that makes a form to update a category.
|
||||
*
|
||||
* @author [A. Gianotto] [<snipe@snipe.net>]
|
||||
* @see CategoriesController::postEdit() method saves the data
|
||||
* @param int $categoryId
|
||||
* @since [v1.0]
|
||||
* @return \Illuminate\Contracts\View\View
|
||||
* @throws \Illuminate\Auth\Access\AuthorizationException
|
||||
*/
|
||||
public function edit($categoryId = null)
|
||||
{
|
||||
$this->authorize('edit', Category::class);
|
||||
$this->authorize('update', Category::class);
|
||||
if (is_null($item = Category::find($categoryId))) {
|
||||
return redirect()->route('categories.index')->with('error', trans('admin/categories/message.does_not_exist'));
|
||||
}
|
||||
$category_types= Helper::categoryTypeList();
|
||||
|
||||
return view('categories/edit', compact('item'))
|
||||
->with('category_types', $category_types);
|
||||
->with('category_types', Helper::categoryTypeList());
|
||||
}
|
||||
|
||||
|
||||
|
@ -129,14 +111,15 @@ class CategoriesController extends Controller
|
|||
*
|
||||
* @author [A. Gianotto] [<snipe@snipe.net>]
|
||||
* @see CategoriesController::getEdit() method that makes the form.
|
||||
* @param Request $request
|
||||
* @param ImageUploadRequest $request
|
||||
* @param int $categoryId
|
||||
* @return \Illuminate\Http\RedirectResponse
|
||||
* @throws \Illuminate\Auth\Access\AuthorizationException
|
||||
* @since [v1.0]
|
||||
*/
|
||||
public function update(ImageUploadRequest $request, $categoryId = null)
|
||||
{
|
||||
$this->authorize('edit', Category::class);
|
||||
$this->authorize('update', Category::class);
|
||||
if (is_null($category = Category::find($categoryId))) {
|
||||
// Redirect to the categories management page
|
||||
return redirect()->to('admin/categories')->with('error', trans('admin/categories/message.does_not_exist'));
|
||||
|
@ -151,37 +134,7 @@ class CategoriesController extends Controller
|
|||
$category->use_default_eula = $request->input('use_default_eula', '0');
|
||||
$category->require_acceptance = $request->input('require_acceptance', '0');
|
||||
$category->checkin_email = $request->input('checkin_email', '0');
|
||||
|
||||
$old_image = $category->image;
|
||||
|
||||
// Set the model's image property to null if the image is being deleted
|
||||
if ($request->input('image_delete') == 1) {
|
||||
$category->image = null;
|
||||
}
|
||||
|
||||
if ($request->file('image')) {
|
||||
$image = $request->file('image');
|
||||
$file_name = $category->id.'-'.str_slug($image->getClientOriginalName()) . "." . $image->getClientOriginalExtension();
|
||||
|
||||
if ($image->getClientOriginalExtension()!='svg') {
|
||||
Image::make($image->getRealPath())->resize(800, null, function ($constraint) {
|
||||
$constraint->aspectRatio();
|
||||
$constraint->upsize();
|
||||
})->save(app('categories_upload_path').$file_name);
|
||||
} else {
|
||||
$image->move(app('categories_upload_path'), $file_name);
|
||||
}
|
||||
$category->image = $file_name;
|
||||
|
||||
}
|
||||
|
||||
if ((($request->file('image')) && (isset($old_image)) && ($old_image!='')) || ($request->input('image_delete') == 1)) {
|
||||
try {
|
||||
unlink(app('categories_upload_path').$old_image);
|
||||
} catch (\Exception $e) {
|
||||
\Log::info($e);
|
||||
}
|
||||
}
|
||||
$category = $request->handleImages($category);
|
||||
|
||||
|
||||
if ($category->save()) {
|
||||
|
@ -193,31 +146,33 @@ class CategoriesController extends Controller
|
|||
}
|
||||
|
||||
/**
|
||||
* Validates and marks a category as deleted.
|
||||
*
|
||||
* @author [A. Gianotto] [<snipe@snipe.net>]
|
||||
* @since [v1.0]
|
||||
* @param int $categoryId
|
||||
* @return \Illuminate\Http\RedirectResponse
|
||||
* Validates and marks a category as deleted.
|
||||
*
|
||||
* @author [A. Gianotto] [<snipe@snipe.net>]
|
||||
* @since [v1.0]
|
||||
* @param int $categoryId
|
||||
* @return \Illuminate\Http\RedirectResponse
|
||||
* @throws \Illuminate\Auth\Access\AuthorizationException
|
||||
*/
|
||||
public function destroy($categoryId)
|
||||
{
|
||||
$this->authorize('delete', Category::class);
|
||||
// Check if the category exists
|
||||
if (is_null($category = Category::find($categoryId))) {
|
||||
if (is_null($category = Category::withCount('models as models_count', 'accessories as accessories_count','consumables as consumables_count','components as components_count')->findOrFail($categoryId))) {
|
||||
return redirect()->route('categories.index')->with('error', trans('admin/categories/message.not_found'));
|
||||
}
|
||||
|
||||
if ($category->has_models() > 0) {
|
||||
if ($category->models_count > 0) {
|
||||
return redirect()->route('categories.index')->with('error', trans('admin/categories/message.assoc_items', ['asset_type'=>'model']));
|
||||
} elseif ($category->accessories()->count() > 0) {
|
||||
return redirect()->route('categories.index')->with('error', trans('admin/categories/message.assoc_items', ['asset_type'=>'accessory']));
|
||||
} elseif ($category->consumables()->count() > 0) {
|
||||
return redirect()->route('categories.index')->with('error', trans('admin/categories/message.assoc_items', ['asset_type'=>'consumable']));
|
||||
} elseif ($category->components()->count() > 0) {
|
||||
return redirect()->route('categories.index')->with('error', trans('admin/categories/message.assoc_items', ['asset_type'=>'component']));
|
||||
} elseif ($category->accessories_count > 0) {
|
||||
return redirect()->route('categories.index')->with('error', trans('admin/categories/message.assoc_items', ['asset_type'=>'accessory']));
|
||||
} elseif ($category->consumables_count > 0) {
|
||||
return redirect()->route('categories.index')->with('error', trans('admin/categories/message.assoc_items', ['asset_type'=>'consumable']));
|
||||
} elseif ($category->components_count > 0) {
|
||||
return redirect()->route('categories.index')->with('error', trans('admin/categories/message.assoc_items', ['asset_type'=>'component']));
|
||||
}
|
||||
|
||||
Storage::disk('public')->delete('categories'.'/'.$category->image);
|
||||
$category->delete();
|
||||
// Redirect to the locations management page
|
||||
return redirect()->route('categories.index')->with('success', trans('admin/categories/message.delete.success'));
|
||||
|
@ -225,14 +180,15 @@ class CategoriesController extends Controller
|
|||
|
||||
|
||||
/**
|
||||
* Returns a view that invokes the ajax tables which actually contains
|
||||
* the content for the categories detail view, which is generated in getDataView.
|
||||
*
|
||||
* @author [A. Gianotto] [<snipe@snipe.net>]
|
||||
* @see CategoriesController::getDataView() method that generates the JSON response
|
||||
* @param int $categoryId
|
||||
* @since [v1.8]
|
||||
* @return \Illuminate\Contracts\View\View
|
||||
* Returns a view that invokes the ajax tables which actually contains
|
||||
* the content for the categories detail view, which is generated in getDataView.
|
||||
*
|
||||
* @author [A. Gianotto] [<snipe@snipe.net>]
|
||||
* @see CategoriesController::getDataView() method that generates the JSON response
|
||||
* @param $id
|
||||
* @return \Illuminate\Contracts\View\View
|
||||
* @throws \Illuminate\Auth\Access\AuthorizationException
|
||||
* @since [v1.8]
|
||||
*/
|
||||
public function show($id)
|
||||
{
|
||||
|
@ -255,10 +211,8 @@ class CategoriesController extends Controller
|
|||
}
|
||||
|
||||
// Prepare the error message
|
||||
$error = trans('admin/categories/message.does_not_exist', compact('id'));
|
||||
// Redirect to the user management page
|
||||
return redirect()->route('categories.index')->with('error', $error);
|
||||
return redirect()->route('categories.index')
|
||||
->with('error', trans('admin/categories/message.does_not_exist'));
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
|
|
|
@ -1,9 +1,9 @@
|
|||
<?php
|
||||
namespace App\Http\Controllers;
|
||||
|
||||
use App\Exceptions\CheckoutNotAllowed;
|
||||
use App\Models\Asset;
|
||||
use App\Models\Location;
|
||||
use App\Models\SnipeModel;
|
||||
use App\Models\User;
|
||||
|
||||
trait CheckInOutRequest
|
||||
|
|
|
@ -1,14 +1,10 @@
|
|||
<?php
|
||||
namespace App\Http\Controllers;
|
||||
|
||||
use App\Models\Company;
|
||||
use Input;
|
||||
use Lang;
|
||||
use Redirect;
|
||||
use View;
|
||||
use Illuminate\Http\Request;
|
||||
use Image;
|
||||
use App\Http\Requests\ImageUploadRequest;
|
||||
use App\Models\Company;
|
||||
use Illuminate\Http\Request;
|
||||
use Illuminate\Support\Facades\Storage;
|
||||
|
||||
/**
|
||||
* This controller handles all actions related to Companies for
|
||||
|
@ -21,11 +17,12 @@ final class CompaniesController extends Controller
|
|||
{
|
||||
|
||||
/**
|
||||
* Returns view to display listing of companies.
|
||||
*
|
||||
* @author [Abdullah Alansari] [<ahimta@gmail.com>]
|
||||
* @since [v1.8]
|
||||
* @return \Illuminate\Contracts\View\View
|
||||
* Returns view to display listing of companies.
|
||||
*
|
||||
* @author [Abdullah Alansari] [<ahimta@gmail.com>]
|
||||
* @since [v1.8]
|
||||
* @return \Illuminate\Contracts\View\View
|
||||
* @throws \Illuminate\Auth\Access\AuthorizationException
|
||||
*/
|
||||
public function index()
|
||||
{
|
||||
|
@ -35,11 +32,12 @@ final class CompaniesController extends Controller
|
|||
}
|
||||
|
||||
/**
|
||||
* Returns view to create a new company.
|
||||
*
|
||||
* @author [Abdullah Alansari] [<ahimta@gmail.com>]
|
||||
* @since [v1.8]
|
||||
* @return \Illuminate\Contracts\View\View
|
||||
* Returns view to create a new company.
|
||||
*
|
||||
* @author [Abdullah Alansari] [<ahimta@gmail.com>]
|
||||
* @since [v1.8]
|
||||
* @return \Illuminate\Contracts\View\View
|
||||
* @throws \Illuminate\Auth\Access\AuthorizationException
|
||||
*/
|
||||
public function create()
|
||||
{
|
||||
|
@ -55,6 +53,7 @@ final class CompaniesController extends Controller
|
|||
* @since [v1.8]
|
||||
* @param Request $request
|
||||
* @return \Illuminate\Http\RedirectResponse
|
||||
* @throws \Illuminate\Auth\Access\AuthorizationException
|
||||
*/
|
||||
public function store(ImageUploadRequest $request)
|
||||
{
|
||||
|
@ -63,16 +62,7 @@ final class CompaniesController extends Controller
|
|||
$company = new Company;
|
||||
$company->name = $request->input('name');
|
||||
|
||||
if ($request->file('image')) {
|
||||
$image = $request->file('image');
|
||||
$file_name = str_random(25).".".$image->getClientOriginalExtension();
|
||||
$path = public_path('uploads/companies/'.$file_name);
|
||||
Image::make($image->getRealPath())->resize(800, null, function ($constraint) {
|
||||
$constraint->aspectRatio();
|
||||
$constraint->upsize();
|
||||
})->save($path);
|
||||
$company->image = $file_name;
|
||||
}
|
||||
$company = $request->handleImages($company);
|
||||
|
||||
if ($company->save()) {
|
||||
return redirect()->route('companies.index')
|
||||
|
@ -83,12 +73,13 @@ final class CompaniesController extends Controller
|
|||
|
||||
|
||||
/**
|
||||
* Return form to edit existing company.
|
||||
*
|
||||
* @author [Abdullah Alansari] [<ahimta@gmail.com>]
|
||||
* @since [v1.8]
|
||||
* @param int $companyId
|
||||
* @return \Illuminate\Contracts\View\View
|
||||
* Return form to edit existing company.
|
||||
*
|
||||
* @author [Abdullah Alansari] [<ahimta@gmail.com>]
|
||||
* @since [v1.8]
|
||||
* @param int $companyId
|
||||
* @return \Illuminate\Contracts\View\View
|
||||
* @throws \Illuminate\Auth\Access\AuthorizationException
|
||||
*/
|
||||
public function edit($companyId)
|
||||
{
|
||||
|
@ -107,9 +98,10 @@ final class CompaniesController extends Controller
|
|||
*
|
||||
* @author [Abdullah Alansari] [<ahimta@gmail.com>]
|
||||
* @since [v1.8]
|
||||
* @param Request $request
|
||||
* @param ImageUploadRequest $request
|
||||
* @param int $companyId
|
||||
* @return \Illuminate\Http\RedirectResponse
|
||||
* @throws \Illuminate\Auth\Access\AuthorizationException
|
||||
*/
|
||||
public function update(ImageUploadRequest $request, $companyId)
|
||||
{
|
||||
|
@ -121,37 +113,7 @@ final class CompaniesController extends Controller
|
|||
|
||||
$company->name = $request->input('name');
|
||||
|
||||
$old_image = $company->image;
|
||||
|
||||
// Set the model's image property to null if the image is being deleted
|
||||
if ($request->input('image_delete') == 1) {
|
||||
$company->image = null;
|
||||
}
|
||||
|
||||
if ($request->file('image')) {
|
||||
$image = $request->file('image');
|
||||
$file_name = $company->id.'-'.str_slug($image->getClientOriginalName()) . "." . $image->getClientOriginalExtension();
|
||||
|
||||
if ($image->getClientOriginalExtension()!='svg') {
|
||||
Image::make($image->getRealPath())->resize(800, null, function ($constraint) {
|
||||
$constraint->aspectRatio();
|
||||
$constraint->upsize();
|
||||
})->save(app('companies_upload_path').$file_name);
|
||||
} else {
|
||||
$image->move(app('companies_upload_path'), $file_name);
|
||||
}
|
||||
$company->image = $file_name;
|
||||
|
||||
}
|
||||
|
||||
if ((($request->file('image')) && (isset($old_image)) && ($old_image!='')) || ($request->input('image_delete') == 1)) {
|
||||
try {
|
||||
unlink(app('companies_upload_path').$old_image);
|
||||
} catch (\Exception $e) {
|
||||
\Log::info($e);
|
||||
}
|
||||
}
|
||||
|
||||
$company = $request->handleImages($company);
|
||||
|
||||
if ($company->save()) {
|
||||
return redirect()->route('companies.index')
|
||||
|
@ -162,38 +124,47 @@ final class CompaniesController extends Controller
|
|||
}
|
||||
|
||||
/**
|
||||
* Delete company
|
||||
*
|
||||
* @author [Abdullah Alansari] [<ahimta@gmail.com>]
|
||||
* @since [v1.8]
|
||||
* @param int $companyId
|
||||
* @return \Illuminate\Http\RedirectResponse
|
||||
* Delete company
|
||||
*
|
||||
* @author [Abdullah Alansari] [<ahimta@gmail.com>]
|
||||
* @since [v1.8]
|
||||
* @param int $companyId
|
||||
* @return \Illuminate\Http\RedirectResponse
|
||||
* @throws \Illuminate\Auth\Access\AuthorizationException
|
||||
*/
|
||||
public function destroy($companyId)
|
||||
{
|
||||
if (is_null($company = Company::find($companyId))) {
|
||||
return redirect()->route('companies.index')
|
||||
->with('error', trans('admin/companies/message.not_found'));
|
||||
} else {
|
||||
}
|
||||
|
||||
$this->authorize('delete', $company);
|
||||
|
||||
$this->authorize('delete', $company);
|
||||
try {
|
||||
|
||||
try {
|
||||
$company->delete();
|
||||
return redirect()->route('companies.index')
|
||||
->with('success', trans('admin/companies/message.delete.success'));
|
||||
} catch (\Illuminate\Database\QueryException $exception) {
|
||||
/*
|
||||
* NOTE: This happens when there's a foreign key constraint violation
|
||||
* For example when rows in other tables are referencing this company
|
||||
*/
|
||||
if ($exception->getCode() == 23000) {
|
||||
return redirect()->route('companies.index')
|
||||
->with('error', trans('admin/companies/message.assoc_users'));
|
||||
} else {
|
||||
throw $exception;
|
||||
if ($company->image) {
|
||||
try {
|
||||
Storage::disk('public')->delete('companies'.'/'.$company->image);
|
||||
} catch (\Exception $e) {
|
||||
\Log::debug($e);
|
||||
}
|
||||
}
|
||||
|
||||
$company->delete();
|
||||
return redirect()->route('companies.index')
|
||||
->with('success', trans('admin/companies/message.delete.success'));
|
||||
} catch (\Illuminate\Database\QueryException $exception) {
|
||||
/*
|
||||
* NOTE: This happens when there's a foreign key constraint violation
|
||||
* For example when rows in other tables are referencing this company
|
||||
*/
|
||||
if ($exception->getCode() == 23000) {
|
||||
return redirect()->route('companies.index')
|
||||
->with('error', trans('admin/companies/message.assoc_users'));
|
||||
}
|
||||
|
||||
throw $exception;
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -203,9 +174,8 @@ final class CompaniesController extends Controller
|
|||
if (is_null($company = Company::find($id))) {
|
||||
return redirect()->route('companies.index')
|
||||
->with('error', trans('admin/companies/message.not_found'));
|
||||
} else {
|
||||
return view('companies/view')->with('company',$company);
|
||||
}
|
||||
|
||||
return view('companies/view')->with('company',$company);
|
||||
}
|
||||
}
|
||||
|
|
107
app/Http/Controllers/Components/ComponentCheckinController.php
Normal file
107
app/Http/Controllers/Components/ComponentCheckinController.php
Normal file
|
@ -0,0 +1,107 @@
|
|||
<?php
|
||||
|
||||
namespace App\Http\Controllers\Components;
|
||||
|
||||
use App\Events\CheckoutableCheckedIn;
|
||||
use App\Events\ComponentCheckedIn;
|
||||
use App\Http\Controllers\Controller;
|
||||
use App\Models\Asset;
|
||||
use App\Models\Component;
|
||||
use Illuminate\Http\Request;
|
||||
use Illuminate\Support\Facades\Auth;
|
||||
use Illuminate\Support\Facades\DB;
|
||||
use Illuminate\Support\Facades\Validator;
|
||||
|
||||
class ComponentCheckinController extends Controller
|
||||
{
|
||||
|
||||
/**
|
||||
* Returns a view that allows the checkin of a component from an asset.
|
||||
*
|
||||
* @author [A. Gianotto] [<snipe@snipe.net>]
|
||||
* @see ComponentCheckinController::store() method that stores the data.
|
||||
* @since [v4.1.4]
|
||||
* @param $component_asset_id
|
||||
* @return \Illuminate\Contracts\View\View
|
||||
* @throws \Illuminate\Auth\Access\AuthorizationException
|
||||
*/
|
||||
public function create($component_asset_id)
|
||||
{
|
||||
|
||||
// This could probably be done more cleanly but I am very tired. - @snipe
|
||||
if ($component_assets = DB::table('components_assets')->find($component_asset_id)) {
|
||||
if (is_null($component = Component::find($component_assets->component_id))) {
|
||||
return redirect()->route('components.index')->with('error', trans('admin/components/messages.not_found'));
|
||||
}
|
||||
if (is_null($asset = Asset::find($component_assets->asset_id))) {
|
||||
return redirect()->route('components.index')->with('error',
|
||||
trans('admin/components/message.not_found'));
|
||||
}
|
||||
$this->authorize('checkin', $component);
|
||||
return view('components/checkin', compact('component_assets','component','asset'));
|
||||
}
|
||||
|
||||
return redirect()->route('components.index')->with('error', trans('admin/components/messages.not_found'));
|
||||
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Validate and store checkin data.
|
||||
*
|
||||
* @author [A. Gianotto] [<snipe@snipe.net>]
|
||||
* @see ComponentCheckinController::create() method that returns the form.
|
||||
* @since [v4.1.4]
|
||||
* @param Request $request
|
||||
* @param $component_asset_id
|
||||
* @return \Illuminate\Http\RedirectResponse
|
||||
* @throws \Illuminate\Auth\Access\AuthorizationException
|
||||
*/
|
||||
public function store(Request $request, $component_asset_id)
|
||||
{
|
||||
if ($component_assets = DB::table('components_assets')->find($component_asset_id)) {
|
||||
if (is_null($component = Component::find($component_assets->component_id))) {
|
||||
return redirect()->route('components.index')->with('error',
|
||||
trans('admin/components/message.not_found'));
|
||||
}
|
||||
|
||||
|
||||
$this->authorize('checkin', $component);
|
||||
|
||||
$max_to_checkin = $component_assets->assigned_qty;
|
||||
$validator = Validator::make($request->all(), [
|
||||
"checkin_qty" => "required|numeric|between:1,$max_to_checkin"
|
||||
]);
|
||||
|
||||
if ($validator->fails()) {
|
||||
return redirect()->back()
|
||||
->withErrors($validator)
|
||||
->withInput();
|
||||
}
|
||||
|
||||
// Validation passed, so let's figure out what we have to do here.
|
||||
$qty_remaining_in_checkout = ($component_assets->assigned_qty - (int)$request->input('checkin_qty'));
|
||||
|
||||
// We have to modify the record to reflect the new qty that's
|
||||
// actually checked out.
|
||||
$component_assets->assigned_qty = $qty_remaining_in_checkout;
|
||||
DB::table('components_assets')->where('id',
|
||||
$component_asset_id)->update(['assigned_qty' => $qty_remaining_in_checkout]);
|
||||
|
||||
// If the checked-in qty is exactly the same as the assigned_qty,
|
||||
// we can simply delete the associated components_assets record
|
||||
if ($qty_remaining_in_checkout == 0) {
|
||||
DB::table('components_assets')->where('id', '=', $component_asset_id)->delete();
|
||||
}
|
||||
|
||||
$asset = Asset::find($component_assets->asset_id);
|
||||
|
||||
event(new CheckoutableCheckedIn($component, $asset, Auth::user(), $request->input('note')));
|
||||
|
||||
return redirect()->route('components.index')->with('success',
|
||||
trans('admin/components/message.checkout.success'));
|
||||
}
|
||||
return redirect()->route('components.index')->with('error', trans('admin/components/message.not_found'));
|
||||
}
|
||||
|
||||
}
|
|
@ -0,0 +1,95 @@
|
|||
<?php
|
||||
|
||||
namespace App\Http\Controllers\Components;
|
||||
|
||||
use App\Events\CheckoutableCheckedOut;
|
||||
use App\Events\ComponentCheckedOut;
|
||||
use App\Http\Controllers\Controller;
|
||||
use App\Models\Asset;
|
||||
use App\Models\Component;
|
||||
use Illuminate\Http\Request;
|
||||
use Illuminate\Support\Facades\Auth;
|
||||
use Illuminate\Support\Facades\Input;
|
||||
use Illuminate\Support\Facades\Validator;
|
||||
|
||||
class ComponentCheckoutController extends Controller
|
||||
{
|
||||
/**
|
||||
* Returns a view that allows the checkout of a component to an asset.
|
||||
*
|
||||
* @author [A. Gianotto] [<snipe@snipe.net>]
|
||||
* @see ComponentCheckoutController::store() method that stores the data.
|
||||
* @since [v3.0]
|
||||
* @param int $componentId
|
||||
* @return \Illuminate\Contracts\View\View
|
||||
* @throws \Illuminate\Auth\Access\AuthorizationException
|
||||
*/
|
||||
public function create($componentId)
|
||||
{
|
||||
// Check if the component exists
|
||||
if (is_null($component = Component::find($componentId))) {
|
||||
// Redirect to the component management page with error
|
||||
return redirect()->route('components.index')->with('error', trans('admin/components/message.not_found'));
|
||||
}
|
||||
$this->authorize('checkout', $component);
|
||||
return view('components/checkout', compact('component'));
|
||||
}
|
||||
|
||||
/**
|
||||
* Validate and store checkout data.
|
||||
*
|
||||
* @author [A. Gianotto] [<snipe@snipe.net>]
|
||||
* @see ComponentCheckoutController::create() method that returns the form.
|
||||
* @since [v3.0]
|
||||
* @param Request $request
|
||||
* @param int $componentId
|
||||
* @return \Illuminate\Http\RedirectResponse
|
||||
* @throws \Illuminate\Auth\Access\AuthorizationException
|
||||
*/
|
||||
public function store(Request $request, $componentId)
|
||||
{
|
||||
// Check if the component exists
|
||||
if (is_null($component = Component::find($componentId))) {
|
||||
// Redirect to the component management page with error
|
||||
return redirect()->route('components.index')->with('error', trans('admin/components/message.not_found'));
|
||||
}
|
||||
|
||||
$this->authorize('checkout', $component);
|
||||
|
||||
$max_to_checkout = $component->numRemaining();
|
||||
$validator = Validator::make($request->all(), [
|
||||
"asset_id" => "required",
|
||||
"assigned_qty" => "required|numeric|between:1,$max_to_checkout"
|
||||
]);
|
||||
|
||||
if ($validator->fails()) {
|
||||
return redirect()->back()
|
||||
->withErrors($validator)
|
||||
->withInput();
|
||||
}
|
||||
|
||||
$admin_user = Auth::user();
|
||||
$asset_id = e(Input::get('asset_id'));
|
||||
|
||||
// Check if the user exists
|
||||
if (is_null($asset = Asset::find($asset_id))) {
|
||||
// Redirect to the component management page with error
|
||||
return redirect()->route('components.index')->with('error', trans('admin/components/message.asset_does_not_exist'));
|
||||
}
|
||||
|
||||
// Update the component data
|
||||
$component->asset_id = $asset_id;
|
||||
|
||||
$component->assets()->attach($component->id, [
|
||||
'component_id' => $component->id,
|
||||
'user_id' => $admin_user->id,
|
||||
'created_at' => date('Y-m-d H:i:s'),
|
||||
'assigned_qty' => Input::get('assigned_qty'),
|
||||
'asset_id' => $asset_id
|
||||
]);
|
||||
|
||||
event(new CheckoutableCheckedOut($component, $asset, Auth::user(), $request->input('note')));
|
||||
|
||||
return redirect()->route('components.index')->with('success', trans('admin/components/message.checkout.success'));
|
||||
}
|
||||
}
|
199
app/Http/Controllers/Components/ComponentsController.php
Normal file
199
app/Http/Controllers/Components/ComponentsController.php
Normal file
|
@ -0,0 +1,199 @@
|
|||
<?php
|
||||
namespace App\Http\Controllers\Components;
|
||||
|
||||
use App\Http\Controllers\Controller;
|
||||
use App\Http\Requests\ImageUploadRequest;
|
||||
use App\Models\Company;
|
||||
use App\Models\Component;
|
||||
use Illuminate\Support\Facades\Auth;
|
||||
use Illuminate\Support\Facades\Input;
|
||||
use Illuminate\Support\Facades\Storage;
|
||||
|
||||
/**
|
||||
* This class controls all actions related to Components for
|
||||
* the Snipe-IT Asset Management application.
|
||||
*
|
||||
* @version v1.0
|
||||
*/
|
||||
class ComponentsController extends Controller
|
||||
{
|
||||
/**
|
||||
* Returns a view that invokes the ajax tables which actually contains
|
||||
* the content for the components listing, which is generated in getDatatable.
|
||||
*
|
||||
* @author [A. Gianotto] [<snipe@snipe.net>]
|
||||
* @see ComponentsController::getDatatable() method that generates the JSON response
|
||||
* @since [v3.0]
|
||||
* @return \Illuminate\Contracts\View\View
|
||||
* @throws \Illuminate\Auth\Access\AuthorizationException
|
||||
*/
|
||||
public function index()
|
||||
{
|
||||
$this->authorize('view', Component::class);
|
||||
return view('components/index');
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Returns a form to create a new component.
|
||||
*
|
||||
* @author [A. Gianotto] [<snipe@snipe.net>]
|
||||
* @see ComponentsController::postCreate() method that stores the data
|
||||
* @since [v3.0]
|
||||
* @return \Illuminate\Contracts\View\View
|
||||
* @throws \Illuminate\Auth\Access\AuthorizationException
|
||||
*/
|
||||
public function create()
|
||||
{
|
||||
$this->authorize('create', Component::class);
|
||||
return view('components/edit')->with('category_type', 'component')
|
||||
->with('item', new Component);
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Validate and store data for new component.
|
||||
*
|
||||
* @author [A. Gianotto] [<snipe@snipe.net>]
|
||||
* @see ComponentsController::getCreate() method that generates the view
|
||||
* @since [v3.0]
|
||||
* @param ImageUploadRequest $request
|
||||
* @return \Illuminate\Http\RedirectResponse
|
||||
* @throws \Illuminate\Auth\Access\AuthorizationException
|
||||
*/
|
||||
public function store(ImageUploadRequest $request)
|
||||
{
|
||||
$this->authorize('create', Component::class);
|
||||
$component = new Component();
|
||||
$component->name = $request->input('name');
|
||||
$component->category_id = $request->input('category_id');
|
||||
$component->location_id = $request->input('location_id');
|
||||
$component->company_id = Company::getIdForCurrentUser($request->input('company_id'));
|
||||
$component->order_number = $request->input('order_number', null);
|
||||
$component->min_amt = $request->input('min_amt', null);
|
||||
$component->serial = $request->input('serial', null);
|
||||
$component->purchase_date = $request->input('purchase_date', null);
|
||||
$component->purchase_cost = $request->input('purchase_cost', null);
|
||||
$component->qty = $request->input('qty');
|
||||
$component->user_id = Auth::id();
|
||||
|
||||
$component = $request->handleImages($component);
|
||||
|
||||
if ($component->save()) {
|
||||
return redirect()->route('components.index')->with('success', trans('admin/components/message.create.success'));
|
||||
}
|
||||
return redirect()->back()->withInput()->withErrors($component->getErrors());
|
||||
}
|
||||
|
||||
/**
|
||||
* Return a view to edit a component.
|
||||
*
|
||||
* @author [A. Gianotto] [<snipe@snipe.net>]
|
||||
* @see ComponentsController::postEdit() method that stores the data.
|
||||
* @since [v3.0]
|
||||
* @param int $componentId
|
||||
* @return \Illuminate\Contracts\View\View
|
||||
* @throws \Illuminate\Auth\Access\AuthorizationException
|
||||
*/
|
||||
public function edit($componentId = null)
|
||||
{
|
||||
if ($item = Component::find($componentId)) {
|
||||
$this->authorize('update', $item);
|
||||
return view('components/edit', compact('item'))->with('category_type', 'component');
|
||||
}
|
||||
return redirect()->route('components.index')->with('error', trans('admin/components/message.does_not_exist'));
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Return a view to edit a component.
|
||||
*
|
||||
* @author [A. Gianotto] [<snipe@snipe.net>]
|
||||
* @see ComponentsController::getEdit() method presents the form.
|
||||
* @param ImageUploadRequest $request
|
||||
* @param int $componentId
|
||||
* @return \Illuminate\Http\RedirectResponse
|
||||
* @throws \Illuminate\Auth\Access\AuthorizationException
|
||||
* @since [v3.0]
|
||||
*/
|
||||
public function update(ImageUploadRequest $request, $componentId = null)
|
||||
{
|
||||
if (is_null($component = Component::find($componentId))) {
|
||||
return redirect()->route('components.index')->with('error', trans('admin/components/message.does_not_exist'));
|
||||
}
|
||||
|
||||
$this->authorize('update', $component);
|
||||
|
||||
// Update the component data
|
||||
$component->name = Input::get('name');
|
||||
$component->category_id = Input::get('category_id');
|
||||
$component->location_id = Input::get('location_id');
|
||||
$component->company_id = Company::getIdForCurrentUser(Input::get('company_id'));
|
||||
$component->order_number = Input::get('order_number');
|
||||
$component->min_amt = Input::get('min_amt');
|
||||
$component->serial = Input::get('serial');
|
||||
$component->purchase_date = Input::get('purchase_date');
|
||||
$component->purchase_cost = request('purchase_cost');
|
||||
$component->qty = Input::get('qty');
|
||||
|
||||
$component = $request->handleImages($component);
|
||||
|
||||
if ($component->save()) {
|
||||
return redirect()->route('components.index')->with('success', trans('admin/components/message.update.success'));
|
||||
}
|
||||
return redirect()->back()->withInput()->withErrors($component->getErrors());
|
||||
}
|
||||
|
||||
/**
|
||||
* Delete a component.
|
||||
*
|
||||
* @author [A. Gianotto] [<snipe@snipe.net>]
|
||||
* @since [v3.0]
|
||||
* @param int $componentId
|
||||
* @return \Illuminate\Http\RedirectResponse
|
||||
* @throws \Illuminate\Auth\Access\AuthorizationException
|
||||
*/
|
||||
public function destroy($componentId)
|
||||
{
|
||||
if (is_null($component = Component::find($componentId))) {
|
||||
return redirect()->route('components.index')->with('error', trans('admin/components/message.does_not_exist'));
|
||||
}
|
||||
|
||||
$this->authorize('delete', $component);
|
||||
|
||||
// Remove the image if one exists
|
||||
if (Storage::disk('public')->exists('components/'.$component->image)) {
|
||||
try {
|
||||
Storage::disk('public')->delete('components/'.$component->image);
|
||||
} catch (\Exception $e) {
|
||||
\Log::debug($e);
|
||||
}
|
||||
}
|
||||
|
||||
$component->delete();
|
||||
return redirect()->route('components.index')->with('success', trans('admin/components/message.delete.success'));
|
||||
}
|
||||
|
||||
/**
|
||||
* Return a view to display component information.
|
||||
*
|
||||
* @author [A. Gianotto] [<snipe@snipe.net>]
|
||||
* @see ComponentsController::getDataView() method that generates the JSON response
|
||||
* @since [v3.0]
|
||||
* @param int $componentId
|
||||
* @return \Illuminate\Contracts\View\View
|
||||
* @throws \Illuminate\Auth\Access\AuthorizationException
|
||||
*/
|
||||
public function show($componentId = null)
|
||||
{
|
||||
$component = Component::find($componentId);
|
||||
|
||||
if (isset($component->id)) {
|
||||
$this->authorize('view', $component);
|
||||
return view('components/view', compact('component'));
|
||||
}
|
||||
// Redirect to the user management page
|
||||
return redirect()->route('components.index')
|
||||
->with('error', trans('admin/components/message.does_not_exist'));
|
||||
}
|
||||
}
|
|
@ -1,397 +0,0 @@
|
|||
<?php
|
||||
namespace App\Http\Controllers;
|
||||
|
||||
use App\Helpers\Helper;
|
||||
use App\Http\Requests\ImageUploadRequest;
|
||||
use App\Models\Actionlog;
|
||||
use App\Models\Company;
|
||||
use App\Models\Component;
|
||||
use App\Models\CustomField;
|
||||
use App\Models\Setting;
|
||||
use App\Models\User;
|
||||
use App\Models\Asset;
|
||||
use Auth;
|
||||
use Config;
|
||||
use DB;
|
||||
use Input;
|
||||
use Lang;
|
||||
use Mail;
|
||||
use Redirect;
|
||||
use Slack;
|
||||
use Str;
|
||||
use View;
|
||||
use Validator;
|
||||
use Illuminate\Http\Request;
|
||||
use Gate;
|
||||
use Image;
|
||||
|
||||
/**
|
||||
* This class controls all actions related to Components for
|
||||
* the Snipe-IT Asset Management application.
|
||||
*
|
||||
* @version v1.0
|
||||
*/
|
||||
class ComponentsController extends Controller
|
||||
{
|
||||
/**
|
||||
* Returns a view that invokes the ajax tables which actually contains
|
||||
* the content for the components listing, which is generated in getDatatable.
|
||||
*
|
||||
* @author [A. Gianotto] [<snipe@snipe.net>]
|
||||
* @see ComponentsController::getDatatable() method that generates the JSON response
|
||||
* @since [v3.0]
|
||||
* @return \Illuminate\Contracts\View\View
|
||||
*/
|
||||
public function index()
|
||||
{
|
||||
$this->authorize('view', Component::class);
|
||||
return view('components/index');
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Returns a form to create a new component.
|
||||
*
|
||||
* @author [A. Gianotto] [<snipe@snipe.net>]
|
||||
* @see ComponentsController::postCreate() method that stores the data
|
||||
* @since [v3.0]
|
||||
* @return \Illuminate\Contracts\View\View
|
||||
*/
|
||||
public function create()
|
||||
{
|
||||
$this->authorize('create', Component::class);
|
||||
$category_type = 'component';
|
||||
return view('components/edit')->with('category_type',$category_type)
|
||||
->with('item', new Component);
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Validate and store data for new component.
|
||||
*
|
||||
* @author [A. Gianotto] [<snipe@snipe.net>]
|
||||
* @see ComponentsController::getCreate() method that generates the view
|
||||
* @since [v3.0]
|
||||
* @return \Illuminate\Http\RedirectResponse
|
||||
*/
|
||||
public function store(ImageUploadRequest $request)
|
||||
{
|
||||
$this->authorize('create', Component::class);
|
||||
$component = new Component();
|
||||
$component->name = $request->input('name');
|
||||
$component->category_id = $request->input('category_id');
|
||||
$component->location_id = $request->input('location_id');
|
||||
$component->company_id = Company::getIdForCurrentUser($request->input('company_id'));
|
||||
$component->order_number = $request->input('order_number', null);
|
||||
$component->min_amt = $request->input('min_amt', null);
|
||||
$component->serial = $request->input('serial', null);
|
||||
$component->purchase_date = $request->input('purchase_date', null);
|
||||
$component->purchase_cost = $request->input('purchase_cost', null);
|
||||
$component->qty = $request->input('qty');
|
||||
$component->user_id = Auth::id();
|
||||
|
||||
|
||||
if ($request->file('image')) {
|
||||
$image = $request->file('image');
|
||||
$file_name = str_random(25).".".$image->getClientOriginalExtension();
|
||||
$path = public_path('uploads/components/'.$file_name);
|
||||
Image::make($image->getRealPath())->resize(800, null, function ($constraint) {
|
||||
$constraint->aspectRatio();
|
||||
$constraint->upsize();
|
||||
})->save($path);
|
||||
$component->image = $file_name;
|
||||
}
|
||||
|
||||
if ($component->save()) {
|
||||
return redirect()->route('components.index')->with('success', trans('admin/components/message.create.success'));
|
||||
}
|
||||
return redirect()->back()->withInput()->withErrors($component->getErrors());
|
||||
}
|
||||
|
||||
/**
|
||||
* Return a view to edit a component.
|
||||
*
|
||||
* @author [A. Gianotto] [<snipe@snipe.net>]
|
||||
* @see ComponentsController::postEdit() method that stores the data.
|
||||
* @since [v3.0]
|
||||
* @param int $componentId
|
||||
* @return \Illuminate\Contracts\View\View
|
||||
*/
|
||||
public function edit($componentId = null)
|
||||
{
|
||||
|
||||
|
||||
if ($item = Component::find($componentId)) {
|
||||
$this->authorize('update', $item);
|
||||
$category_type = 'component';
|
||||
return view('components/edit', compact('item'))->with('category_type', $category_type);
|
||||
}
|
||||
return redirect()->route('components.index')->with('error', trans('admin/components/message.does_not_exist'));
|
||||
|
||||
|
||||
|
||||
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Return a view to edit a component.
|
||||
*
|
||||
* @author [A. Gianotto] [<snipe@snipe.net>]
|
||||
* @see ComponentsController::getEdit() method presents the form.
|
||||
* @param int $componentId
|
||||
* @since [v3.0]
|
||||
* @return \Illuminate\Http\RedirectResponse
|
||||
*/
|
||||
public function update(ImageUploadRequest $request, $componentId = null)
|
||||
{
|
||||
if (is_null($component = Component::find($componentId))) {
|
||||
return redirect()->route('components.index')->with('error', trans('admin/components/message.does_not_exist'));
|
||||
}
|
||||
|
||||
$this->authorize('update', $component);
|
||||
|
||||
|
||||
// Update the component data
|
||||
$component->name = Input::get('name');
|
||||
$component->category_id = Input::get('category_id');
|
||||
$component->location_id = Input::get('location_id');
|
||||
$component->company_id = Company::getIdForCurrentUser(Input::get('company_id'));
|
||||
$component->order_number = Input::get('order_number');
|
||||
$component->min_amt = Input::get('min_amt');
|
||||
$component->serial = Input::get('serial');
|
||||
$component->purchase_date = Input::get('purchase_date');
|
||||
$component->purchase_cost = request('purchase_cost');
|
||||
$component->qty = Input::get('qty');
|
||||
|
||||
if ($request->file('image')) {
|
||||
$image = $request->file('image');
|
||||
$file_name = str_random(25).".".$image->getClientOriginalExtension();
|
||||
$path = public_path('uploads/components/'.$file_name);
|
||||
Image::make($image->getRealPath())->resize(800, null, function ($constraint) {
|
||||
$constraint->aspectRatio();
|
||||
$constraint->upsize();
|
||||
})->save($path);
|
||||
$component->image = $file_name;
|
||||
} elseif ($request->input('image_delete')=='1') {
|
||||
$component->image = null;
|
||||
}
|
||||
|
||||
if ($component->save()) {
|
||||
return redirect()->route('components.index')->with('success', trans('admin/components/message.update.success'));
|
||||
}
|
||||
return redirect()->back()->withInput()->withErrors($component->getErrors());
|
||||
}
|
||||
|
||||
/**
|
||||
* Delete a component.
|
||||
*
|
||||
* @author [A. Gianotto] [<snipe@snipe.net>]
|
||||
* @since [v3.0]
|
||||
* @param int $componentId
|
||||
* @return \Illuminate\Http\RedirectResponse
|
||||
*/
|
||||
public function destroy($componentId)
|
||||
{
|
||||
if (is_null($component = Component::find($componentId))) {
|
||||
return redirect()->route('components.index')->with('error', trans('admin/components/message.does_not_exist'));
|
||||
}
|
||||
|
||||
$this->authorize('delete', $component);
|
||||
$component->delete();
|
||||
return redirect()->route('components.index')->with('success', trans('admin/components/message.delete.success'));
|
||||
}
|
||||
|
||||
/**
|
||||
* Return a view to display component information.
|
||||
*
|
||||
* @author [A. Gianotto] [<snipe@snipe.net>]
|
||||
* @see ComponentsController::getDataView() method that generates the JSON response
|
||||
* @since [v3.0]
|
||||
* @param int $componentId
|
||||
* @return \Illuminate\Contracts\View\View
|
||||
*/
|
||||
public function show($componentId = null)
|
||||
{
|
||||
$component = Component::find($componentId);
|
||||
|
||||
if (isset($component->id)) {
|
||||
$this->authorize('view', $component);
|
||||
return view('components/view', compact('component'));
|
||||
}
|
||||
// Prepare the error message
|
||||
$error = trans('admin/components/message.does_not_exist', compact('id'));
|
||||
// Redirect to the user management page
|
||||
return redirect()->route('components.index')->with('error', $error);
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns a view that allows the checkout of a component to an asset.
|
||||
*
|
||||
* @author [A. Gianotto] [<snipe@snipe.net>]
|
||||
* @see ComponentsController::postCheckout() method that stores the data.
|
||||
* @since [v3.0]
|
||||
* @param int $componentId
|
||||
* @return \Illuminate\Contracts\View\View
|
||||
*/
|
||||
public function getCheckout($componentId)
|
||||
{
|
||||
// Check if the component exists
|
||||
if (is_null($component = Component::find($componentId))) {
|
||||
// Redirect to the component management page with error
|
||||
return redirect()->route('components.index')->with('error', trans('admin/components/message.not_found'));
|
||||
}
|
||||
$this->authorize('checkout', $component);
|
||||
return view('components/checkout', compact('component'));
|
||||
}
|
||||
|
||||
/**
|
||||
* Validate and store checkout data.
|
||||
*
|
||||
* @author [A. Gianotto] [<snipe@snipe.net>]
|
||||
* @see ComponentsController::getCheckout() method that returns the form.
|
||||
* @since [v3.0]
|
||||
* @param Request $request
|
||||
* @param int $componentId
|
||||
* @return \Illuminate\Http\RedirectResponse
|
||||
*/
|
||||
public function postCheckout(Request $request, $componentId)
|
||||
{
|
||||
// Check if the component exists
|
||||
if (is_null($component = Component::find($componentId))) {
|
||||
// Redirect to the component management page with error
|
||||
return redirect()->route('components.index')->with('error', trans('admin/components/message.not_found'));
|
||||
}
|
||||
|
||||
$this->authorize('checkout', $component);
|
||||
|
||||
$max_to_checkout = $component->numRemaining();
|
||||
$validator = Validator::make($request->all(), [
|
||||
"asset_id" => "required",
|
||||
"assigned_qty" => "required|numeric|between:1,$max_to_checkout"
|
||||
]);
|
||||
|
||||
if ($validator->fails()) {
|
||||
return redirect()->back()
|
||||
->withErrors($validator)
|
||||
->withInput();
|
||||
}
|
||||
|
||||
$admin_user = Auth::user();
|
||||
$asset_id = e(Input::get('asset_id'));
|
||||
|
||||
// Check if the user exists
|
||||
if (is_null($asset = Asset::find($asset_id))) {
|
||||
// Redirect to the component management page with error
|
||||
return redirect()->route('components.index')->with('error', trans('admin/components/message.asset_does_not_exist'));
|
||||
}
|
||||
|
||||
// Update the component data
|
||||
$component->asset_id = $asset_id;
|
||||
|
||||
$component->assets()->attach($component->id, [
|
||||
'component_id' => $component->id,
|
||||
'user_id' => $admin_user->id,
|
||||
'created_at' => date('Y-m-d H:i:s'),
|
||||
'assigned_qty' => Input::get('assigned_qty'),
|
||||
'asset_id' => $asset_id
|
||||
]);
|
||||
|
||||
$component->logCheckout(e(Input::get('note')), $asset);
|
||||
return redirect()->route('components.index')->with('success', trans('admin/components/message.checkout.success'));
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns a view that allows the checkin of a component from an asset.
|
||||
*
|
||||
* @author [A. Gianotto] [<snipe@snipe.net>]
|
||||
* @see ComponentsController::postCheckout() method that stores the data.
|
||||
* @since [v4.1.4]
|
||||
* @param int $componentId
|
||||
* @return \Illuminate\Contracts\View\View
|
||||
*/
|
||||
public function getCheckin($component_asset_id)
|
||||
{
|
||||
|
||||
// This could probably be done more cleanly but I am very tired. - @snipe
|
||||
if ($component_assets = DB::table('components_assets')->find($component_asset_id)) {
|
||||
if (is_null($component = Component::find($component_assets->component_id))) {
|
||||
return redirect()->route('components.index')->with('error', trans('admin/components/messages.not_found'));
|
||||
}
|
||||
if (is_null($asset = Asset::find($component_assets->asset_id))) {
|
||||
return redirect()->route('components.index')->with('error',
|
||||
trans('admin/components/message.not_found'));
|
||||
}
|
||||
$this->authorize('checkin', $component);
|
||||
return view('components/checkin', compact('component_assets','component','asset'));
|
||||
}
|
||||
|
||||
return redirect()->route('components.index')->with('error', trans('admin/components/messages.not_found'));
|
||||
|
||||
}
|
||||
|
||||
/**
|
||||
* Validate and store checkin data.
|
||||
*
|
||||
* @author [A. Gianotto] [<snipe@snipe.net>]
|
||||
* @see ComponentsController::getCheckout() method that returns the form.
|
||||
* @since [v4.1.4]
|
||||
* @param Request $request
|
||||
* @param int $componentId
|
||||
* @return \Illuminate\Http\RedirectResponse
|
||||
*/
|
||||
public function postCheckin(Request $request, $component_asset_id)
|
||||
{
|
||||
if ($component_assets = DB::table('components_assets')->find($component_asset_id)) {
|
||||
if (is_null($component = Component::find($component_assets->component_id))) {
|
||||
return redirect()->route('components.index')->with('error',
|
||||
trans('admin/components/message.not_found'));
|
||||
}
|
||||
|
||||
|
||||
$this->authorize('checkin', $component);
|
||||
|
||||
$max_to_checkin = $component_assets->assigned_qty;
|
||||
$validator = Validator::make($request->all(), [
|
||||
"checkin_qty" => "required|numeric|between:1,$max_to_checkin"
|
||||
]);
|
||||
|
||||
if ($validator->fails()) {
|
||||
return redirect()->back()
|
||||
->withErrors($validator)
|
||||
->withInput();
|
||||
}
|
||||
|
||||
// Validation passed, so let's figure out what we have to do here.
|
||||
$qty_remaining_in_checkout = ($component_assets->assigned_qty - (int)$request->input('checkin_qty'));
|
||||
|
||||
// We have to modify the record to reflect the new qty that's
|
||||
// actually checked out.
|
||||
$component_assets->assigned_qty = $qty_remaining_in_checkout;
|
||||
DB::table('components_assets')->where('id',
|
||||
$component_asset_id)->update(['assigned_qty' => $qty_remaining_in_checkout]);
|
||||
|
||||
$log = new Actionlog();
|
||||
$log->user_id = Auth::user()->id;
|
||||
$log->action_type = 'checkin from';
|
||||
$log->target_type = Asset::class;
|
||||
$log->target_id = $component_assets->asset_id;
|
||||
$log->item_id = $component_assets->component_id;
|
||||
$log->item_type = Component::class;
|
||||
$log->note = $request->input('note');
|
||||
$log->save();
|
||||
|
||||
// If the checked-in qty is exactly the same as the assigned_qty,
|
||||
// we can simply delete the associated components_assets record
|
||||
if ($qty_remaining_in_checkout == 0) {
|
||||
DB::table('components_assets')->where('id', '=', $component_asset_id)->delete();
|
||||
}
|
||||
|
||||
return redirect()->route('components.index')->with('success',
|
||||
trans('admin/components/message.checkout.success'));
|
||||
}
|
||||
return redirect()->route('components.index')->with('error', trans('admin/components/message.not_found'));
|
||||
}
|
||||
|
||||
|
||||
}
|
|
@ -0,0 +1,77 @@
|
|||
<?php
|
||||
|
||||
namespace App\Http\Controllers\Consumables;
|
||||
|
||||
use App\Events\CheckoutableCheckedOut;
|
||||
use App\Http\Controllers\Controller;
|
||||
use App\Models\Consumable;
|
||||
use App\Models\User;
|
||||
use Illuminate\Http\Request;
|
||||
use Illuminate\Support\Facades\Auth;
|
||||
use Illuminate\Support\Facades\Input;
|
||||
|
||||
class ConsumableCheckoutController extends Controller
|
||||
{
|
||||
|
||||
/**
|
||||
* Return a view to checkout a consumable to a user.
|
||||
*
|
||||
* @author [A. Gianotto] [<snipe@snipe.net>]
|
||||
* @see ConsumableCheckoutController::store() method that stores the data.
|
||||
* @since [v1.0]
|
||||
* @param int $consumableId
|
||||
* @return \Illuminate\Contracts\View\View
|
||||
* @throws \Illuminate\Auth\Access\AuthorizationException
|
||||
*/
|
||||
public function create($consumableId)
|
||||
{
|
||||
if (is_null($consumable = Consumable::find($consumableId))) {
|
||||
return redirect()->route('consumables.index')->with('error', trans('admin/consumables/message.does_not_exist'));
|
||||
}
|
||||
$this->authorize('checkout', $consumable);
|
||||
return view('consumables/checkout', compact('consumable'));
|
||||
}
|
||||
|
||||
/**
|
||||
* Saves the checkout information
|
||||
*
|
||||
* @author [A. Gianotto] [<snipe@snipe.net>]
|
||||
* @see ConsumableCheckoutController::create() method that returns the form.
|
||||
* @since [v1.0]
|
||||
* @param int $consumableId
|
||||
* @return \Illuminate\Http\RedirectResponse
|
||||
* @throws \Illuminate\Auth\Access\AuthorizationException
|
||||
*/
|
||||
public function store(Request $request, $consumableId)
|
||||
{
|
||||
if (is_null($consumable = Consumable::find($consumableId))) {
|
||||
return redirect()->route('consumables.index')->with('error', trans('admin/consumables/message.not_found'));
|
||||
}
|
||||
|
||||
$this->authorize('checkout', $consumable);
|
||||
|
||||
$admin_user = Auth::user();
|
||||
$assigned_to = e(Input::get('assigned_to'));
|
||||
|
||||
// Check if the user exists
|
||||
if (is_null($user = User::find($assigned_to))) {
|
||||
// Redirect to the consumable management page with error
|
||||
return redirect()->route('checkout/consumable', $consumable)->with('error', trans('admin/consumables/message.checkout.user_does_not_exist'));
|
||||
}
|
||||
|
||||
// Update the consumable data
|
||||
$consumable->assigned_to = e(Input::get('assigned_to'));
|
||||
|
||||
$consumable->users()->attach($consumable->id, [
|
||||
'consumable_id' => $consumable->id,
|
||||
'user_id' => $admin_user->id,
|
||||
'assigned_to' => e(Input::get('assigned_to'))
|
||||
]);
|
||||
|
||||
event(new CheckoutableCheckedOut($consumable, $user, Auth::user(), $request->input('note')));
|
||||
|
||||
// Redirect to the new consumable page
|
||||
return redirect()->route('consumables.index')->with('success', trans('admin/consumables/message.checkout.success'));
|
||||
|
||||
}
|
||||
}
|
196
app/Http/Controllers/Consumables/ConsumablesController.php
Normal file
196
app/Http/Controllers/Consumables/ConsumablesController.php
Normal file
|
@ -0,0 +1,196 @@
|
|||
<?php
|
||||
|
||||
namespace App\Http\Controllers\Consumables;
|
||||
|
||||
use App\Helpers\Helper;
|
||||
use App\Http\Controllers\Controller;
|
||||
use App\Http\Requests\ImageUploadRequest;
|
||||
use App\Models\Company;
|
||||
use App\Models\Consumable;
|
||||
use Illuminate\Support\Facades\Auth;
|
||||
use Illuminate\Support\Facades\Input;
|
||||
|
||||
/**
|
||||
* This controller handles all actions related to Consumables for
|
||||
* the Snipe-IT Asset Management application.
|
||||
*
|
||||
* @version v1.0
|
||||
*/
|
||||
class ConsumablesController extends Controller
|
||||
{
|
||||
/**
|
||||
* Return a view to display component information.
|
||||
*
|
||||
* @author [A. Gianotto] [<snipe@snipe.net>]
|
||||
* @see ConsumablesController::getDatatable() method that generates the JSON response
|
||||
* @since [v1.0]
|
||||
* @return \Illuminate\Contracts\View\View
|
||||
* @throws \Illuminate\Auth\Access\AuthorizationException
|
||||
*/
|
||||
public function index()
|
||||
{
|
||||
$this->authorize('index', Consumable::class);
|
||||
return view('consumables/index');
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Return a view to display the form view to create a new consumable
|
||||
*
|
||||
* @author [A. Gianotto] [<snipe@snipe.net>]
|
||||
* @see ConsumablesController::postCreate() method that stores the form data
|
||||
* @since [v1.0]
|
||||
* @return \Illuminate\Contracts\View\View
|
||||
* @throws \Illuminate\Auth\Access\AuthorizationException
|
||||
*/
|
||||
public function create()
|
||||
{
|
||||
$this->authorize('create', Consumable::class);
|
||||
return view('consumables/edit')->with('category_type', 'consumable')
|
||||
->with('item', new Consumable);
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Validate and store new consumable data.
|
||||
*
|
||||
* @author [A. Gianotto] [<snipe@snipe.net>]
|
||||
* @see ConsumablesController::getCreate() method that returns the form view
|
||||
* @since [v1.0]
|
||||
* @param ImageUploadRequest $request
|
||||
* @return \Illuminate\Http\RedirectResponse
|
||||
* @throws \Illuminate\Auth\Access\AuthorizationException
|
||||
*/
|
||||
public function store(ImageUploadRequest $request)
|
||||
{
|
||||
$this->authorize('create', Consumable::class);
|
||||
$consumable = new Consumable();
|
||||
$consumable->name = $request->input('name');
|
||||
$consumable->category_id = $request->input('category_id');
|
||||
$consumable->location_id = $request->input('location_id');
|
||||
$consumable->company_id = Company::getIdForCurrentUser($request->input('company_id'));
|
||||
$consumable->order_number = $request->input('order_number');
|
||||
$consumable->min_amt = $request->input('min_amt');
|
||||
$consumable->manufacturer_id = $request->input('manufacturer_id');
|
||||
$consumable->model_number = $request->input('model_number');
|
||||
$consumable->item_no = $request->input('item_no');
|
||||
$consumable->purchase_date = $request->input('purchase_date');
|
||||
$consumable->purchase_cost = Helper::ParseFloat($request->input('purchase_cost'));
|
||||
$consumable->qty = $request->input('qty');
|
||||
$consumable->user_id = Auth::id();
|
||||
|
||||
|
||||
$consumable = $request->handleImages($consumable);
|
||||
|
||||
if ($consumable->save()) {
|
||||
return redirect()->route('consumables.index')->with('success', trans('admin/consumables/message.create.success'));
|
||||
}
|
||||
|
||||
return redirect()->back()->withInput()->withErrors($consumable->getErrors());
|
||||
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns a form view to edit a consumable.
|
||||
*
|
||||
* @author [A. Gianotto] [<snipe@snipe.net>]
|
||||
* @param int $consumableId
|
||||
* @see ConsumablesController::postEdit() method that stores the form data.
|
||||
* @since [v1.0]
|
||||
* @return \Illuminate\Contracts\View\View
|
||||
* @throws \Illuminate\Auth\Access\AuthorizationException
|
||||
*/
|
||||
public function edit($consumableId = null)
|
||||
{
|
||||
if ($item = Consumable::find($consumableId)) {
|
||||
$this->authorize($item);
|
||||
return view('consumables/edit', compact('item'))->with('category_type', 'consumable');
|
||||
}
|
||||
|
||||
return redirect()->route('consumables.index')->with('error', trans('admin/consumables/message.does_not_exist'));
|
||||
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Returns a form view to edit a consumable.
|
||||
*
|
||||
* @author [A. Gianotto] [<snipe@snipe.net>]
|
||||
* @param ImageUploadRequest $request
|
||||
* @param int $consumableId
|
||||
* @return \Illuminate\Http\RedirectResponse
|
||||
* @throws \Illuminate\Auth\Access\AuthorizationException
|
||||
* @see ConsumablesController::getEdit() method that stores the form data.
|
||||
* @since [v1.0]
|
||||
*/
|
||||
public function update(ImageUploadRequest $request, $consumableId = null)
|
||||
{
|
||||
if (is_null($consumable = Consumable::find($consumableId))) {
|
||||
return redirect()->route('consumables.index')->with('error', trans('admin/consumables/message.does_not_exist'));
|
||||
}
|
||||
|
||||
$this->authorize($consumable);
|
||||
|
||||
$consumable->name = $request->input('name');
|
||||
$consumable->category_id = $request->input('category_id');
|
||||
$consumable->location_id = $request->input('location_id');
|
||||
$consumable->company_id = Company::getIdForCurrentUser($request->input('company_id'));
|
||||
$consumable->order_number = $request->input('order_number');
|
||||
$consumable->min_amt = $request->input('min_amt');
|
||||
$consumable->manufacturer_id = $request->input('manufacturer_id');
|
||||
$consumable->model_number = $request->input('model_number');
|
||||
$consumable->item_no = $request->input('item_no');
|
||||
$consumable->purchase_date = $request->input('purchase_date');
|
||||
$consumable->purchase_cost = Helper::ParseFloat(Input::get('purchase_cost'));
|
||||
$consumable->qty = Helper::ParseFloat(Input::get('qty'));
|
||||
|
||||
$consumable = $request->handleImages($consumable);
|
||||
|
||||
if ($consumable->save()) {
|
||||
return redirect()->route('consumables.index')->with('success', trans('admin/consumables/message.update.success'));
|
||||
}
|
||||
return redirect()->back()->withInput()->withErrors($consumable->getErrors());
|
||||
}
|
||||
|
||||
/**
|
||||
* Delete a consumable.
|
||||
*
|
||||
* @author [A. Gianotto] [<snipe@snipe.net>]
|
||||
* @param int $consumableId
|
||||
* @since [v1.0]
|
||||
* @return \Illuminate\Http\RedirectResponse
|
||||
* @throws \Illuminate\Auth\Access\AuthorizationException
|
||||
*/
|
||||
public function destroy($consumableId)
|
||||
{
|
||||
if (is_null($consumable = Consumable::find($consumableId))) {
|
||||
return redirect()->route('consumables.index')->with('error', trans('admin/consumables/message.not_found'));
|
||||
}
|
||||
$this->authorize($consumable);
|
||||
$consumable->delete();
|
||||
// Redirect to the locations management page
|
||||
return redirect()->route('consumables.index')->with('success', trans('admin/consumables/message.delete.success'));
|
||||
}
|
||||
|
||||
/**
|
||||
* Return a view to display component information.
|
||||
*
|
||||
* @author [A. Gianotto] [<snipe@snipe.net>]
|
||||
* @see ConsumablesController::getDataView() method that generates the JSON response
|
||||
* @since [v1.0]
|
||||
* @param int $consumableId
|
||||
* @return \Illuminate\Contracts\View\View
|
||||
* @throws \Illuminate\Auth\Access\AuthorizationException
|
||||
*/
|
||||
public function show($consumableId = null)
|
||||
{
|
||||
$consumable = Consumable::find($consumableId);
|
||||
$this->authorize($consumable);
|
||||
if (isset($consumable->id)) {
|
||||
return view('consumables/view', compact('consumable'));
|
||||
}
|
||||
return redirect()->route('consumables.index')
|
||||
->with('error', trans('admin/consumables/message.does_not_exist'));
|
||||
}
|
||||
|
||||
}
|
|
@ -1,286 +0,0 @@
|
|||
<?php
|
||||
|
||||
namespace App\Http\Controllers;
|
||||
|
||||
use App\Helpers\Helper;
|
||||
use App\Models\Company;
|
||||
use App\Models\Consumable;
|
||||
use App\Models\Setting;
|
||||
use App\Models\User;
|
||||
use Auth;
|
||||
use Config;
|
||||
use DB;
|
||||
use Input;
|
||||
use Lang;
|
||||
use Redirect;
|
||||
use Slack;
|
||||
use Str;
|
||||
use View;
|
||||
use Gate;
|
||||
use Image;
|
||||
use App\Http\Requests\ImageUploadRequest;
|
||||
|
||||
/**
|
||||
* This controller handles all actions related to Consumables for
|
||||
* the Snipe-IT Asset Management application.
|
||||
*
|
||||
* @version v1.0
|
||||
*/
|
||||
class ConsumablesController extends Controller
|
||||
{
|
||||
/**
|
||||
* Return a view to display component information.
|
||||
*
|
||||
* @author [A. Gianotto] [<snipe@snipe.net>]
|
||||
* @see ConsumablesController::getDatatable() method that generates the JSON response
|
||||
* @since [v1.0]
|
||||
* @return \Illuminate\Contracts\View\View
|
||||
*/
|
||||
public function index()
|
||||
{
|
||||
$this->authorize('index', Consumable::class);
|
||||
return view('consumables/index');
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Return a view to display the form view to create a new consumable
|
||||
*
|
||||
* @author [A. Gianotto] [<snipe@snipe.net>]
|
||||
* @see ConsumablesController::postCreate() method that stores the form data
|
||||
* @since [v1.0]
|
||||
* @return \Illuminate\Contracts\View\View
|
||||
*/
|
||||
public function create()
|
||||
{
|
||||
$this->authorize('create', Consumable::class);
|
||||
$category_type = 'consumable';
|
||||
return view('consumables/edit')->with('category_type', $category_type)
|
||||
->with('item', new Consumable);
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Validate and store new consumable data.
|
||||
*
|
||||
* @author [A. Gianotto] [<snipe@snipe.net>]
|
||||
* @see ConsumablesController::getCreate() method that returns the form view
|
||||
* @since [v1.0]
|
||||
* @return \Illuminate\Http\RedirectResponse
|
||||
*/
|
||||
public function store(ImageUploadRequest $request)
|
||||
{
|
||||
$this->authorize('create', Consumable::class);
|
||||
$consumable = new Consumable();
|
||||
$consumable->name = $request->input('name');
|
||||
$consumable->category_id = $request->input('category_id');
|
||||
$consumable->location_id = $request->input('location_id');
|
||||
$consumable->company_id = Company::getIdForCurrentUser($request->input('company_id'));
|
||||
$consumable->order_number = $request->input('order_number');
|
||||
$consumable->min_amt = $request->input('min_amt');
|
||||
$consumable->manufacturer_id = $request->input('manufacturer_id');
|
||||
$consumable->model_number = $request->input('model_number');
|
||||
$consumable->item_no = $request->input('item_no');
|
||||
$consumable->purchase_date = $request->input('purchase_date');
|
||||
$consumable->purchase_cost = Helper::ParseFloat($request->input('purchase_cost'));
|
||||
$consumable->qty = $request->input('qty');
|
||||
$consumable->user_id = Auth::id();
|
||||
|
||||
|
||||
if ($request->file('image')) {
|
||||
$image = $request->file('image');
|
||||
$file_name = str_random(25).".".$image->getClientOriginalExtension();
|
||||
$path = public_path('uploads/consumables/'.$file_name);
|
||||
Image::make($image->getRealPath())->resize(800, null, function ($constraint) {
|
||||
$constraint->aspectRatio();
|
||||
$constraint->upsize();
|
||||
})->save($path);
|
||||
$consumable->image = $file_name;
|
||||
}
|
||||
|
||||
if ($consumable->save()) {
|
||||
return redirect()->route('consumables.index')->with('success', trans('admin/consumables/message.create.success'));
|
||||
}
|
||||
|
||||
return redirect()->back()->withInput()->withErrors($consumable->getErrors());
|
||||
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns a form view to edit a consumable.
|
||||
*
|
||||
* @author [A. Gianotto] [<snipe@snipe.net>]
|
||||
* @param int $consumableId
|
||||
* @see ConsumablesController::postEdit() method that stores the form data.
|
||||
* @since [v1.0]
|
||||
* @return \Illuminate\Contracts\View\View
|
||||
*/
|
||||
public function edit($consumableId = null)
|
||||
{
|
||||
if ($item = Consumable::find($consumableId)) {
|
||||
$this->authorize($item);
|
||||
$category_type = 'consumable';
|
||||
return view('consumables/edit', compact('item'))->with('category_type', $category_type);
|
||||
}
|
||||
|
||||
return redirect()->route('consumables.index')->with('error', trans('admin/consumables/message.does_not_exist'));
|
||||
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Returns a form view to edit a consumable.
|
||||
*
|
||||
* @author [A. Gianotto] [<snipe@snipe.net>]
|
||||
* @param int $consumableId
|
||||
* @see ConsumablesController::getEdit() method that stores the form data.
|
||||
* @since [v1.0]
|
||||
* @return \Illuminate\Http\RedirectResponse
|
||||
*/
|
||||
public function update(ImageUploadRequest $request, $consumableId = null)
|
||||
{
|
||||
if (is_null($consumable = Consumable::find($consumableId))) {
|
||||
return redirect()->route('consumables.index')->with('error', trans('admin/consumables/message.does_not_exist'));
|
||||
}
|
||||
|
||||
$this->authorize($consumable);
|
||||
|
||||
$consumable->name = $request->input('name');
|
||||
$consumable->category_id = $request->input('category_id');
|
||||
$consumable->location_id = $request->input('location_id');
|
||||
$consumable->company_id = Company::getIdForCurrentUser($request->input('company_id'));
|
||||
$consumable->order_number = $request->input('order_number');
|
||||
$consumable->min_amt = $request->input('min_amt');
|
||||
$consumable->manufacturer_id = $request->input('manufacturer_id');
|
||||
$consumable->model_number = $request->input('model_number');
|
||||
$consumable->item_no = $request->input('item_no');
|
||||
$consumable->purchase_date = $request->input('purchase_date');
|
||||
$consumable->purchase_cost = Helper::ParseFloat(Input::get('purchase_cost'));
|
||||
$consumable->qty = Helper::ParseFloat(Input::get('qty'));
|
||||
|
||||
if ($request->file('image')) {
|
||||
$image = $request->file('image');
|
||||
$file_name = str_random(25).".".$image->getClientOriginalExtension();
|
||||
$path = public_path('uploads/consumables/'.$file_name);
|
||||
Image::make($image->getRealPath())->resize(800, null, function ($constraint) {
|
||||
$constraint->aspectRatio();
|
||||
$constraint->upsize();
|
||||
})->save($path);
|
||||
$consumable->image = $file_name;
|
||||
} elseif ($request->input('image_delete')=='1') {
|
||||
$consumable->image = null;
|
||||
}
|
||||
|
||||
if ($consumable->save()) {
|
||||
return redirect()->route('consumables.index')->with('success', trans('admin/consumables/message.update.success'));
|
||||
}
|
||||
return redirect()->back()->withInput()->withErrors($consumable->getErrors());
|
||||
}
|
||||
|
||||
/**
|
||||
* Delete a consumable.
|
||||
*
|
||||
* @author [A. Gianotto] [<snipe@snipe.net>]
|
||||
* @param int $consumableId
|
||||
* @since [v1.0]
|
||||
* @return \Illuminate\Http\RedirectResponse
|
||||
*/
|
||||
public function destroy($consumableId)
|
||||
{
|
||||
if (is_null($consumable = Consumable::find($consumableId))) {
|
||||
return redirect()->route('consumables.index')->with('error', trans('admin/consumables/message.not_found'));
|
||||
}
|
||||
$this->authorize($consumable);
|
||||
$consumable->delete();
|
||||
// Redirect to the locations management page
|
||||
return redirect()->route('consumables.index')->with('success', trans('admin/consumables/message.delete.success'));
|
||||
}
|
||||
|
||||
/**
|
||||
* Return a view to display component information.
|
||||
*
|
||||
* @author [A. Gianotto] [<snipe@snipe.net>]
|
||||
* @see ConsumablesController::getDataView() method that generates the JSON response
|
||||
* @since [v1.0]
|
||||
* @param int $consumableId
|
||||
* @return \Illuminate\Contracts\View\View
|
||||
*/
|
||||
public function show($consumableId = null)
|
||||
{
|
||||
$consumable = Consumable::find($consumableId);
|
||||
$this->authorize($consumable);
|
||||
if (isset($consumable->id)) {
|
||||
return view('consumables/view', compact('consumable'));
|
||||
}
|
||||
return redirect()->route('consumables.index')->with('error', trans('admin/consumables/message.does_not_exist', compact('id')));
|
||||
}
|
||||
|
||||
/**
|
||||
* Return a view to checkout a consumable to a user.
|
||||
*
|
||||
* @author [A. Gianotto] [<snipe@snipe.net>]
|
||||
* @see ConsumablesController::postCheckout() method that stores the data.
|
||||
* @since [v1.0]
|
||||
* @param int $consumableId
|
||||
* @return \Illuminate\Contracts\View\View
|
||||
*/
|
||||
public function getCheckout($consumableId)
|
||||
{
|
||||
if (is_null($consumable = Consumable::find($consumableId))) {
|
||||
return redirect()->route('consumables.index')->with('error', trans('admin/consumables/message.does_not_exist'));
|
||||
}
|
||||
$this->authorize('checkout', $consumable);
|
||||
return view('consumables/checkout', compact('consumable'));
|
||||
}
|
||||
|
||||
/**
|
||||
* Saves the checkout information
|
||||
*
|
||||
* @author [A. Gianotto] [<snipe@snipe.net>]
|
||||
* @see ConsumablesController::getCheckout() method that returns the form.
|
||||
* @since [v1.0]
|
||||
* @param int $consumableId
|
||||
* @return \Illuminate\Http\RedirectResponse
|
||||
*/
|
||||
public function postCheckout($consumableId)
|
||||
{
|
||||
if (is_null($consumable = Consumable::find($consumableId))) {
|
||||
return redirect()->route('consumables.index')->with('error', trans('admin/consumables/message.not_found'));
|
||||
}
|
||||
|
||||
$this->authorize('checkout', $consumable);
|
||||
|
||||
$admin_user = Auth::user();
|
||||
$assigned_to = e(Input::get('assigned_to'));
|
||||
|
||||
// Check if the user exists
|
||||
if (is_null($user = User::find($assigned_to))) {
|
||||
// Redirect to the consumable management page with error
|
||||
return redirect()->route('checkout/consumable', $consumable)->with('error', trans('admin/consumables/message.checkout.user_does_not_exist'));
|
||||
}
|
||||
|
||||
// Update the consumable data
|
||||
$consumable->assigned_to = e(Input::get('assigned_to'));
|
||||
|
||||
$consumable->users()->attach($consumable->id, [
|
||||
'consumable_id' => $consumable->id,
|
||||
'user_id' => $admin_user->id,
|
||||
'assigned_to' => e(Input::get('assigned_to'))
|
||||
]);
|
||||
|
||||
$logaction = $consumable->logCheckout(e(Input::get('note')), $user);
|
||||
$data['log_id'] = $logaction->id;
|
||||
$data['eula'] = $consumable->getEula();
|
||||
$data['first_name'] = $user->first_name;
|
||||
$data['item_name'] = $consumable->name;
|
||||
$data['checkout_date'] = $logaction->created_at;
|
||||
$data['note'] = $logaction->note;
|
||||
$data['require_acceptance'] = $consumable->requireAcceptance();
|
||||
|
||||
|
||||
// Redirect to the new consumable page
|
||||
return redirect()->route('consumables.index')->with('success', trans('admin/consumables/message.checkout.success'));
|
||||
|
||||
}
|
||||
|
||||
}
|
|
@ -22,10 +22,10 @@
|
|||
namespace App\Http\Controllers;
|
||||
|
||||
use Auth;
|
||||
use Illuminate\Foundation\Bus\DispatchesJobs;
|
||||
use Illuminate\Routing\Controller as BaseController;
|
||||
use Illuminate\Foundation\Validation\ValidatesRequests;
|
||||
use Illuminate\Foundation\Auth\Access\AuthorizesRequests;
|
||||
use Illuminate\Foundation\Bus\DispatchesJobs;
|
||||
use Illuminate\Foundation\Validation\ValidatesRequests;
|
||||
use Illuminate\Routing\Controller as BaseController;
|
||||
|
||||
abstract class Controller extends BaseController
|
||||
{
|
||||
|
|
|
@ -1,19 +1,12 @@
|
|||
<?php
|
||||
namespace App\Http\Controllers;
|
||||
|
||||
use App\Http\Requests\CustomFieldRequest;
|
||||
use View;
|
||||
use App\Models\CustomFieldset;
|
||||
use App\Models\CustomField;
|
||||
use Input;
|
||||
use Validator;
|
||||
use Redirect;
|
||||
use App\Models\AssetModel;
|
||||
use Lang;
|
||||
use Auth;
|
||||
use Illuminate\Http\Request;
|
||||
use App\Helpers\Helper;
|
||||
use Log;
|
||||
use App\Http\Requests\CustomFieldRequest;
|
||||
use App\Models\CustomField;
|
||||
use App\Models\CustomFieldset;
|
||||
use Illuminate\Support\Facades\Auth;
|
||||
use Redirect;
|
||||
|
||||
/**
|
||||
* This controller handles all actions related to Custom Asset Fields for
|
||||
|
@ -29,49 +22,53 @@ class CustomFieldsController extends Controller
|
|||
{
|
||||
|
||||
/**
|
||||
* Returns a view with a listing of custom fields.
|
||||
*
|
||||
* @author [Brady Wetherington] [<uberbrady@gmail.com>]
|
||||
* @since [v1.8]
|
||||
* @return View
|
||||
*/
|
||||
* Returns a view with a listing of custom fields.
|
||||
*
|
||||
* @author [Brady Wetherington] [<uberbrady@gmail.com>]
|
||||
* @since [v1.8]
|
||||
* @return \Illuminate\Support\Facades\View
|
||||
* @throws \Illuminate\Auth\Access\AuthorizationException
|
||||
*/
|
||||
public function index()
|
||||
{
|
||||
$this->authorize('view', CustomField::class);
|
||||
|
||||
$fieldsets = CustomFieldset::with("fields", "models")->get();
|
||||
$fields = CustomField::with("fieldset")->get();
|
||||
|
||||
return view("custom_fields.index")->with("custom_fieldsets", $fieldsets)->with("custom_fields", $fields);
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
/**
|
||||
* Returns a view with a form to create a new custom field.
|
||||
*
|
||||
* @see CustomFieldsController::storeField()
|
||||
* @author [Brady Wetherington] [<uberbrady@gmail.com>]
|
||||
* @since [v1.8]
|
||||
* @return View
|
||||
*/
|
||||
* Returns a view with a form to create a new custom field.
|
||||
*
|
||||
* @see CustomFieldsController::storeField()
|
||||
* @author [Brady Wetherington] [<uberbrady@gmail.com>]
|
||||
* @since [v1.8]
|
||||
* @return \Illuminate\Support\Facades\View
|
||||
* @throws \Illuminate\Auth\Access\AuthorizationException
|
||||
*/
|
||||
public function create()
|
||||
{
|
||||
$this->authorize('create', CustomField::class);
|
||||
|
||||
return view("custom_fields.fields.edit")->with('field', new CustomField());
|
||||
return view("custom_fields.fields.edit",[
|
||||
'predefinedFormats' => Helper::predefined_formats(),
|
||||
'customFormat' => ''
|
||||
])->with('field', new CustomField());
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Validates and stores a new custom field.
|
||||
*
|
||||
* @see CustomFieldsController::createField()
|
||||
* @author [Brady Wetherington] [<uberbrady@gmail.com>]
|
||||
* @since [v1.8]
|
||||
* @return Redirect
|
||||
*/
|
||||
* Validates and stores a new custom field.
|
||||
*
|
||||
* @see CustomFieldsController::createField()
|
||||
* @author [Brady Wetherington] [<uberbrady@gmail.com>]
|
||||
* @since [v1.8]
|
||||
* @return Redirect
|
||||
* @throws \Illuminate\Auth\Access\AuthorizationException
|
||||
*/
|
||||
public function store(CustomFieldRequest $request)
|
||||
{
|
||||
$this->authorize('create', CustomField::class);
|
||||
|
@ -83,22 +80,24 @@ class CustomFieldsController extends Controller
|
|||
"field_values" => $request->get("field_values"),
|
||||
"field_encrypted" => $request->get("field_encrypted", 0),
|
||||
"show_in_email" => $request->get("show_in_email", 0),
|
||||
"user_id" => Auth::user()->id
|
||||
"user_id" => Auth::id()
|
||||
]);
|
||||
|
||||
|
||||
if ($request->has("custom_format")) {
|
||||
if ($request->filled("custom_format")) {
|
||||
$field->format = e($request->get("custom_format"));
|
||||
} else {
|
||||
$field->format = e($request->get("format"));
|
||||
}
|
||||
|
||||
if ($field->save()) {
|
||||
|
||||
return redirect()->route("fields.index")->with("success", trans('admin/custom_fields/message.field.create.success'));
|
||||
} else {
|
||||
return redirect()->back()->withInput()->with('error', trans('admin/custom_fields/message.field.create.error'));
|
||||
}
|
||||
|
||||
return redirect()->back()->withInput()
|
||||
->with('error', trans('admin/custom_fields/message.field.create.error'));
|
||||
|
||||
}
|
||||
|
||||
|
||||
|
@ -108,6 +107,7 @@ class CustomFieldsController extends Controller
|
|||
* @author [A. Gianotto] [<snipe@snipe.net>]
|
||||
* @since [v3.0]
|
||||
* @return Redirect
|
||||
* @throws \Illuminate\Auth\Access\AuthorizationException
|
||||
*/
|
||||
public function deleteFieldFromFieldset($field_id, $fieldset_id)
|
||||
{
|
||||
|
@ -116,19 +116,21 @@ class CustomFieldsController extends Controller
|
|||
$this->authorize('update', $field);
|
||||
|
||||
if ($field->fieldset()->detach($fieldset_id)) {
|
||||
return redirect()->route('fieldsets.show', ['fieldset' => $fieldset_id])->with("success", trans('admin/custom_fields/message.field.delete.success'));
|
||||
return redirect()->route('fieldsets.show', ['fieldset' => $fieldset_id])
|
||||
->with("success", trans('admin/custom_fields/message.field.delete.success'));
|
||||
}
|
||||
|
||||
return redirect()->back()->withErrors(['message' => "Field is in-use"]);
|
||||
}
|
||||
|
||||
/**
|
||||
* Delete a custom field.
|
||||
*
|
||||
* @author [Brady Wetherington] [<uberbrady@gmail.com>]
|
||||
* @since [v1.8]
|
||||
* @return Redirect
|
||||
*/
|
||||
* Delete a custom field.
|
||||
*
|
||||
* @author [Brady Wetherington] [<uberbrady@gmail.com>]
|
||||
* @since [v1.8]
|
||||
* @return Redirect
|
||||
* @throws \Illuminate\Auth\Access\AuthorizationException
|
||||
*/
|
||||
public function destroy($field_id)
|
||||
{
|
||||
$field = CustomField::find($field_id);
|
||||
|
@ -137,56 +139,66 @@ class CustomFieldsController extends Controller
|
|||
|
||||
if ($field->fieldset->count()>0) {
|
||||
return redirect()->back()->withErrors(['message' => "Field is in-use"]);
|
||||
} else {
|
||||
$field->delete();
|
||||
return redirect()->route("fields.index")->with("success", trans('admin/custom_fields/message.field.delete.success'));
|
||||
}
|
||||
$field->delete();
|
||||
return redirect()->route("fields.index")
|
||||
->with("success", trans('admin/custom_fields/message.field.delete.success'));
|
||||
}
|
||||
|
||||
|
||||
|
||||
/**
|
||||
* Return a view to edit a custom field
|
||||
*
|
||||
* @author [A. Gianotto] [<snipe@snipe.net>]
|
||||
* @param int $id
|
||||
* @since [v4.0]
|
||||
* @return View
|
||||
*/
|
||||
* Return a view to edit a custom field
|
||||
*
|
||||
* @author [A. Gianotto] [<snipe@snipe.net>]
|
||||
* @param int $id
|
||||
* @since [v4.0]
|
||||
* @return \Illuminate\Support\Facades\View
|
||||
* @throws \Illuminate\Auth\Access\AuthorizationException
|
||||
*/
|
||||
public function edit($id)
|
||||
{
|
||||
$field = CustomField::find($id);
|
||||
|
||||
$this->authorize('update', $field);
|
||||
|
||||
return view("custom_fields.fields.edit")->with('field', $field);
|
||||
$customFormat = '';
|
||||
if((stripos($field->format, 'regex') === 0) && ($field->format !== CustomField::PREDEFINED_FORMATS['MAC'])) {
|
||||
$customFormat = $field->format;
|
||||
}
|
||||
|
||||
return view("custom_fields.fields.edit",[
|
||||
'field' => $field,
|
||||
'customFormat' => $customFormat,
|
||||
'predefinedFormats' => Helper::predefined_formats()
|
||||
]);
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Store the updated field
|
||||
*
|
||||
* @todo Allow encrypting/decrypting if encryption status changes
|
||||
*
|
||||
* @author [A. Gianotto] [<snipe@snipe.net>]
|
||||
* @param int $id
|
||||
* @since [v4.0]
|
||||
* @return Redirect
|
||||
*/
|
||||
* Store the updated field
|
||||
*
|
||||
* @todo Allow encrypting/decrypting if encryption status changes
|
||||
*
|
||||
* @author [A. Gianotto] [<snipe@snipe.net>]
|
||||
* @param int $id
|
||||
* @since [v4.0]
|
||||
* @return Redirect
|
||||
* @throws \Illuminate\Auth\Access\AuthorizationException
|
||||
*/
|
||||
public function update(CustomFieldRequest $request, $id)
|
||||
{
|
||||
$field = CustomField::find($id);
|
||||
|
||||
|
||||
$this->authorize('update', $field);
|
||||
|
||||
$field->name = e($request->get("name"));
|
||||
$field->element = e($request->get("element"));
|
||||
$field->field_values = e($request->get("field_values"));
|
||||
$field->user_id = Auth::user()->id;
|
||||
$field->help_text = $request->get("help_text");
|
||||
$field->name = e($request->get("name"));
|
||||
$field->element = e($request->get("element"));
|
||||
$field->field_values = e($request->get("field_values"));
|
||||
$field->user_id = Auth::id();
|
||||
$field->help_text = $request->get("help_text");
|
||||
$field->show_in_email = $request->get("show_in_email", 0);
|
||||
|
||||
if (!in_array(Input::get('format'), array_keys(CustomField::$PredefinedFormats))) {
|
||||
if ($request->get('format') == 'CUSTOM REGEX') {
|
||||
$field->format = e($request->get("custom_format"));
|
||||
} else {
|
||||
$field->format = e($request->get("format"));
|
||||
|
|
|
@ -1,17 +1,14 @@
|
|||
<?php
|
||||
namespace App\Http\Controllers;
|
||||
|
||||
use View;
|
||||
use App\Models\CustomFieldset;
|
||||
use App\Models\CustomField;
|
||||
use Input;
|
||||
use Validator;
|
||||
use Redirect;
|
||||
use App\Models\AssetModel;
|
||||
use Lang;
|
||||
use Auth;
|
||||
use App\Models\CustomField;
|
||||
use App\Models\CustomFieldset;
|
||||
use Illuminate\Http\Request;
|
||||
use Log;
|
||||
use Illuminate\Support\Facades\Auth;
|
||||
use Illuminate\Support\Facades\Input;
|
||||
use Illuminate\Support\Facades\Validator;
|
||||
use Redirect;
|
||||
|
||||
/**
|
||||
* This controller handles all actions related to Custom Asset Fields for
|
||||
|
@ -26,23 +23,26 @@ use Log;
|
|||
class CustomFieldsetsController extends Controller
|
||||
{
|
||||
|
||||
/**
|
||||
* Validates and stores a new custom field.
|
||||
*
|
||||
* @author [Brady Wetherington] [<uberbrady@gmail.com>]
|
||||
* @param int $id
|
||||
* @since [v1.8]
|
||||
* @return View
|
||||
*/
|
||||
/**
|
||||
* Validates and stores a new custom field.
|
||||
*
|
||||
* @author [Brady Wetherington] [<uberbrady@gmail.com>]
|
||||
* @param int $id
|
||||
* @return \Illuminate\Support\Facades\View
|
||||
* @throws \Illuminate\Auth\Access\AuthorizationException
|
||||
* @since [v1.8]
|
||||
*/
|
||||
public function show($id)
|
||||
{
|
||||
$cfset = CustomFieldset::with('fields')->where('id', '=', $id)->orderBy('id', 'ASC')->first();
|
||||
$cfset = CustomFieldset::with('fields')
|
||||
->where('id', '=', $id)->orderBy('id', 'ASC')->first();
|
||||
|
||||
$this->authorize('view', $cfset);
|
||||
|
||||
if ($cfset) {
|
||||
$custom_fields_list = ["" => "Add New Field to Fieldset"] + CustomField::pluck("name", "id")->toArray();
|
||||
|
||||
|
||||
$maxid = 0;
|
||||
foreach ($cfset->fields as $field) {
|
||||
if ($field->pivot->order > $maxid) {
|
||||
|
@ -56,18 +56,26 @@ class CustomFieldsetsController extends Controller
|
|||
return view("custom_fields.fieldsets.view")->with("custom_fieldset", $cfset)->with("maxid", $maxid+1)->with("custom_fields_list", $custom_fields_list);
|
||||
}
|
||||
|
||||
return redirect()->route("fields.index")->with("error", trans('admin/custom_fields/message.fieldset.does_not_exist'));
|
||||
return view("custom_fields.fieldsets.view")
|
||||
->with("custom_fieldset", $cfset)
|
||||
->with("maxid", $maxid+1)
|
||||
->with("custom_fields_list", $custom_fields_list);
|
||||
}
|
||||
|
||||
return redirect()->route("fields.index")
|
||||
->with("error", trans('admin/custom_fields/message.fieldset.does_not_exist'));
|
||||
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Returns a view with a form for creating a new custom fieldset.
|
||||
*
|
||||
* @author [Brady Wetherington] [<uberbrady@gmail.com>]
|
||||
* @since [v1.8]
|
||||
* @return View
|
||||
*/
|
||||
* Returns a view with a form for creating a new custom fieldset.
|
||||
*
|
||||
* @author [Brady Wetherington] [<uberbrady@gmail.com>]
|
||||
* @since [v1.8]
|
||||
* @return \Illuminate\Support\Facades\View
|
||||
* @throws \Illuminate\Auth\Access\AuthorizationException
|
||||
*/
|
||||
public function create()
|
||||
{
|
||||
$this->authorize('create', CustomFieldset::class);
|
||||
|
@ -77,29 +85,30 @@ class CustomFieldsetsController extends Controller
|
|||
|
||||
|
||||
/**
|
||||
* Validates and stores a new custom fieldset.
|
||||
*
|
||||
* @author [Brady Wetherington] [<uberbrady@gmail.com>]
|
||||
* @since [v1.8]
|
||||
* @return Redirect
|
||||
*/
|
||||
* Validates and stores a new custom fieldset.
|
||||
*
|
||||
* @author [Brady Wetherington] [<uberbrady@gmail.com>]
|
||||
* @since [v1.8]
|
||||
* @param Request $request
|
||||
* @return Redirect
|
||||
* @throws \Illuminate\Auth\Access\AuthorizationException
|
||||
*/
|
||||
public function store(Request $request)
|
||||
{
|
||||
$this->authorize('create', CustomFieldset::class);
|
||||
|
||||
$cfset = new CustomFieldset(
|
||||
[
|
||||
$cfset = new CustomFieldset([
|
||||
"name" => e($request->get("name")),
|
||||
"user_id" => Auth::user()->id]
|
||||
);
|
||||
"user_id" => Auth::user()->id
|
||||
]);
|
||||
|
||||
$validator = Validator::make(Input::all(), $cfset->rules);
|
||||
if ($validator->passes()) {
|
||||
$cfset->save();
|
||||
return redirect()->route("fieldsets.show", [$cfset->id])->with('success', trans('admin/custom_fields/message.fieldset.create.success'));
|
||||
} else {
|
||||
return redirect()->back()->withInput()->withErrors($validator);
|
||||
return redirect()->route("fieldsets.show", [$cfset->id])
|
||||
->with('success', trans('admin/custom_fields/message.fieldset.create.success'));
|
||||
}
|
||||
return redirect()->back()->withInput()->withErrors($validator);
|
||||
}
|
||||
|
||||
|
||||
|
@ -136,13 +145,14 @@ class CustomFieldsetsController extends Controller
|
|||
|
||||
|
||||
/**
|
||||
* Validates a custom fieldset and then deletes if it has no models associated.
|
||||
*
|
||||
* @author [Brady Wetherington] [<uberbrady@gmail.com>]
|
||||
* @param int $id
|
||||
* @since [v1.8]
|
||||
* @return View
|
||||
*/
|
||||
* Validates a custom fieldset and then deletes if it has no models associated.
|
||||
*
|
||||
* @author [Brady Wetherington] [<uberbrady@gmail.com>]
|
||||
* @param int $id
|
||||
* @since [v1.8]
|
||||
* @return View
|
||||
* @throws \Illuminate\Auth\Access\AuthorizationException
|
||||
*/
|
||||
public function destroy($id)
|
||||
{
|
||||
$fieldset = CustomFieldset::find($id);
|
||||
|
@ -154,9 +164,8 @@ class CustomFieldsetsController extends Controller
|
|||
if ($models->count() == 0) {
|
||||
$fieldset->delete();
|
||||
return redirect()->route("fields.index")->with("success", trans('admin/custom_fields/message.fieldset.delete.success'));
|
||||
} else {
|
||||
return redirect()->route("fields.index")->with("error", trans('admin/custom_fields/message.fieldset.delete.in_use'));
|
||||
}
|
||||
return redirect()->route("fields.index")->with("error", trans('admin/custom_fields/message.fieldset.delete.in_use'));
|
||||
}
|
||||
|
||||
return redirect()->route("fields.index")->with("error", trans('admin/custom_fields/message.fieldset.does_not_exist'));
|
||||
|
|
|
@ -2,12 +2,8 @@
|
|||
namespace App\Http\Controllers;
|
||||
|
||||
use App\Http\Controllers\AdminController;
|
||||
use App\Models\Actionlog;
|
||||
use View;
|
||||
use Auth;
|
||||
use Redirect;
|
||||
use App\Models\Asset;
|
||||
use App\Models\Company;
|
||||
use View;
|
||||
|
||||
/**
|
||||
* This controller handles all actions related to the Admin Dashboard
|
||||
|
|
|
@ -2,12 +2,11 @@
|
|||
|
||||
namespace App\Http\Controllers;
|
||||
|
||||
use Illuminate\Http\Request;
|
||||
use App\Models\Department;
|
||||
use App\Helpers\Helper;
|
||||
use Auth;
|
||||
use Image;
|
||||
use App\Http\Requests\ImageUploadRequest;
|
||||
use App\Models\Department;
|
||||
use Illuminate\Http\Request;
|
||||
use Illuminate\Support\Facades\Auth;
|
||||
use Illuminate\Support\Facades\Storage;
|
||||
|
||||
class DepartmentsController extends Controller
|
||||
{
|
||||
|
@ -24,7 +23,9 @@ class DepartmentsController extends Controller
|
|||
* @author [A. Gianotto] [<snipe@snipe.net>]
|
||||
* @see AssetController::getDatatable() method that generates the JSON response
|
||||
* @since [v4.0]
|
||||
* @return View
|
||||
* @param Request $request
|
||||
* @return \Illuminate\Support\Facades\View
|
||||
* @throws \Illuminate\Auth\Access\AuthorizationException
|
||||
*/
|
||||
public function index(Request $request)
|
||||
{
|
||||
|
@ -42,8 +43,9 @@ class DepartmentsController extends Controller
|
|||
*
|
||||
* @author [A. Gianotto] [<snipe@snipe.net>]
|
||||
* @since [v4.0]
|
||||
* @param \Illuminate\Http\Request $request
|
||||
* @param ImageUploadRequest $request
|
||||
* @return \Illuminate\Http\Response
|
||||
* @throws \Illuminate\Auth\Access\AuthorizationException
|
||||
*/
|
||||
public function store(ImageUploadRequest $request)
|
||||
{
|
||||
|
@ -53,16 +55,7 @@ class DepartmentsController extends Controller
|
|||
$department->user_id = Auth::user()->id;
|
||||
$department->manager_id = ($request->filled('manager_id' ) ? $request->input('manager_id') : null);
|
||||
|
||||
if ($request->file('image')) {
|
||||
$image = $request->file('image');
|
||||
$file_name = str_random(25).".".$image->getClientOriginalExtension();
|
||||
$path = public_path('uploads/departments/'.$file_name);
|
||||
Image::make($image->getRealPath())->resize(800, null, function ($constraint) {
|
||||
$constraint->aspectRatio();
|
||||
$constraint->upsize();
|
||||
})->save($path);
|
||||
$department->image = $file_name;
|
||||
}
|
||||
$department = $request->handleImages($department);
|
||||
|
||||
if ($department->save()) {
|
||||
return redirect()->route("departments.index")->with('success', trans('admin/departments/message.create.success'));
|
||||
|
@ -78,6 +71,7 @@ class DepartmentsController extends Controller
|
|||
* @param int $id
|
||||
* @since [v4.0]
|
||||
* @return \Illuminate\Contracts\View\View
|
||||
* @throws \Illuminate\Auth\Access\AuthorizationException
|
||||
*/
|
||||
public function show($id)
|
||||
{
|
||||
|
@ -88,7 +82,7 @@ class DepartmentsController extends Controller
|
|||
if (isset($department->id)) {
|
||||
return view('departments/view', compact('department'));
|
||||
}
|
||||
return redirect()->route('departments.index')->with('error', trans('admin/departments/message.does_not_exist', compact('id')));
|
||||
return redirect()->route('departments.index')->with('error', trans('admin/departments/message.does_not_exist'));
|
||||
}
|
||||
|
||||
|
||||
|
@ -99,6 +93,7 @@ class DepartmentsController extends Controller
|
|||
* @see DepartmentsController::postCreate() method that validates and stores the data
|
||||
* @since [v4.0]
|
||||
* @return \Illuminate\Contracts\View\View
|
||||
* @throws \Illuminate\Auth\Access\AuthorizationException
|
||||
*/
|
||||
public function create()
|
||||
{
|
||||
|
@ -115,6 +110,7 @@ class DepartmentsController extends Controller
|
|||
* @param int $locationId
|
||||
* @since [v4.0]
|
||||
* @return \Illuminate\Http\RedirectResponse
|
||||
* @throws \Illuminate\Auth\Access\AuthorizationException
|
||||
*/
|
||||
public function destroy($id)
|
||||
{
|
||||
|
@ -128,23 +124,32 @@ class DepartmentsController extends Controller
|
|||
return redirect()->to(route('departments.index'))->with('error', trans('admin/departments/message.assoc_users'));
|
||||
}
|
||||
|
||||
if ($department->image) {
|
||||
try {
|
||||
Storage::disk('public')->delete('departments'.'/'.$department->image);
|
||||
} catch (\Exception $e) {
|
||||
\Log::debug($e);
|
||||
}
|
||||
}
|
||||
$department->delete();
|
||||
|
||||
return redirect()->back()->with('success', trans('admin/departments/message.delete.success'));
|
||||
|
||||
}
|
||||
|
||||
/**
|
||||
* Makes a form view to edit location information.
|
||||
* Makes a form view to edit Department information.
|
||||
*
|
||||
* @author [A. Gianotto] [<snipe@snipe.net>]
|
||||
* @see LocationsController::postCreate() method that validates and stores
|
||||
* @param int $locationId
|
||||
* @param int $departmentId
|
||||
* @since [v1.0]
|
||||
* @return \Illuminate\Contracts\View\View
|
||||
* @throws \Illuminate\Auth\Access\AuthorizationException
|
||||
*/
|
||||
public function edit($id = null)
|
||||
public function edit($departmentId = null)
|
||||
{
|
||||
if (is_null($item = Department::find($id))) {
|
||||
if (is_null($item = Department::find($departmentId))) {
|
||||
return redirect()->back()->with('error', trans('admin/locations/message.does_not_exist'));
|
||||
}
|
||||
|
||||
|
@ -164,36 +169,7 @@ class DepartmentsController extends Controller
|
|||
$department->fill($request->all());
|
||||
$department->manager_id = ($request->filled('manager_id' ) ? $request->input('manager_id') : null);
|
||||
|
||||
$old_image = $department->image;
|
||||
|
||||
// Set the model's image property to null if the image is being deleted
|
||||
if ($request->input('image_delete') == 1) {
|
||||
$department->image = null;
|
||||
}
|
||||
|
||||
if ($request->file('image')) {
|
||||
$image = $request->file('image');
|
||||
$file_name = $department->id.'-'.str_slug($image->getClientOriginalName()) . "." . $image->getClientOriginalExtension();
|
||||
|
||||
if ($image->getClientOriginalExtension()!='svg') {
|
||||
Image::make($image->getRealPath())->resize(800, null, function ($constraint) {
|
||||
$constraint->aspectRatio();
|
||||
$constraint->upsize();
|
||||
})->save(app('departments_upload_path').$file_name);
|
||||
} else {
|
||||
$image->move(app('departments_upload_path'), $file_name);
|
||||
}
|
||||
$department->image = $file_name;
|
||||
|
||||
}
|
||||
|
||||
if ((($request->file('image')) && (isset($old_image)) && ($old_image!='')) || ($request->input('image_delete') == 1)) {
|
||||
try {
|
||||
unlink(app('departments_upload_path').$old_image);
|
||||
} catch (\Exception $e) {
|
||||
\Log::info($e);
|
||||
}
|
||||
}
|
||||
$department = $request->handleImages($department);
|
||||
|
||||
if ($department->save()) {
|
||||
return redirect()->route("departments.index")->with('success', trans('admin/departments/message.update.success'));
|
||||
|
|
|
@ -1,16 +1,9 @@
|
|||
<?php
|
||||
namespace App\Http\Controllers;
|
||||
|
||||
use App\Helpers\Helper;
|
||||
use Lang;
|
||||
use App\Models\Depreciation;
|
||||
use Redirect;
|
||||
use App\Models\Setting;
|
||||
use DB;
|
||||
use Str;
|
||||
use View;
|
||||
use Auth;
|
||||
use Illuminate\Http\Request;
|
||||
use Illuminate\Support\Facades\Auth;
|
||||
|
||||
/**
|
||||
* This controller handles all actions related to Depreciations for
|
||||
|
@ -21,13 +14,14 @@ use Illuminate\Http\Request;
|
|||
class DepreciationsController extends Controller
|
||||
{
|
||||
/**
|
||||
* Returns a view that invokes the ajax tables which actually contains
|
||||
* the content for the depreciation listing, which is generated in getDatatable.
|
||||
*
|
||||
* @author [A. Gianotto] [<snipe@snipe.net]
|
||||
* @see DepreciationsController::getDatatable() method that generates the JSON response
|
||||
* @since [v1.0]
|
||||
* @return \Illuminate\Contracts\View\View
|
||||
* Returns a view that invokes the ajax tables which actually contains
|
||||
* the content for the depreciation listing, which is generated in getDatatable.
|
||||
*
|
||||
* @author [A. Gianotto] [<snipe@snipe.net]
|
||||
* @see DepreciationsController::getDatatable() method that generates the JSON response
|
||||
* @since [v1.0]
|
||||
* @return \Illuminate\Contracts\View\View
|
||||
* @throws \Illuminate\Auth\Access\AuthorizationException
|
||||
*/
|
||||
public function index()
|
||||
{
|
||||
|
@ -39,12 +33,13 @@ class DepreciationsController extends Controller
|
|||
|
||||
|
||||
/**
|
||||
* Returns a view that displays a form to create a new depreciation.
|
||||
*
|
||||
* @author [A. Gianotto] [<snipe@snipe.net]
|
||||
* @see DepreciationsController::postCreate()
|
||||
* @since [v1.0]
|
||||
* @return \Illuminate\Contracts\View\View
|
||||
* Returns a view that displays a form to create a new depreciation.
|
||||
*
|
||||
* @author [A. Gianotto] [<snipe@snipe.net]
|
||||
* @see DepreciationsController::postCreate()
|
||||
* @since [v1.0]
|
||||
* @return \Illuminate\Contracts\View\View
|
||||
* @throws \Illuminate\Auth\Access\AuthorizationException
|
||||
*/
|
||||
public function create()
|
||||
{
|
||||
|
@ -63,6 +58,7 @@ class DepreciationsController extends Controller
|
|||
* @since [v1.0]
|
||||
* @param Request $request
|
||||
* @return \Illuminate\Http\RedirectResponse
|
||||
* @throws \Illuminate\Auth\Access\AuthorizationException
|
||||
*/
|
||||
public function store(Request $request)
|
||||
{
|
||||
|
@ -84,13 +80,14 @@ class DepreciationsController extends Controller
|
|||
}
|
||||
|
||||
/**
|
||||
* Returns a view that displays a form to update a depreciation.
|
||||
*
|
||||
* @author [A. Gianotto] [<snipe@snipe.net]
|
||||
* @see DepreciationsController::postEdit()
|
||||
* @param int $depreciationId
|
||||
* @since [v1.0]
|
||||
* @return \Illuminate\Contracts\View\View
|
||||
* Returns a view that displays a form to update a depreciation.
|
||||
*
|
||||
* @author [A. Gianotto] [<snipe@snipe.net]
|
||||
* @see DepreciationsController::postEdit()
|
||||
* @param int $depreciationId
|
||||
* @since [v1.0]
|
||||
* @return \Illuminate\Contracts\View\View
|
||||
* @throws \Illuminate\Auth\Access\AuthorizationException
|
||||
*/
|
||||
public function edit($depreciationId = null)
|
||||
{
|
||||
|
@ -115,6 +112,7 @@ class DepreciationsController extends Controller
|
|||
* @param int $depreciationId
|
||||
* @return \Illuminate\Http\RedirectResponse
|
||||
* @since [v1.0]
|
||||
* @throws \Illuminate\Auth\Access\AuthorizationException
|
||||
*/
|
||||
public function update(Request $request, $depreciationId = null)
|
||||
{
|
||||
|
@ -147,17 +145,18 @@ class DepreciationsController extends Controller
|
|||
* @since [v1.0]
|
||||
* @param integer $depreciationId
|
||||
* @return \Illuminate\Http\RedirectResponse
|
||||
* @throws \Illuminate\Auth\Access\AuthorizationException
|
||||
*/
|
||||
public function destroy($depreciationId)
|
||||
{
|
||||
// Check if the depreciation exists
|
||||
if (is_null($depreciation = Depreciation::find($depreciationId))) {
|
||||
if (is_null($depreciation = Depreciation::withCount('models as models_count')->find($depreciationId))) {
|
||||
return redirect()->route('depreciations.index')->with('error', trans('admin/depreciations/message.not_found'));
|
||||
}
|
||||
|
||||
$this->authorize('delete', $depreciation);
|
||||
|
||||
if ($depreciation->has_models() > 0) {
|
||||
if ($depreciation->models_count > 0) {
|
||||
// Redirect to the asset management page
|
||||
return redirect()->route('depreciations.index')->with('error', trans('admin/depreciations/message.assoc_users'));
|
||||
}
|
||||
|
@ -175,6 +174,7 @@ class DepreciationsController extends Controller
|
|||
* @param int $depreciationId
|
||||
* @since [v1.0]
|
||||
* @return \Illuminate\Contracts\View\View
|
||||
* @throws \Illuminate\Auth\Access\AuthorizationException
|
||||
*/
|
||||
public function show($id)
|
||||
{
|
||||
|
|
|
@ -1,15 +1,9 @@
|
|||
<?php
|
||||
namespace App\Http\Controllers;
|
||||
|
||||
use Config;
|
||||
use Input;
|
||||
use Lang;
|
||||
use Redirect;
|
||||
use App\Models\Setting;
|
||||
use Validator;
|
||||
use View;
|
||||
use App\Models\Group;
|
||||
use App\Helpers\Helper;
|
||||
use App\Models\Group;
|
||||
use Illuminate\Support\Facades\Input;
|
||||
|
||||
/**
|
||||
* This controller handles all actions related to User Groups for
|
||||
|
@ -109,7 +103,6 @@ class GroupsController extends Controller
|
|||
*/
|
||||
public function update($id = null)
|
||||
{
|
||||
$permissions = config('permissions');
|
||||
if (!$group = Group::find($id)) {
|
||||
return redirect()->route('groups.index')->with('error', trans('admin/groups/message.group_not_found', compact('id')));
|
||||
}
|
||||
|
@ -126,13 +119,14 @@ class GroupsController extends Controller
|
|||
}
|
||||
|
||||
/**
|
||||
* Validates and deletes the User Group.
|
||||
*
|
||||
* @author [A. Gianotto] [<snipe@snipe.net]
|
||||
* @see GroupsController::getEdit()
|
||||
* @param int $id
|
||||
* @since [v1.0]
|
||||
* @return \Illuminate\Http\RedirectResponse
|
||||
* Validates and deletes the User Group.
|
||||
*
|
||||
* @author [A. Gianotto] [<snipe@snipe.net]
|
||||
* @see GroupsController::getEdit()
|
||||
* @param int $id
|
||||
* @since [v1.0]
|
||||
* @return \Illuminate\Http\RedirectResponse
|
||||
* @throws \Exception
|
||||
*/
|
||||
public function destroy($id = null)
|
||||
{
|
||||
|
@ -152,9 +146,9 @@ class GroupsController extends Controller
|
|||
* the content for the group detail page.
|
||||
*
|
||||
* @author [A. Gianotto] [<snipe@snipe.net>]
|
||||
* @param int $locationId
|
||||
* @since [v4.0.11]
|
||||
* @param $id
|
||||
* @return \Illuminate\Contracts\View\View
|
||||
* @since [v4.0.11]
|
||||
*/
|
||||
public function show($id)
|
||||
{
|
||||
|
|
|
@ -3,18 +3,19 @@
|
|||
namespace App\Http\Controllers;
|
||||
|
||||
use App\Http\Transformers\ImportsTransformer;
|
||||
use App\Models\Import;
|
||||
use Illuminate\Http\Request;
|
||||
use App\Models\Asset;
|
||||
|
||||
use App\Models\Import;
|
||||
|
||||
class ImportsController extends Controller
|
||||
{
|
||||
/**
|
||||
* @return \Illuminate\Contracts\View\Factory|\Illuminate\View\View
|
||||
* @throws \Illuminate\Auth\Access\AuthorizationException
|
||||
*/
|
||||
public function index()
|
||||
{
|
||||
$this->authorize('import');
|
||||
$imports = Import::latest()->get();
|
||||
$imports = (new ImportsTransformer)->transformImports($imports);
|
||||
$imports = (new ImportsTransformer)->transformImports(Import::latest()->get());
|
||||
return view('importer/import')->with('imports', $imports);
|
||||
}
|
||||
}
|
||||
|
|
71
app/Http/Controllers/Kits/CheckoutKitController.php
Normal file
71
app/Http/Controllers/Kits/CheckoutKitController.php
Normal file
|
@ -0,0 +1,71 @@
|
|||
<?php
|
||||
namespace App\Http\Controllers\Kits;
|
||||
|
||||
use App\Http\Controllers\CheckInOutRequest;
|
||||
use App\Http\Controllers\Controller;
|
||||
use App\Models\PredefinedKit;
|
||||
use App\Models\PredefinedLicence;
|
||||
use App\Models\PredefinedModel;
|
||||
use App\Models\User;
|
||||
use App\Services\PredefinedKitCheckoutService;
|
||||
use Illuminate\Http\Request;
|
||||
use Illuminate\Support\Arr;
|
||||
|
||||
/**
|
||||
* This controller handles all access kits management:
|
||||
* list, add/remove/change
|
||||
*
|
||||
* @author [D. Minaev.] [<dmitriy.minaev.v@gmail.com>]
|
||||
*/
|
||||
class CheckoutKitController extends Controller
|
||||
{
|
||||
|
||||
public $kitService;
|
||||
use CheckInOutRequest;
|
||||
|
||||
public function __construct(PredefinedKitCheckoutService $kitService)
|
||||
{
|
||||
$this->kitService = $kitService;
|
||||
}
|
||||
|
||||
/**
|
||||
* Show Bulk Checkout Page
|
||||
*
|
||||
* @author [D. Minaev.] [<dmitriy.minaev.v@gmail.com>]
|
||||
* @return View View to checkout
|
||||
*/
|
||||
public function showCheckout($kit_id)
|
||||
{
|
||||
$this->authorize('checkout', Asset::class);
|
||||
|
||||
$kit = PredefinedKit::findOrFail($kit_id);
|
||||
return view('kits/checkout')->with('kit', $kit);
|
||||
}
|
||||
|
||||
/**
|
||||
* Validate and process the new Predefined Kit data.
|
||||
*
|
||||
* @author [D. Minaev.] [<dmitriy.minaev.v@gmail.com>]
|
||||
* @return Redirect
|
||||
*/
|
||||
public function store(Request $request, $kit_id)
|
||||
{
|
||||
$user_id = e($request->get('user_id'));
|
||||
if (is_null($user = User::find($user_id))) {
|
||||
return redirect()->back()->with('error', trans('admin/users/message.user_not_found'));
|
||||
}
|
||||
|
||||
$kit = new PredefinedKit();
|
||||
$kit->id = $kit_id;
|
||||
|
||||
$checkout_result = $this->kitService->checkout($request, $kit, $user);
|
||||
if (Arr::has($checkout_result, 'errors') && count($checkout_result['errors']) > 0 ) {
|
||||
return redirect()->back()->with('error', 'Checkout error')->with('error_messages', $checkout_result['errors']); // TODO: trans
|
||||
}
|
||||
return redirect()->back()->with('success', 'Checkout was successful')
|
||||
->with('assets', Arr::get($checkout_result, 'assets', null))
|
||||
->with('accessories', Arr::get($checkout_result, 'accessories', null))
|
||||
->with('consumables', Arr::get($checkout_result, 'consumables', null)); // TODO: trans
|
||||
|
||||
}
|
||||
}
|
469
app/Http/Controllers/Kits/PredefinedKitsController.php
Normal file
469
app/Http/Controllers/Kits/PredefinedKitsController.php
Normal file
|
@ -0,0 +1,469 @@
|
|||
<?php
|
||||
namespace App\Http\Controllers\Kits;
|
||||
|
||||
use App\Http\Controllers\Controller;
|
||||
use App\Http\Requests\ImageUploadRequest;
|
||||
use App\Models\PredefinedKit;
|
||||
use App\Models\PredefinedLicence;
|
||||
use App\Models\PredefinedModel;
|
||||
use Illuminate\Http\Request;
|
||||
|
||||
/**
|
||||
* This controller handles all access kits management:
|
||||
* list, add/remove/change
|
||||
*
|
||||
* @author [D. Minaev] [<dmitriy.minaev.v@gmail.com>]
|
||||
*/
|
||||
class PredefinedKitsController extends Controller
|
||||
{
|
||||
/**
|
||||
* @author [D. Minaev] [<dmitriy.minaev.v@gmail.com>]
|
||||
* @return \Illuminate\Contracts\View\View
|
||||
* @throws \Illuminate\Auth\Access\AuthorizationException
|
||||
*/
|
||||
public function index()
|
||||
{
|
||||
$this->authorize('index', PredefinedKit::class);
|
||||
return view('kits/index');
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns a form view to create a new kit.
|
||||
*
|
||||
* @author [D. Minaev] [<dmitriy.minaev.v@gmail.com>]
|
||||
* @throws \Illuminate\Auth\Access\AuthorizationException
|
||||
* @return mixed
|
||||
*/
|
||||
public function create()
|
||||
{
|
||||
$this->authorize('create', PredefinedKit::class);
|
||||
return view('kits/create')->with('item', new PredefinedKit);
|
||||
}
|
||||
|
||||
/**
|
||||
* Validate and process the new Predefined Kit data.
|
||||
*
|
||||
* @author [D. Minaev] [<dmitriy.minaev.v@gmail.com>]
|
||||
* @return Redirect
|
||||
*/
|
||||
public function store(ImageUploadRequest $request)
|
||||
{
|
||||
$this->authorize('create', PredefinedKit::class);
|
||||
// Create a new Predefined Kit
|
||||
$kit = new PredefinedKit;
|
||||
$kit->name = $request->input('name');
|
||||
|
||||
if (!$kit->save()) {
|
||||
return redirect()->back()->withInput()->withErrors($kit->getErrors());
|
||||
}
|
||||
$success = $kit->save();
|
||||
if (!$success) {
|
||||
return redirect()->back()->withInput()->withErrors($kit->getErrors());
|
||||
}
|
||||
return redirect()->route("kits.index")->with('success', 'Kit was successfully created.'); // TODO: trans()
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns a view containing the Predefined Kit edit form.
|
||||
*
|
||||
* @author [D. Minaev] [<dmitriy.minaev.v@gmail.com>]
|
||||
* @since [v1.0]
|
||||
* @param int $kit_id
|
||||
* @return View
|
||||
*/
|
||||
public function edit($kit_id=null)
|
||||
{
|
||||
$this->authorize('update', PredefinedKit::class);
|
||||
if ($kit = PredefinedKit::find($kit_id)) {
|
||||
return view('kits/edit')
|
||||
->with('item', $kit)
|
||||
->with('models', $kit->models)
|
||||
->with('licenses', $kit->licenses);
|
||||
}
|
||||
return redirect()->route('kits.index')->with('error', 'Kit does not exist'); // TODO: trans
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Validates and processes form data from the edit
|
||||
* Predefined Kit form based on the kit ID passed.
|
||||
*
|
||||
* @author [D. Minaev] [<dmitriy.minaev.v@gmail.com>]
|
||||
* @since [v1.0]
|
||||
* @param int $kit_id
|
||||
* @return Redirect
|
||||
*/
|
||||
public function update(ImageUploadRequest $request, $kit_id=null)
|
||||
{
|
||||
$this->authorize('update', PredefinedKit::class);
|
||||
// Check if the kit exists
|
||||
if (is_null($kit = PredefinedKit::find($kit_id))) {
|
||||
// Redirect to the kits management page
|
||||
return redirect()->route('kits.index')->with('error', 'Kit does not exist'); // TODO: trans
|
||||
}
|
||||
|
||||
$kit->name = $request->input('name');
|
||||
|
||||
if ($kit->save()) {
|
||||
return redirect()->route("kits.index")->with('success', 'Kit was successfully updated'); // TODO: trans
|
||||
}
|
||||
return redirect()->back()->withInput()->withErrors($kit->getErrors());
|
||||
}
|
||||
|
||||
/**
|
||||
* Validate and delete the given Predefined Kit.
|
||||
* Also delete all contained helping items
|
||||
*
|
||||
* @author [D. Minaev] [<dmitriy.minaev.v@gmail.com>]
|
||||
* @since [v1.0]
|
||||
* @param int $kit_id
|
||||
* @return Redirect
|
||||
*/
|
||||
public function destroy($kit_id)
|
||||
{
|
||||
$this->authorize('delete', PredefinedKit::class);
|
||||
// Check if the kit exists
|
||||
if (is_null($kit = PredefinedKit::find($kit_id))) {
|
||||
return redirect()->route('kits.index')->with('error', 'Kit not found'); // TODO: trans
|
||||
}
|
||||
|
||||
// Delete childs
|
||||
$kit->models()->detach();
|
||||
$kit->licenses()->detach();
|
||||
$kit->consumables()->detach();
|
||||
$kit->accessories()->detach();
|
||||
// Delete the kit
|
||||
$kit->delete();
|
||||
|
||||
// Redirect to the kit management page
|
||||
return redirect()->route('kits.index')->with('success', 'Kit was successfully deleted'); // TODO: trans
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the kit information to present to the kit view page
|
||||
*
|
||||
* @author [D. Minaev] [<dmitriy.minaev.v@gmail.com>]
|
||||
* @since [v1.0]
|
||||
* @param int $modelId
|
||||
* @return View
|
||||
*/
|
||||
public function show($kit_id=null)
|
||||
{
|
||||
return $this->edit($kit_id);
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Returns a view containing the Predefined Kit edit form.
|
||||
*
|
||||
* @author [D. Minaev] [<dmitriy.minaev.v@gmail.com>]
|
||||
* @param int $kit_id
|
||||
* @return View
|
||||
*/
|
||||
public function editModel($kit_id, $model_id)
|
||||
{
|
||||
$this->authorize('update', PredefinedKit::class);
|
||||
if (($kit = PredefinedKit::find($kit_id))
|
||||
&& ($model = $kit->models()->find($model_id))) {
|
||||
|
||||
return view('kits/model-edit', [
|
||||
'kit' => $kit,
|
||||
'model' => $model,
|
||||
'item' => $model->pivot
|
||||
]);
|
||||
}
|
||||
return redirect()->route('kits.index')->with('error', 'Kit does not exist'); // TODO: trans
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the kit information to present to the kit view page
|
||||
*
|
||||
* @author [D. Minaev] [<dmitriy.minaev.v@gmail.com>]
|
||||
* @param int $modelId
|
||||
* @return View
|
||||
*/
|
||||
public function updateModel(Request $request, $kit_id, $model_id)
|
||||
{
|
||||
|
||||
$this->authorize('update', PredefinedKit::class);
|
||||
if (is_null($kit = PredefinedKit::find($kit_id))) {
|
||||
// Redirect to the kits management page
|
||||
return redirect()->route('kits.index')->with('error', 'Kit does not exist'); // TODO: trans
|
||||
}
|
||||
|
||||
$validator = \Validator::make($request->all(), $kit->makeModelRules($model_id));
|
||||
|
||||
if ($validator->fails()) {
|
||||
return redirect()->back()->withInput()->withErrors($validator);
|
||||
}
|
||||
|
||||
$pivot = $kit->models()->wherePivot('id', $request->input('pivot_id'))->first()->pivot;
|
||||
|
||||
$pivot->model_id = $request->input('model_id');
|
||||
$pivot->quantity = $request->input('quantity');
|
||||
$pivot->save();
|
||||
|
||||
return redirect()->route('kits.edit', $kit_id)->with('success', 'Model updated successfully.'); // TODO: trans
|
||||
}
|
||||
|
||||
/**
|
||||
* Remove the model from set
|
||||
*
|
||||
* @author [D. Minaev] [<dmitriy.minaev.v@gmail.com>]
|
||||
* @param int $modelId
|
||||
* @return View
|
||||
*/
|
||||
public function detachModel($kit_id, $model_id)
|
||||
{
|
||||
$this->authorize('update', PredefinedKit::class);
|
||||
if (is_null($kit = PredefinedKit::find($kit_id))) {
|
||||
// Redirect to the kits management page
|
||||
return redirect()->route('kits.index')->with('error', 'Kit does not exist'); // TODO: trans
|
||||
}
|
||||
|
||||
// Delete childs
|
||||
$kit->models()->detach($model_id);
|
||||
|
||||
// Redirect to the kit management page
|
||||
return redirect()->route('kits.edit', $kit_id)->with('success', 'Model was successfully detached'); // TODO: trans
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns a view containing attached license edit form.
|
||||
*
|
||||
* @author [D. Minaev] [<dmitriy.minaev.v@gmail.com>]
|
||||
* @param int $kit_id
|
||||
* @param int $license_id
|
||||
* @return View
|
||||
*/
|
||||
public function editLicense($kit_id, $license_id)
|
||||
{
|
||||
$this->authorize('update', PredefinedKit::class);
|
||||
if (!($kit = PredefinedKit::find($kit_id))) {
|
||||
return redirect()->route('kits.index')->with('error', 'Kit does not exist'); // TODO: trans
|
||||
}
|
||||
if (!($license = $kit->licenses()->find($license_id))) {
|
||||
return redirect()->route('kits.index')->with('error', 'License does not exist'); // TODO: trans
|
||||
}
|
||||
|
||||
return view('kits/license-edit', [
|
||||
'kit' => $kit,
|
||||
'license' => $license,
|
||||
'item' => $license->pivot
|
||||
]);
|
||||
}
|
||||
|
||||
/**
|
||||
* Update attached licese
|
||||
*
|
||||
* @author [D. Minaev] [<dmitriy.minaev.v@gmail.com>]
|
||||
* @param int $kit_id
|
||||
* @param int $license_id
|
||||
* @return View
|
||||
*/
|
||||
public function updateLicense(Request $request, $kit_id, $license_id)
|
||||
{
|
||||
|
||||
$this->authorize('update', PredefinedKit::class);
|
||||
if (is_null($kit = PredefinedKit::find($kit_id))) {
|
||||
// Redirect to the kits management page
|
||||
return redirect()->route('kits.index')->with('error', 'Kit does not exist'); // TODO: trans
|
||||
}
|
||||
|
||||
$validator = \Validator::make($request->all(), $kit->makeLicenseRules($license_id));
|
||||
|
||||
if ($validator->fails()) {
|
||||
return redirect()->back()->withInput()->withErrors($validator);
|
||||
}
|
||||
|
||||
$pivot = $kit->licenses()->wherePivot('id', $request->input('pivot_id'))->first()->pivot;
|
||||
|
||||
$pivot->license_id = $request->input('license_id');
|
||||
$pivot->quantity = $request->input('quantity');
|
||||
$pivot->save();
|
||||
|
||||
return redirect()->route('kits.edit', $kit_id)->with('success', 'License updated successfully.'); // TODO: trans
|
||||
}
|
||||
|
||||
/**
|
||||
* Remove the license from set
|
||||
*
|
||||
* @author [D. Minaev] [<dmitriy.minaev.v@gmail.com>]
|
||||
* @param int $kit_id
|
||||
* @param int $license_id
|
||||
* @return View
|
||||
*/
|
||||
public function detachLicense($kit_id, $license_id)
|
||||
{
|
||||
$this->authorize('update', PredefinedKit::class);
|
||||
if (is_null($kit = PredefinedKit::find($kit_id))) {
|
||||
// Redirect to the kits management page
|
||||
return redirect()->route('kits.index')->with('error', 'Kit does not exist'); // TODO: trans
|
||||
}
|
||||
|
||||
// Delete childs
|
||||
$kit->licenses()->detach($license_id);
|
||||
|
||||
// Redirect to the kit management page
|
||||
return redirect()->route('kits.edit', $kit_id)->with('success', 'License was successfully detached'); // TODO: trans
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Returns a view containing attached accessory edit form.
|
||||
*
|
||||
* @author [D. Minaev] [<dmitriy.minaev.v@gmail.com>]
|
||||
* @param int $kit_id
|
||||
* @param int $accessoryId
|
||||
* @return View
|
||||
*/
|
||||
public function editAccessory($kit_id, $accessory_id)
|
||||
{
|
||||
$this->authorize('update', PredefinedKit::class);
|
||||
if (!($kit = PredefinedKit::find($kit_id))) {
|
||||
return redirect()->route('kits.index')->with('error', 'Kit does not exist'); // TODO: trans
|
||||
}
|
||||
if (!($accessory = $kit->accessories()->find($accessory_id))) {
|
||||
return redirect()->route('kits.index')->with('error', 'Accessory does not exist'); // TODO: trans
|
||||
}
|
||||
|
||||
return view('kits/accessory-edit', [
|
||||
'kit' => $kit,
|
||||
'accessory' => $accessory,
|
||||
'item' => $accessory->pivot
|
||||
]);
|
||||
}
|
||||
|
||||
/**
|
||||
* Update attached accessory
|
||||
*
|
||||
* @author [D. Minaev] [<dmitriy.minaev.v@gmail.com>]
|
||||
* @param int $kit_id
|
||||
* @param int $accessory_id
|
||||
* @return View
|
||||
*/
|
||||
public function updateAccessory(Request $request, $kit_id, $accessory_id)
|
||||
{
|
||||
|
||||
$this->authorize('update', PredefinedKit::class);
|
||||
if (is_null($kit = PredefinedKit::find($kit_id))) {
|
||||
// Redirect to the kits management page
|
||||
return redirect()->route('kits.index')->with('error', 'Kit does not exist'); // TODO: trans
|
||||
}
|
||||
|
||||
$validator = \Validator::make($request->all(), $kit->makeAccessoryRules($accessory_id));
|
||||
|
||||
if ($validator->fails()) {
|
||||
return redirect()->back()->withInput()->withErrors($validator);
|
||||
}
|
||||
|
||||
$pivot = $kit->accessories()->wherePivot('id', $request->input('pivot_id'))->first()->pivot;
|
||||
|
||||
$pivot->accessory_id = $request->input('accessory_id');
|
||||
$pivot->quantity = $request->input('quantity');
|
||||
$pivot->save();
|
||||
|
||||
return redirect()->route('kits.edit', $kit_id)->with('success', 'Accessory updated successfully.'); // TODO: trans
|
||||
}
|
||||
|
||||
/**
|
||||
* Remove the accessory from set
|
||||
*
|
||||
* @author [D. Minaev] [<dmitriy.minaev.v@gmail.com>]
|
||||
* @param int $accessory_id
|
||||
* @return View
|
||||
*/
|
||||
public function detachAccessory($kit_id, $accessory_id)
|
||||
{
|
||||
$this->authorize('update', PredefinedKit::class);
|
||||
if (is_null($kit = PredefinedKit::find($kit_id))) {
|
||||
// Redirect to the kits management page
|
||||
return redirect()->route('kits.index')->with('error', 'Kit does not exist'); // TODO: trans
|
||||
}
|
||||
|
||||
// Delete childs
|
||||
$kit->accessories()->detach($accessory_id);
|
||||
|
||||
// Redirect to the kit management page
|
||||
return redirect()->route('kits.edit', $kit_id)->with('success', 'Accessory was successfully detached'); // TODO: trans
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns a view containing attached consumable edit form.
|
||||
*
|
||||
* @author [D. Minaev] [<dmitriy.minaev.v@gmail.com>]
|
||||
* @param int $kit_id
|
||||
* @param int $consumable_id
|
||||
* @return View
|
||||
*/
|
||||
public function editConsumable($kit_id, $consumable_id)
|
||||
{
|
||||
$this->authorize('update', PredefinedKit::class);
|
||||
if (!($kit = PredefinedKit::find($kit_id))) {
|
||||
return redirect()->route('kits.index')->with('error', 'Kit does not exist'); // TODO: trans
|
||||
}
|
||||
if (!($consumable = $kit->consumables()->find($consumable_id))) {
|
||||
return redirect()->route('kits.index')->with('error', 'Consumable does not exist'); // TODO: trans
|
||||
}
|
||||
|
||||
return view('kits/consumable-edit', [
|
||||
'kit' => $kit,
|
||||
'consumable' => $consumable,
|
||||
'item' => $consumable->pivot
|
||||
]);
|
||||
}
|
||||
|
||||
/**
|
||||
* Update attached consumable
|
||||
*
|
||||
* @author [D. Minaev] [<dmitriy.minaev.v@gmail.com>]
|
||||
* @param int $kit_id
|
||||
* @param int $consumableId
|
||||
* @return View
|
||||
*/
|
||||
public function updateConsumable(Request $request, $kit_id, $consumable_id)
|
||||
{
|
||||
|
||||
$this->authorize('update', PredefinedKit::class);
|
||||
if (is_null($kit = PredefinedKit::find($kit_id))) {
|
||||
// Redirect to the kits management page
|
||||
return redirect()->route('kits.index')->with('error', 'Kit does not exist'); // TODO: trans
|
||||
}
|
||||
|
||||
$validator = \Validator::make($request->all(), $kit->makeConsumableRules($consumable_id));
|
||||
|
||||
if ($validator->fails()) {
|
||||
return redirect()->back()->withInput()->withErrors($validator);
|
||||
}
|
||||
|
||||
$pivot = $kit->consumables()->wherePivot('id', $request->input('pivot_id'))->first()->pivot;
|
||||
|
||||
$pivot->consumable_id = $request->input('consumable_id');
|
||||
$pivot->quantity = $request->input('quantity');
|
||||
$pivot->save();
|
||||
|
||||
return redirect()->route('kits.edit', $kit_id)->with('success', 'Consumable updated successfully.'); // TODO: trans
|
||||
}
|
||||
|
||||
/**
|
||||
* Remove the consumable from set
|
||||
*
|
||||
* @author [D. Minaev] [<dmitriy.minaev.v@gmail.com>]
|
||||
* @param int $consumable_id
|
||||
* @return View
|
||||
*/
|
||||
public function detachConsumable($kit_id, $consumable_id)
|
||||
{
|
||||
$this->authorize('update', PredefinedKit::class);
|
||||
if (is_null($kit = PredefinedKit::find($kit_id))) {
|
||||
// Redirect to the kits management page
|
||||
return redirect()->route('kits.index')->with('error', 'Kit does not exist'); // TODO: trans
|
||||
}
|
||||
|
||||
// Delete childs
|
||||
$kit->consumables()->detach($consumable_id);
|
||||
|
||||
// Redirect to the kit management page
|
||||
return redirect()->route('kits.edit', $kit_id)->with('success', 'Consumable was successfully detached'); // TODO: trans
|
||||
}
|
||||
}
|
105
app/Http/Controllers/Licenses/LicenseCheckinController.php
Normal file
105
app/Http/Controllers/Licenses/LicenseCheckinController.php
Normal file
|
@ -0,0 +1,105 @@
|
|||
<?php
|
||||
|
||||
namespace App\Http\Controllers\Licenses;
|
||||
|
||||
use App\Events\CheckoutableCheckedIn;
|
||||
use App\Http\Controllers\Controller;
|
||||
use App\Models\License;
|
||||
use App\Models\LicenseSeat;
|
||||
use App\Models\User;
|
||||
use Illuminate\Http\Request;
|
||||
use Illuminate\Support\Facades\Auth;
|
||||
use Illuminate\Support\Facades\Input;
|
||||
use Illuminate\Support\Facades\Session;
|
||||
use Illuminate\Support\Facades\Validator;
|
||||
|
||||
class LicenseCheckinController extends Controller
|
||||
{
|
||||
|
||||
/**
|
||||
* Makes the form view to check a license seat back into inventory.
|
||||
*
|
||||
* @author [A. Gianotto] [<snipe@snipe.net>]
|
||||
* @since [v1.0]
|
||||
* @param int $seatId
|
||||
* @param string $backTo
|
||||
* @return \Illuminate\Contracts\View\View
|
||||
* @throws \Illuminate\Auth\Access\AuthorizationException
|
||||
*/
|
||||
public function create($seatId = null, $backTo = null)
|
||||
{
|
||||
// Check if the asset exists
|
||||
if (is_null($licenseSeat = LicenseSeat::find($seatId)) || is_null($license = License::find($licenseSeat->license_id))) {
|
||||
// Redirect to the asset management page with error
|
||||
return redirect()->route('licenses.index')->with('error', trans('admin/licenses/message.not_found'));
|
||||
}
|
||||
|
||||
$this->authorize('checkout', $license);
|
||||
return view('licenses/checkin', compact('licenseSeat'))->with('backto', $backTo);
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Validates and stores the license checkin action.
|
||||
*
|
||||
* @author [A. Gianotto] [<snipe@snipe.net>]
|
||||
* @see LicenseCheckinController::create() method that provides the form view
|
||||
* @since [v1.0]
|
||||
* @param int $seatId
|
||||
* @param string $backTo
|
||||
* @return \Illuminate\Http\RedirectResponse
|
||||
* @throws \Illuminate\Auth\Access\AuthorizationException
|
||||
*/
|
||||
public function store(Request $request, $seatId = null, $backTo = null)
|
||||
{
|
||||
// Check if the asset exists
|
||||
if (is_null($licenseSeat = LicenseSeat::find($seatId))) {
|
||||
// Redirect to the asset management page with error
|
||||
return redirect()->route('licenses.index')->with('error', trans('admin/licenses/message.not_found'));
|
||||
}
|
||||
|
||||
$license = License::find($licenseSeat->license_id);
|
||||
$this->authorize('checkout', $license);
|
||||
|
||||
if (!$license->reassignable) {
|
||||
// Not allowed to checkin
|
||||
Session::flash('error', 'License not reassignable.');
|
||||
return redirect()->back()->withInput();
|
||||
}
|
||||
|
||||
// Declare the rules for the form validation
|
||||
$rules = [
|
||||
'note' => 'string',
|
||||
'notes' => 'string',
|
||||
];
|
||||
|
||||
// Create a new validator instance from our validation rules
|
||||
$validator = Validator::make(Input::all(), $rules);
|
||||
|
||||
// If validation fails, we'll exit the operation now.
|
||||
if ($validator->fails()) {
|
||||
// Ooops.. something went wrong
|
||||
return redirect()->back()->withInput()->withErrors($validator);
|
||||
}
|
||||
$return_to = User::find($licenseSeat->assigned_to);
|
||||
|
||||
// Update the asset data
|
||||
$licenseSeat->assigned_to = null;
|
||||
$licenseSeat->asset_id = null;
|
||||
|
||||
// Was the asset updated?
|
||||
if ($licenseSeat->save()) {
|
||||
|
||||
event(new CheckoutableCheckedIn($licenseSeat, $return_to, Auth::user(), $request->input('note')));
|
||||
|
||||
if ($backTo=='user') {
|
||||
return redirect()->route("users.show", $return_to->id)->with('success', trans('admin/licenses/message.checkin.success'));
|
||||
}
|
||||
return redirect()->route("licenses.show", $licenseSeat->license_id)->with('success', trans('admin/licenses/message.checkin.success'));
|
||||
}
|
||||
|
||||
// Redirect to the license page with error
|
||||
return redirect()->route("licenses.index")->with('error', trans('admin/licenses/message.checkin.error'));
|
||||
}
|
||||
|
||||
}
|
Some files were not shown because too many files have changed in this diff Show more
Loading…
Reference in a new issue