mirror of
https://github.com/crater-invoice/crater.git
synced 2025-10-27 11:41:09 -04:00
Compare commits
247 Commits
increase-s
...
dark-globa
| Author | SHA1 | Date | |
|---|---|---|---|
| 3defe3fa29 | |||
| c5acf1343e | |||
| 0321ca5515 | |||
| bd345949e5 | |||
| b4b00ebdd6 | |||
| 43316dae28 | |||
| 80e2548b38 | |||
| e8d92cd641 | |||
| 2c8bb38531 | |||
| 04c7ae39a2 | |||
| af2482a69c | |||
| cac35826c2 | |||
| 18b5705372 | |||
| c61fbad5ce | |||
| 15f3f566e3 | |||
| 2e93082282 | |||
| ca55221c4f | |||
| 98196194e2 | |||
| 7447cc24f9 | |||
| 889d22d92c | |||
| bc8f2cd484 | |||
| 4e47f58bad | |||
| d8c429912e | |||
| df04fd9e53 | |||
| 0aaf0e7e75 | |||
| 3d0b89bb4d | |||
| 38c4b9ebce | |||
| 7be59e78e0 | |||
| 189c51cdf4 | |||
| 204483836a | |||
| 33bc9ded65 | |||
| 4271ef451e | |||
| 6eb44fba93 | |||
| 96e7300583 | |||
| a479d966d1 | |||
| bca2794c4c | |||
| cb88c19059 | |||
| 946c7efab4 | |||
| d7b1d15f93 | |||
| 94e1efe115 | |||
| b0e38b74e9 | |||
| bd5f0fe5cf | |||
| 787619b907 | |||
| fd70ab9a99 | |||
| 33315638df | |||
| 157559cc05 | |||
| bba14bf51a | |||
| 9d1484d62d | |||
| 654dd9e64d | |||
| ea41989034 | |||
| 3f3f83a00a | |||
| adc5962071 | |||
| c4c00002d7 | |||
| a7c1e12db6 | |||
| 32949d1eec | |||
| 7718f77f3d | |||
| 7cde971f8b | |||
| 4e7441a5cf | |||
| b714833b06 | |||
| 88035ea490 | |||
| a9e54981bf | |||
| ef35293f8a | |||
| 5c63770b6b | |||
| 80847529fa | |||
| d130e20c92 | |||
| 586fb1ae10 | |||
| 20c2502e31 | |||
| 0e31f85c18 | |||
| e7301eb7a3 | |||
| 18507ddb6f | |||
| 7275f3dd47 | |||
| e31f947aba | |||
| 7ba120db31 | |||
| bc73ed8c9e | |||
| b1689dd2c6 | |||
| f6c59b7423 | |||
| 2cadcad485 | |||
| 04deade111 | |||
| ee0632f0d3 | |||
| f6771dafd3 | |||
| fadef0ea07 | |||
| c07e44520a | |||
| 6552c4edd6 | |||
| 5183a825e6 | |||
| 83a7c97e9e | |||
| eea3925fcd | |||
| 9a0de9f64f | |||
| a23644c9d8 | |||
| b884001e87 | |||
| bb54edc147 | |||
| 25c43ab4d2 | |||
| 388d00241b | |||
| 69d8c95557 | |||
| ea9748ca68 | |||
| 66a5501bd2 | |||
| c897521137 | |||
| adf4b3a74d | |||
| cc737593b7 | |||
| 9356c309a2 | |||
| 35da80103e | |||
| 99f553f1c3 | |||
| 3f4305c7cb | |||
| a678b4d272 | |||
| 0c83456866 | |||
| 2cb51b84c7 | |||
| 3908878109 | |||
| 6970a4f243 | |||
| 5720803116 | |||
| 351e6617d9 | |||
| ffa7906382 | |||
| 2a43ec9e9d | |||
| 48f9da14ba | |||
| 4153d10a0a | |||
| 1322ed15dc | |||
| a452ec5eaf | |||
| b819307612 | |||
| 7202fdcbf2 | |||
| c28fc073e4 | |||
| 439fc4e002 | |||
| ca15751a5f | |||
| 50637f5f7c | |||
| e3219baad2 | |||
| 8de8a07e3e | |||
| ab28ba38ce | |||
| 7a27317f1a | |||
| ab153963e4 | |||
| 65dd1eca01 | |||
| bed05fc21f | |||
| 0578122fc3 | |||
| ce3db7d0c6 | |||
| 854ae10198 | |||
| 2383e89daa | |||
| 6529fa1892 | |||
| eef74fd2fc | |||
| 2f69b6fa71 | |||
| 7170fb0cef | |||
| db7a084a19 | |||
| e24a89fe39 | |||
| 6a3e9e132f | |||
| 68575b69b9 | |||
| 8da5f99511 | |||
| 912dbdc1c5 | |||
| 771d396bfb | |||
| 30dc428b1a | |||
| 6f7555bdce | |||
| 13cbb5439f | |||
| a0cd12913d | |||
| 67e93dcb00 | |||
| 7427f8a4ac | |||
| 10ceaa0e2c | |||
| 15256a19db | |||
| 8ba84f68c7 | |||
| 9e23f9b9b1 | |||
| 7f4cdfffc6 | |||
| c9d6824f8c | |||
| 84f5890294 | |||
| ab8089fe98 | |||
| 383ba65d7c | |||
| f34dac9d3f | |||
| c3965613b5 | |||
| c07e309918 | |||
| 35e71ec110 | |||
| 82dbee4794 | |||
| d883e89819 | |||
| 00133d66c2 | |||
| e8a88dbad3 | |||
| 2b7028b7c8 | |||
| 513d43d92f | |||
| b781f11175 | |||
| ca1aa604e3 | |||
| e1e1157f2d | |||
| 3f2c774f91 | |||
| 9448677dad | |||
| 9709489c66 | |||
| 2fcc87180f | |||
| 0c77562d0e | |||
| 5f53138dc5 | |||
| 2019e9be03 | |||
| 938e6f2a9f | |||
| c82dc94252 | |||
| c6b36d78b9 | |||
| 1d402e0143 | |||
| 75a0ed1ffc | |||
| 577c015d14 | |||
| 760f4566aa | |||
| d7ec554eba | |||
| c194e98a7b | |||
| 6a34708a37 | |||
| ab863a8d88 | |||
| f594556de0 | |||
| 30f36461c2 | |||
| 980de6d492 | |||
| ff3cd0f7b9 | |||
| 323b7d8ea6 | |||
| dc7282d6e9 | |||
| 85836c3f9c | |||
| 221184df41 | |||
| f313a8c164 | |||
| 8f4fea3811 | |||
| dca97e80e7 | |||
| 9e6b4bd862 | |||
| 55beed430a | |||
| dd324c8bb6 | |||
| e3f3809f2d | |||
| d877b16776 | |||
| eac1bbb622 | |||
| 4ef5e7e54b | |||
| e2bb414efe | |||
| 941bc4bdb8 | |||
| a14655d73b | |||
| d303b1a71c | |||
| f677a54c2a | |||
| 37fa96b29a | |||
| 147be77859 | |||
| 6ef2553423 | |||
| 22f6a48b5b | |||
| 897d759758 | |||
| bcd80377cf | |||
| dcb3ddecb9 | |||
| 1197215ff6 | |||
| 4ca56de585 | |||
| b7c344132d | |||
| 9eae813c24 | |||
| 54f76f7cbe | |||
| bdea879273 | |||
| 6c5dcfe227 | |||
| f79becad07 | |||
| c150c4edeb | |||
| d2dee7d511 | |||
| fa9134610c | |||
| 02aabacd50 | |||
| a20c0a5ef9 | |||
| df33776873 | |||
| faf1ef0998 | |||
| 65404d5d6f | |||
| cdc913d16c | |||
| c9d0a63854 | |||
| 2fd8d8a5f4 | |||
| 2765f35f98 | |||
| 9652e3bdf5 | |||
| d69b7fd491 | |||
| f5c4f66165 | |||
| 848970fc08 | |||
| 37226fb35b | |||
| f59bae9518 | |||
| 72398f0ac9 | |||
| fbe25517e2 |
@ -36,3 +36,5 @@ SANCTUM_STATEFUL_DOMAINS=crater.test
|
||||
SESSION_DOMAIN=crater.test
|
||||
|
||||
TRUSTED_PROXIES="*"
|
||||
|
||||
CRON_JOB_AUTH_TOKEN=""
|
||||
|
||||
162
.github/workflows/uffizzi-build.yml
vendored
Normal file
162
.github/workflows/uffizzi-build.yml
vendored
Normal file
@ -0,0 +1,162 @@
|
||||
name: Build PR Image
|
||||
on:
|
||||
pull_request:
|
||||
types: [opened,synchronize,reopened,closed]
|
||||
|
||||
jobs:
|
||||
|
||||
build-application:
|
||||
name: Build and Push `application`
|
||||
runs-on: ubuntu-latest
|
||||
if: ${{ github.event_name != 'pull_request' || github.event.action != 'closed' }}
|
||||
outputs:
|
||||
tags: ${{ steps.meta.outputs.tags }}
|
||||
steps:
|
||||
- name: Checkout git repo
|
||||
uses: actions/checkout@v3
|
||||
- name: Set up Docker Buildx
|
||||
uses: docker/setup-buildx-action@v2
|
||||
- name: Generate UUID image name
|
||||
id: uuid
|
||||
run: echo "UUID_TAG_APP=$(uuidgen)" >> $GITHUB_ENV
|
||||
- name: Docker metadata
|
||||
id: meta
|
||||
uses: docker/metadata-action@v3
|
||||
with:
|
||||
images: registry.uffizzi.com/${{ env.UUID_TAG_APP }}
|
||||
tags: type=raw,value=60d
|
||||
- name: Build and Push Image to registry.uffizzi.com ephemeral registry
|
||||
uses: docker/build-push-action@v2
|
||||
with:
|
||||
push: true
|
||||
context: ./
|
||||
tags: ${{ steps.meta.outputs.tags }}
|
||||
labels: ${{ steps.meta.outputs.labels }}
|
||||
file: ./uffizzi/Dockerfile
|
||||
cache-from: type=gha
|
||||
cache-to: type=gha,mode=max
|
||||
|
||||
|
||||
build-nginx:
|
||||
name: Build and Push `nginx`
|
||||
runs-on: ubuntu-latest
|
||||
if: ${{ github.event_name != 'pull_request' || github.event.action != 'closed' }}
|
||||
outputs:
|
||||
tags: ${{ steps.meta.outputs.tags }}
|
||||
steps:
|
||||
- name: Checkout git repo
|
||||
uses: actions/checkout@v3
|
||||
- name: Set up Docker Buildx
|
||||
uses: docker/setup-buildx-action@v2
|
||||
- name: Generate UUID image name
|
||||
id: uuid
|
||||
run: echo "UUID_TAG_NGINX=$(uuidgen)" >> $GITHUB_ENV
|
||||
- name: Docker metadata
|
||||
id: meta
|
||||
uses: docker/metadata-action@v3
|
||||
with:
|
||||
images: registry.uffizzi.com/${{ env.UUID_TAG_NGINX }}
|
||||
tags: type=raw,value=60d
|
||||
- name: Build and Push Image to Uffizzi ephemeral registry
|
||||
uses: docker/build-push-action@v2
|
||||
with:
|
||||
push: true
|
||||
context: ./
|
||||
tags: ${{ steps.meta.outputs.tags }}
|
||||
labels: ${{ steps.meta.outputs.labels }}
|
||||
file: ./uffizzi/nginx/Dockerfile
|
||||
cache-from: type=gha
|
||||
cache-to: type=gha,mode=max
|
||||
|
||||
|
||||
build-crond:
|
||||
name: Build and Push `crond`
|
||||
runs-on: ubuntu-latest
|
||||
if: ${{ github.event_name != 'pull_request' || github.event.action != 'closed' }}
|
||||
outputs:
|
||||
tags: ${{ steps.meta.outputs.tags }}
|
||||
steps:
|
||||
- name: Checkout git repo
|
||||
uses: actions/checkout@v3
|
||||
- name: Set up Docker Buildx
|
||||
uses: docker/setup-buildx-action@v2
|
||||
- name: Generate UUID image name
|
||||
id: uuid
|
||||
run: echo "UUID_TAG_CROND=$(uuidgen)" >> $GITHUB_ENV
|
||||
- name: Docker metadata
|
||||
id: meta
|
||||
uses: docker/metadata-action@v3
|
||||
with:
|
||||
images: registry.uffizzi.com/${{ env.UUID_TAG_CROND }}
|
||||
tags: type=raw,value=60d
|
||||
- name: Build and Push Image to registry.uffizzi.com ephemeral registry
|
||||
uses: docker/build-push-action@v2
|
||||
with:
|
||||
push: true
|
||||
context: ./
|
||||
tags: ${{ steps.meta.outputs.tags }}
|
||||
labels: ${{ steps.meta.outputs.labels }}
|
||||
file: ./uffizzi/crond/Dockerfile
|
||||
cache-from: type=gha
|
||||
cache-to: type=gha,mode=max
|
||||
|
||||
|
||||
|
||||
render-compose-file:
|
||||
name: Render Docker Compose File
|
||||
# Pass output of this workflow to another triggered by `workflow_run` event.
|
||||
runs-on: ubuntu-latest
|
||||
outputs:
|
||||
compose-file-cache-key: ${{ steps.hash.outputs.hash }}
|
||||
needs:
|
||||
- build-application
|
||||
- build-nginx
|
||||
- build-crond
|
||||
steps:
|
||||
- name: Checkout git repo
|
||||
uses: actions/checkout@v3
|
||||
- name: Render Compose File
|
||||
run: |
|
||||
APP_IMAGE=$(echo ${{ needs.build-application.outputs.tags }})
|
||||
export APP_IMAGE
|
||||
NGINX_IMAGE=$(echo ${{ needs.build-nginx.outputs.tags }})
|
||||
export NGINX_IMAGE
|
||||
CROND_IMAGE=$(echo ${{ needs.build-crond.outputs.tags }})
|
||||
export CROND_IMAGE
|
||||
# Render simple template from environment variables.
|
||||
envsubst < ./uffizzi/docker-compose.uffizzi.yml > docker-compose.rendered.yml
|
||||
cat docker-compose.rendered.yml
|
||||
- name: Upload Rendered Compose File as Artifact
|
||||
uses: actions/upload-artifact@v3
|
||||
with:
|
||||
name: preview-spec
|
||||
path: docker-compose.rendered.yml
|
||||
retention-days: 2
|
||||
- name: Serialize PR Event to File
|
||||
run: |
|
||||
cat << EOF > event.json
|
||||
${{ toJSON(github.event) }}
|
||||
|
||||
EOF
|
||||
- name: Upload PR Event as Artifact
|
||||
uses: actions/upload-artifact@v3
|
||||
with:
|
||||
name: preview-spec
|
||||
path: event.json
|
||||
retention-days: 2
|
||||
|
||||
delete-preview:
|
||||
name: Call for Preview Deletion
|
||||
runs-on: ubuntu-latest
|
||||
if: ${{ github.event.action == 'closed' }}
|
||||
steps:
|
||||
# If this PR is closing, we will not render a compose file nor pass it to the next workflow.
|
||||
- name: Serialize PR Event to File
|
||||
run: echo '${{ toJSON(github.event) }}' > event.json
|
||||
- name: Upload PR Event as Artifact
|
||||
uses: actions/upload-artifact@v3
|
||||
with:
|
||||
name: preview-spec
|
||||
path: event.json
|
||||
retention-days: 2
|
||||
|
||||
84
.github/workflows/uffizzi-preview.yml
vendored
Normal file
84
.github/workflows/uffizzi-preview.yml
vendored
Normal file
@ -0,0 +1,84 @@
|
||||
name: Deploy Uffizzi Preview
|
||||
|
||||
on:
|
||||
workflow_run:
|
||||
workflows:
|
||||
- "Build PR Image"
|
||||
types:
|
||||
- completed
|
||||
|
||||
|
||||
jobs:
|
||||
cache-compose-file:
|
||||
name: Cache Compose File
|
||||
runs-on: ubuntu-latest
|
||||
outputs:
|
||||
compose-file-cache-key: ${{ env.COMPOSE_FILE_HASH }}
|
||||
pr-number: ${{ env.PR_NUMBER }}
|
||||
steps:
|
||||
- name: 'Download artifacts'
|
||||
# Fetch output (zip archive) from the workflow run that triggered this workflow.
|
||||
uses: actions/github-script@v6
|
||||
with:
|
||||
script: |
|
||||
let allArtifacts = await github.rest.actions.listWorkflowRunArtifacts({
|
||||
owner: context.repo.owner,
|
||||
repo: context.repo.repo,
|
||||
run_id: context.payload.workflow_run.id,
|
||||
});
|
||||
let matchArtifact = allArtifacts.data.artifacts.filter((artifact) => {
|
||||
return artifact.name == "preview-spec"
|
||||
})[0];
|
||||
let download = await github.rest.actions.downloadArtifact({
|
||||
owner: context.repo.owner,
|
||||
repo: context.repo.repo,
|
||||
artifact_id: matchArtifact.id,
|
||||
archive_format: 'zip',
|
||||
});
|
||||
let fs = require('fs');
|
||||
fs.writeFileSync(`${process.env.GITHUB_WORKSPACE}/preview-spec.zip`, Buffer.from(download.data));
|
||||
- name: 'Unzip artifact'
|
||||
run: unzip preview-spec.zip
|
||||
- name: Read Event into ENV
|
||||
run: |
|
||||
echo 'EVENT_JSON<<EOF' >> $GITHUB_ENV
|
||||
cat event.json >> $GITHUB_ENV
|
||||
echo 'EOF' >> $GITHUB_ENV
|
||||
- name: Hash Rendered Compose File
|
||||
id: hash
|
||||
# If the previous workflow was triggered by a PR close event, we will not have a compose file artifact.
|
||||
if: ${{ fromJSON(env.EVENT_JSON).action != 'closed' }}
|
||||
run: echo "COMPOSE_FILE_HASH=$(md5sum docker-compose.rendered.yml | awk '{ print $1 }')" >> $GITHUB_ENV
|
||||
- name: Cache Rendered Compose File
|
||||
if: ${{ fromJSON(env.EVENT_JSON).action != 'closed' }}
|
||||
uses: actions/cache@v3
|
||||
with:
|
||||
path: docker-compose.rendered.yml
|
||||
key: ${{ env.COMPOSE_FILE_HASH }}
|
||||
|
||||
- name: Read PR Number From Event Object
|
||||
id: pr
|
||||
run: echo "PR_NUMBER=${{ fromJSON(env.EVENT_JSON).number }}" >> $GITHUB_ENV
|
||||
|
||||
- name: DEBUG - Print Job Outputs
|
||||
if: ${{ runner.debug }}
|
||||
run: |
|
||||
echo "PR number: ${{ env.PR_NUMBER }}"
|
||||
echo "Compose file hash: ${{ env.COMPOSE_FILE_HASH }}"
|
||||
cat event.json
|
||||
deploy-uffizzi-preview:
|
||||
name: Use Remote Workflow to Preview on Uffizzi
|
||||
needs:
|
||||
- cache-compose-file
|
||||
uses: UffizziCloud/preview-action/.github/workflows/reusable.yaml@v2.6.1
|
||||
with:
|
||||
# If this workflow was triggered by a PR close event, cache-key will be an empty string
|
||||
# and this reusable workflow will delete the preview deployment.
|
||||
compose-file-cache-key: ${{ needs.cache-compose-file.outputs.compose-file-cache-key }}
|
||||
compose-file-cache-path: docker-compose.rendered.yml
|
||||
server: https://app.uffizzi.com/
|
||||
pr-number: ${{ needs.cache-compose-file.outputs.pr-number }}
|
||||
permissions:
|
||||
contents: read
|
||||
pull-requests: write
|
||||
id-token: write
|
||||
5
.gitignore
vendored
5
.gitignore
vendored
@ -1,3 +1,4 @@
|
||||
/Modules
|
||||
/node_modules
|
||||
/public/storage
|
||||
/public/hot
|
||||
@ -12,3 +13,7 @@ Homestead.yaml
|
||||
/.expo
|
||||
/.vscode
|
||||
/docker-compose/db/data/
|
||||
.gitkeep
|
||||
/public/docs
|
||||
/.scribe
|
||||
!storage/fonts/.gitkeep
|
||||
@ -1,4 +1,4 @@
|
||||
FROM php:7.4-fpm
|
||||
FROM php:8.1-fpm
|
||||
|
||||
# Arguments defined in docker-compose.yml
|
||||
ARG user
|
||||
|
||||
@ -40,10 +40,13 @@ class CheckInvoiceStatus extends Command
|
||||
public function handle()
|
||||
{
|
||||
$date = Carbon::now();
|
||||
$invoices = Invoice::where('status', '<>', Invoice::STATUS_COMPLETED)->whereDate('due_date', '<', $date)->get();
|
||||
$invoices = Invoice::whereNotIn('status', [Invoice::STATUS_COMPLETED, Invoice::STATUS_DRAFT])
|
||||
->where('overdue', false)
|
||||
->whereDate('due_date', '<', $date)
|
||||
->get();
|
||||
|
||||
foreach ($invoices as $invoice) {
|
||||
$invoice->status = Invoice::STATUS_OVERDUE;
|
||||
$invoice->overdue = true;
|
||||
printf("Invoice %s is OVERDUE \n", $invoice->invoice_number);
|
||||
$invoice->save();
|
||||
}
|
||||
|
||||
45
app/Console/Commands/InstallModuleCommand.php
Normal file
45
app/Console/Commands/InstallModuleCommand.php
Normal file
@ -0,0 +1,45 @@
|
||||
<?php
|
||||
|
||||
namespace Crater\Console\Commands;
|
||||
|
||||
use Crater\Space\ModuleInstaller;
|
||||
use Illuminate\Console\Command;
|
||||
|
||||
class InstallModuleCommand extends Command
|
||||
{
|
||||
/**
|
||||
* The name and signature of the console command.
|
||||
*
|
||||
* @var string
|
||||
*/
|
||||
protected $signature = 'install:module {module} {version}';
|
||||
|
||||
/**
|
||||
* The console command description.
|
||||
*
|
||||
* @var string
|
||||
*/
|
||||
protected $description = 'Install cloned module.';
|
||||
|
||||
/**
|
||||
* Create a new command instance.
|
||||
*
|
||||
* @return void
|
||||
*/
|
||||
public function __construct()
|
||||
{
|
||||
parent::__construct();
|
||||
}
|
||||
|
||||
/**
|
||||
* Execute the console command.
|
||||
*
|
||||
* @return int
|
||||
*/
|
||||
public function handle()
|
||||
{
|
||||
ModuleInstaller::complete($this->argument('module'), $this->argument('version'));
|
||||
|
||||
return Command::SUCCESS;
|
||||
}
|
||||
}
|
||||
@ -2,6 +2,7 @@
|
||||
|
||||
namespace Crater\Console;
|
||||
|
||||
use Crater\Models\CompanySetting;
|
||||
use Crater\Models\RecurringInvoice;
|
||||
use Illuminate\Console\Scheduling\Schedule;
|
||||
use Illuminate\Foundation\Console\Kernel as ConsoleKernel;
|
||||
@ -16,7 +17,8 @@ class Kernel extends ConsoleKernel
|
||||
protected $commands = [
|
||||
Commands\ResetApp::class,
|
||||
Commands\UpdateCommand::class,
|
||||
Commands\CreateTemplateCommand::class
|
||||
Commands\CreateTemplateCommand::class,
|
||||
Commands\InstallModuleCommand::class,
|
||||
];
|
||||
|
||||
/**
|
||||
@ -36,9 +38,11 @@ class Kernel extends ConsoleKernel
|
||||
|
||||
$recurringInvoices = RecurringInvoice::where('status', 'ACTIVE')->get();
|
||||
foreach ($recurringInvoices as $recurringInvoice) {
|
||||
$timeZone = CompanySetting::getSetting('time_zone', $recurringInvoice->company_id);
|
||||
|
||||
$schedule->call(function () use ($recurringInvoice) {
|
||||
$recurringInvoice->generateInvoice();
|
||||
})->cron($recurringInvoice->frequency);
|
||||
})->cron($recurringInvoice->frequency)->timezone($timeZone);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
26
app/Events/ModuleDisabledEvent.php
Normal file
26
app/Events/ModuleDisabledEvent.php
Normal file
@ -0,0 +1,26 @@
|
||||
<?php
|
||||
|
||||
namespace Crater\Events;
|
||||
|
||||
use Illuminate\Broadcasting\InteractsWithSockets;
|
||||
use Illuminate\Foundation\Events\Dispatchable;
|
||||
use Illuminate\Queue\SerializesModels;
|
||||
|
||||
class ModuleDisabledEvent
|
||||
{
|
||||
use Dispatchable;
|
||||
use InteractsWithSockets;
|
||||
use SerializesModels;
|
||||
|
||||
public $module;
|
||||
|
||||
/**
|
||||
* Create a new event instance.
|
||||
*
|
||||
* @return void
|
||||
*/
|
||||
public function __construct($module)
|
||||
{
|
||||
$this->module = $module;
|
||||
}
|
||||
}
|
||||
26
app/Events/ModuleEnabledEvent.php
Normal file
26
app/Events/ModuleEnabledEvent.php
Normal file
@ -0,0 +1,26 @@
|
||||
<?php
|
||||
|
||||
namespace Crater\Events;
|
||||
|
||||
use Illuminate\Broadcasting\InteractsWithSockets;
|
||||
use Illuminate\Foundation\Events\Dispatchable;
|
||||
use Illuminate\Queue\SerializesModels;
|
||||
|
||||
class ModuleEnabledEvent
|
||||
{
|
||||
use Dispatchable;
|
||||
use InteractsWithSockets;
|
||||
use SerializesModels;
|
||||
|
||||
public $module;
|
||||
|
||||
/**
|
||||
* Create a new event instance.
|
||||
*
|
||||
* @return void
|
||||
*/
|
||||
public function __construct($module)
|
||||
{
|
||||
$this->module = $module;
|
||||
}
|
||||
}
|
||||
26
app/Events/ModuleInstalledEvent.php
Normal file
26
app/Events/ModuleInstalledEvent.php
Normal file
@ -0,0 +1,26 @@
|
||||
<?php
|
||||
|
||||
namespace Crater\Events;
|
||||
|
||||
use Illuminate\Broadcasting\InteractsWithSockets;
|
||||
use Illuminate\Foundation\Events\Dispatchable;
|
||||
use Illuminate\Queue\SerializesModels;
|
||||
|
||||
class ModuleInstalledEvent
|
||||
{
|
||||
use Dispatchable;
|
||||
use InteractsWithSockets;
|
||||
use SerializesModels;
|
||||
|
||||
public $module;
|
||||
|
||||
/**
|
||||
* Create a new event instance.
|
||||
*
|
||||
* @return void
|
||||
*/
|
||||
public function __construct($module)
|
||||
{
|
||||
$this->module = $module;
|
||||
}
|
||||
}
|
||||
@ -103,6 +103,7 @@ class CustomerStatsController extends Controller
|
||||
)
|
||||
->whereCompany()
|
||||
->whereCustomer($customer->id)
|
||||
->where('status', '<>', Invoice::STATUS_DRAFT)
|
||||
->sum('total');
|
||||
$totalReceipts = Payment::whereBetween(
|
||||
'payment_date',
|
||||
|
||||
@ -12,6 +12,7 @@ use Crater\Models\Expense;
|
||||
use Crater\Models\Invoice;
|
||||
use Crater\Models\Payment;
|
||||
use Illuminate\Http\Request;
|
||||
use Silber\Bouncer\BouncerFacade;
|
||||
|
||||
class DashboardController extends Controller
|
||||
{
|
||||
@ -103,6 +104,7 @@ class DashboardController extends Controller
|
||||
'invoice_date',
|
||||
[$startDate->format('Y-m-d'), $start->format('Y-m-d')]
|
||||
)
|
||||
->where('status', '<>', Invoice::STATUS_DRAFT)
|
||||
->whereCompany()
|
||||
->sum('base_total');
|
||||
|
||||
@ -140,6 +142,7 @@ class DashboardController extends Controller
|
||||
$recent_due_invoices = Invoice::with('customer')
|
||||
->whereCompany()
|
||||
->where('base_due_amount', '>', 0)
|
||||
->where('status', '<>', Invoice::STATUS_DRAFT)
|
||||
->take(5)
|
||||
->latest()
|
||||
->get();
|
||||
@ -151,8 +154,8 @@ class DashboardController extends Controller
|
||||
'total_invoice_count' => $total_invoice_count,
|
||||
'total_estimate_count' => $total_estimate_count,
|
||||
|
||||
'recent_due_invoices' => $recent_due_invoices,
|
||||
'recent_estimates' => $recent_estimates,
|
||||
'recent_due_invoices' => BouncerFacade::can('view-invoice', Invoice::class) ? $recent_due_invoices : [],
|
||||
'recent_estimates' => BouncerFacade::can('view-estimate', Estimate::class) ? $recent_estimates : [],
|
||||
|
||||
'chart_data' => $chart_data,
|
||||
|
||||
|
||||
@ -83,6 +83,8 @@ class ConvertEstimateController extends Controller
|
||||
'base_total' => $estimate->total * $exchange_rate,
|
||||
'base_tax' => $estimate->tax * $exchange_rate,
|
||||
'currency_id' => $estimate->currency_id,
|
||||
'sales_tax_type' => $estimate->sales_tax_type,
|
||||
'sales_tax_address_type' => $estimate->sales_tax_address_type,
|
||||
]);
|
||||
|
||||
$invoice->unique_hash = Hashids::connection(Invoice::class)->encode($invoice->id);
|
||||
|
||||
@ -21,6 +21,9 @@ class SendEstimatePreviewController extends Controller
|
||||
|
||||
$markdown = new Markdown(view(), config('mail.markdown'));
|
||||
|
||||
return $markdown->render('emails.send.estimate', ['data' => $estimate->sendEstimateData($request->all())]);
|
||||
$data = $estimate->sendEstimateData($request->all());
|
||||
$data['url'] = $estimate->estimatePdfUrl;
|
||||
|
||||
return $markdown->render('emails.send.estimate', ['data' => $data]);
|
||||
}
|
||||
}
|
||||
|
||||
@ -39,7 +39,7 @@ class ExpensesController extends Controller
|
||||
/**
|
||||
* Store a newly created resource in storage.
|
||||
*
|
||||
* @param \Illuminate\Http\Request $request
|
||||
* @param \Crater\Http\Requests\ExpenseRequest $request
|
||||
* @return \Illuminate\Http\JsonResponse
|
||||
*/
|
||||
public function store(ExpenseRequest $request)
|
||||
@ -67,7 +67,7 @@ class ExpensesController extends Controller
|
||||
/**
|
||||
* Update the specified resource in storage.
|
||||
*
|
||||
* @param \Illuminate\Http\Request $request
|
||||
* @param \Crater\Http\Requests\ExpenseRequest $request
|
||||
* @param \Crater\Models\Expense $expense
|
||||
* @return \Illuminate\Http\JsonResponse
|
||||
*/
|
||||
|
||||
@ -3,19 +3,19 @@
|
||||
namespace Crater\Http\Controllers\V1\Admin\Expense;
|
||||
|
||||
use Crater\Http\Controllers\Controller;
|
||||
use Crater\Http\Requests\UploadExpenseReceiptRequest;
|
||||
use Crater\Models\Expense;
|
||||
use Illuminate\Http\Request;
|
||||
|
||||
class UploadReceiptController extends Controller
|
||||
{
|
||||
/**
|
||||
* Upload the expense receipts to storage.
|
||||
*
|
||||
* @param \Illuminate\Http\Request $request
|
||||
* @param \Crater\Http\Requests\ExpenseRequest $request
|
||||
* @param Expense $expense
|
||||
* @return \Illuminate\Http\JsonResponse
|
||||
*/
|
||||
public function __invoke(Request $request, Expense $expense)
|
||||
public function __invoke(UploadExpenseReceiptRequest $request, Expense $expense)
|
||||
{
|
||||
$this->authorize('update', $expense);
|
||||
|
||||
|
||||
@ -8,6 +8,8 @@ use Crater\Http\Resources\UserResource;
|
||||
use Crater\Models\Company;
|
||||
use Crater\Models\CompanySetting;
|
||||
use Crater\Models\Currency;
|
||||
use Crater\Models\Module;
|
||||
use Crater\Models\Setting;
|
||||
use Crater\Traits\GeneratesMenuTrait;
|
||||
use Illuminate\Http\Request;
|
||||
use Silber\Bouncer\BouncerFacade;
|
||||
@ -47,6 +49,17 @@ class BootstrapController extends Controller
|
||||
|
||||
BouncerFacade::refreshFor($current_user);
|
||||
|
||||
$global_settings = Setting::getSettings([
|
||||
'api_token',
|
||||
'admin_portal_theme',
|
||||
'admin_portal_logo',
|
||||
'login_page_logo',
|
||||
'login_page_heading',
|
||||
'login_page_description',
|
||||
'admin_page_title',
|
||||
'copyright_text'
|
||||
]);
|
||||
|
||||
return response()->json([
|
||||
'current_user' => new UserResource($current_user),
|
||||
'current_user_settings' => $current_user_settings,
|
||||
@ -56,8 +69,10 @@ class BootstrapController extends Controller
|
||||
'current_company_settings' => $current_company_settings,
|
||||
'current_company_currency' => $current_company_currency,
|
||||
'config' => config('crater'),
|
||||
'global_settings' => $global_settings,
|
||||
'main_menu' => $main_menu,
|
||||
'setting_menu' => $setting_menu,
|
||||
'modules' => Module::where('enabled', true)->pluck('name'),
|
||||
]);
|
||||
}
|
||||
}
|
||||
|
||||
@ -20,6 +20,7 @@ class SearchController extends Controller
|
||||
$user = $request->user();
|
||||
|
||||
$customers = Customer::applyFilters($request->only(['search']))
|
||||
->whereCompany()
|
||||
->latest()
|
||||
->paginate(10);
|
||||
|
||||
|
||||
@ -76,6 +76,8 @@ class CloneInvoiceController extends Controller
|
||||
'base_tax' => $invoice->tax * $exchange_rate,
|
||||
'base_due_amount' => $invoice->total * $exchange_rate,
|
||||
'currency_id' => $invoice->currency_id,
|
||||
'sales_tax_type' => $invoice->sales_tax_type,
|
||||
'sales_tax_address_type' => $invoice->sales_tax_address_type,
|
||||
]);
|
||||
|
||||
$newInvoice->unique_hash = Hashids::connection(Invoice::class)->encode($newInvoice->id);
|
||||
|
||||
@ -24,6 +24,7 @@ class InvoicesController extends Controller
|
||||
$limit = $request->has('limit') ? $request->limit : 10;
|
||||
|
||||
$invoices = Invoice::whereCompany()
|
||||
->whereTabFilters($request->tab_status)
|
||||
->join('customers', 'customers.id', '=', 'invoices.customer_id')
|
||||
->applyFilters($request->all())
|
||||
->select('invoices.*', 'customers.name')
|
||||
@ -102,7 +103,7 @@ class InvoicesController extends Controller
|
||||
{
|
||||
$this->authorize('delete multiple invoices');
|
||||
|
||||
Invoice::destroy($request->ids);
|
||||
Invoice::deleteInvoices($request->ids);
|
||||
|
||||
return response()->json([
|
||||
'success' => true,
|
||||
|
||||
@ -21,6 +21,9 @@ class SendInvoicePreviewController extends Controller
|
||||
|
||||
$markdown = new Markdown(view(), config('mail.markdown'));
|
||||
|
||||
return $markdown->render('emails.send.invoice', ['data' => $invoice->sendInvoiceData($request->all())]);
|
||||
$data = $invoice->sendInvoiceData($request->all());
|
||||
$data['url'] = $invoice->invoicePdfUrl;
|
||||
|
||||
return $markdown->render('emails.send.invoice', ['data' => $data]);
|
||||
}
|
||||
}
|
||||
|
||||
25
app/Http/Controllers/V1/Admin/Modules/ApiTokenController.php
Normal file
25
app/Http/Controllers/V1/Admin/Modules/ApiTokenController.php
Normal file
@ -0,0 +1,25 @@
|
||||
<?php
|
||||
|
||||
namespace Crater\Http\Controllers\V1\Admin\Modules;
|
||||
|
||||
use Crater\Http\Controllers\Controller;
|
||||
use Crater\Space\ModuleInstaller;
|
||||
use Illuminate\Http\Request;
|
||||
|
||||
class ApiTokenController extends Controller
|
||||
{
|
||||
/**
|
||||
* Handle the incoming request.
|
||||
*
|
||||
* @param \Illuminate\Http\Request $request
|
||||
* @return \Illuminate\Http\Response
|
||||
*/
|
||||
public function __invoke(Request $request)
|
||||
{
|
||||
$this->authorize('manage modules');
|
||||
|
||||
$response = ModuleInstaller::checkToken($request->api_token);
|
||||
|
||||
return $response;
|
||||
}
|
||||
}
|
||||
@ -0,0 +1,27 @@
|
||||
<?php
|
||||
|
||||
namespace Crater\Http\Controllers\V1\Admin\Modules;
|
||||
|
||||
use Crater\Http\Controllers\Controller;
|
||||
use Crater\Space\ModuleInstaller;
|
||||
use Illuminate\Http\Request;
|
||||
|
||||
class CompleteModuleInstallationController extends Controller
|
||||
{
|
||||
/**
|
||||
* Handle the incoming request.
|
||||
*
|
||||
* @param \Illuminate\Http\Request $request
|
||||
* @return \Illuminate\Http\Response
|
||||
*/
|
||||
public function __invoke(Request $request)
|
||||
{
|
||||
$this->authorize('manage modules');
|
||||
|
||||
$response = ModuleInstaller::complete($request->module, $request->version);
|
||||
|
||||
return response()->json([
|
||||
'success' => $response
|
||||
]);
|
||||
}
|
||||
}
|
||||
@ -0,0 +1,27 @@
|
||||
<?php
|
||||
|
||||
namespace Crater\Http\Controllers\V1\Admin\Modules;
|
||||
|
||||
use Crater\Http\Controllers\Controller;
|
||||
use Crater\Space\ModuleInstaller;
|
||||
use Illuminate\Http\Request;
|
||||
|
||||
class CopyModuleController extends Controller
|
||||
{
|
||||
/**
|
||||
* Handle the incoming request.
|
||||
*
|
||||
* @param \Illuminate\Http\Request $request
|
||||
* @return \Illuminate\Http\Response
|
||||
*/
|
||||
public function __invoke(Request $request)
|
||||
{
|
||||
$this->authorize('manage modules');
|
||||
|
||||
$response = ModuleInstaller::copyFiles($request->module, $request->path);
|
||||
|
||||
return response()->json([
|
||||
'success' => $response
|
||||
]);
|
||||
}
|
||||
}
|
||||
@ -0,0 +1,32 @@
|
||||
<?php
|
||||
|
||||
namespace Crater\Http\Controllers\V1\Admin\Modules;
|
||||
|
||||
use Crater\Events\ModuleDisabledEvent;
|
||||
use Crater\Http\Controllers\Controller;
|
||||
use Crater\Models\Module as ModelsModule;
|
||||
use Illuminate\Http\Request;
|
||||
use Nwidart\Modules\Facades\Module;
|
||||
|
||||
class DisableModuleController extends Controller
|
||||
{
|
||||
/**
|
||||
* Handle the incoming request.
|
||||
*
|
||||
* @param \Illuminate\Http\Request $request
|
||||
* @return \Illuminate\Http\Response
|
||||
*/
|
||||
public function __invoke(Request $request, string $module)
|
||||
{
|
||||
$this->authorize('manage modules');
|
||||
|
||||
$module = ModelsModule::where('name', $module)->first();
|
||||
$module->update(['enabled' => false]);
|
||||
$installedModule = Module::find($module->name);
|
||||
$installedModule->disable();
|
||||
|
||||
ModuleDisabledEvent::dispatch($module);
|
||||
|
||||
return response()->json(['success' => true]);
|
||||
}
|
||||
}
|
||||
@ -0,0 +1,25 @@
|
||||
<?php
|
||||
|
||||
namespace Crater\Http\Controllers\V1\Admin\Modules;
|
||||
|
||||
use Crater\Http\Controllers\Controller;
|
||||
use Crater\Space\ModuleInstaller;
|
||||
use Illuminate\Http\Request;
|
||||
|
||||
class DownloadModuleController extends Controller
|
||||
{
|
||||
/**
|
||||
* Handle the incoming request.
|
||||
*
|
||||
* @param \Illuminate\Http\Request $request
|
||||
* @return \Illuminate\Http\Response
|
||||
*/
|
||||
public function __invoke(Request $request)
|
||||
{
|
||||
$this->authorize('manage modules');
|
||||
|
||||
$response = ModuleInstaller::download($request->module, $request->version);
|
||||
|
||||
return response()->json($response);
|
||||
}
|
||||
}
|
||||
@ -0,0 +1,32 @@
|
||||
<?php
|
||||
|
||||
namespace Crater\Http\Controllers\V1\Admin\Modules;
|
||||
|
||||
use Crater\Events\ModuleEnabledEvent;
|
||||
use Crater\Http\Controllers\Controller;
|
||||
use Crater\Models\Module as ModelsModule;
|
||||
use Illuminate\Http\Request;
|
||||
use Nwidart\Modules\Facades\Module;
|
||||
|
||||
class EnableModuleController extends Controller
|
||||
{
|
||||
/**
|
||||
* Handle the incoming request.
|
||||
*
|
||||
* @param \Illuminate\Http\Request $request
|
||||
* @return \Illuminate\Http\Response
|
||||
*/
|
||||
public function __invoke(Request $request, string $module)
|
||||
{
|
||||
$this->authorize('manage modules');
|
||||
|
||||
$module = ModelsModule::where('name', $module)->first();
|
||||
$module->update(['enabled' => true]);
|
||||
$installedModule = Module::find($module->name);
|
||||
$installedModule->enable();
|
||||
|
||||
ModuleEnabledEvent::dispatch($module);
|
||||
|
||||
return response()->json(['success' => true]);
|
||||
}
|
||||
}
|
||||
33
app/Http/Controllers/V1/Admin/Modules/ModuleController.php
Normal file
33
app/Http/Controllers/V1/Admin/Modules/ModuleController.php
Normal file
@ -0,0 +1,33 @@
|
||||
<?php
|
||||
|
||||
namespace Crater\Http\Controllers\V1\Admin\Modules;
|
||||
|
||||
use Crater\Http\Controllers\Controller;
|
||||
use Crater\Http\Resources\ModuleResource;
|
||||
use Crater\Space\ModuleInstaller;
|
||||
use Illuminate\Http\Request;
|
||||
|
||||
class ModuleController extends Controller
|
||||
{
|
||||
/**
|
||||
* Handle the incoming request.
|
||||
*
|
||||
* @param \Illuminate\Http\Request $request
|
||||
* @return \Illuminate\Http\Response
|
||||
*/
|
||||
public function __invoke(Request $request, string $module)
|
||||
{
|
||||
$this->authorize('manage modules');
|
||||
|
||||
$response = ModuleInstaller::getModule($module);
|
||||
|
||||
if (! $response->success) {
|
||||
return response()->json($response);
|
||||
}
|
||||
|
||||
return (new ModuleResource($response->module))
|
||||
->additional(['meta' => [
|
||||
'modules' => ModuleResource::collection(collect($response->modules))
|
||||
]]);
|
||||
}
|
||||
}
|
||||
25
app/Http/Controllers/V1/Admin/Modules/ModulesController.php
Normal file
25
app/Http/Controllers/V1/Admin/Modules/ModulesController.php
Normal file
@ -0,0 +1,25 @@
|
||||
<?php
|
||||
|
||||
namespace Crater\Http\Controllers\V1\Admin\Modules;
|
||||
|
||||
use Crater\Http\Controllers\Controller;
|
||||
use Crater\Space\ModuleInstaller;
|
||||
use Illuminate\Http\Request;
|
||||
|
||||
class ModulesController extends Controller
|
||||
{
|
||||
/**
|
||||
* Handle the incoming request.
|
||||
*
|
||||
* @param \Illuminate\Http\Request $request
|
||||
* @return \Illuminate\Http\Response
|
||||
*/
|
||||
public function __invoke(Request $request)
|
||||
{
|
||||
$this->authorize('manage modules');
|
||||
|
||||
$response = ModuleInstaller::getModules();
|
||||
|
||||
return $response;
|
||||
}
|
||||
}
|
||||
@ -0,0 +1,28 @@
|
||||
<?php
|
||||
|
||||
namespace Crater\Http\Controllers\V1\Admin\Modules;
|
||||
|
||||
use Crater\Http\Controllers\Controller;
|
||||
use Crater\Http\Requests\UnzipUpdateRequest;
|
||||
use Crater\Space\ModuleInstaller;
|
||||
|
||||
class UnzipModuleController extends Controller
|
||||
{
|
||||
/**
|
||||
* Handle the incoming request.
|
||||
*
|
||||
* @param \Crater\Http\Requests\UnzipUpdateRequest $request
|
||||
* @return \Illuminate\Http\Response
|
||||
*/
|
||||
public function __invoke(UnzipUpdateRequest $request)
|
||||
{
|
||||
$this->authorize('manage modules');
|
||||
|
||||
$path = ModuleInstaller::unzip($request->module, $request->path);
|
||||
|
||||
return response()->json([
|
||||
'success' => true,
|
||||
'path' => $path
|
||||
]);
|
||||
}
|
||||
}
|
||||
@ -0,0 +1,25 @@
|
||||
<?php
|
||||
|
||||
namespace Crater\Http\Controllers\V1\Admin\Modules;
|
||||
|
||||
use Crater\Http\Controllers\Controller;
|
||||
use Crater\Http\Requests\UploadModuleRequest;
|
||||
use Crater\Space\ModuleInstaller;
|
||||
|
||||
class UploadModuleController extends Controller
|
||||
{
|
||||
/**
|
||||
* Handle the incoming request.
|
||||
*
|
||||
* @param \Crater\Http\Requests\UploadModuleRequest $request
|
||||
* @return \Illuminate\Http\Response
|
||||
*/
|
||||
public function __invoke(UploadModuleRequest $request)
|
||||
{
|
||||
$this->authorize('manage modules');
|
||||
|
||||
$response = ModuleInstaller::upload($request);
|
||||
|
||||
return response()->json($response);
|
||||
}
|
||||
}
|
||||
@ -22,6 +22,7 @@ class PaymentMethodsController extends Controller
|
||||
$limit = $request->has('limit') ? $request->limit : 5;
|
||||
|
||||
$paymentMethods = PaymentMethod::applyFilters($request->all())
|
||||
->where('type', PaymentMethod::TYPE_GENERAL)
|
||||
->whereCompany()
|
||||
->latest()
|
||||
->paginateData($limit);
|
||||
@ -68,7 +69,7 @@ class PaymentMethodsController extends Controller
|
||||
{
|
||||
$this->authorize('update', $paymentMethod);
|
||||
|
||||
$paymentMethod->update($request->validated());
|
||||
$paymentMethod->update($request->getPaymentMethodPayload());
|
||||
|
||||
return new PaymentMethodResource($paymentMethod);
|
||||
}
|
||||
@ -83,12 +84,14 @@ class PaymentMethodsController extends Controller
|
||||
{
|
||||
$this->authorize('delete', $paymentMethod);
|
||||
|
||||
$payments = $paymentMethod->payments;
|
||||
|
||||
if ($payments->count() > 0) {
|
||||
if ($paymentMethod->payments()->exists()) {
|
||||
return respondJson('payments_attached', 'Payments Attached.');
|
||||
}
|
||||
|
||||
if ($paymentMethod->expenses()->exists()) {
|
||||
return respondJson('expenses_attached', 'Expenses Attached.');
|
||||
}
|
||||
|
||||
$paymentMethod->delete();
|
||||
|
||||
return response()->json([
|
||||
|
||||
@ -21,6 +21,9 @@ class SendPaymentPreviewController extends Controller
|
||||
|
||||
$markdown = new Markdown(view(), config('mail.markdown'));
|
||||
|
||||
return $markdown->render('emails.send.payment', ['data' => $payment->sendPaymentData($request->all())]);
|
||||
$data = $payment->sendPaymentData($request->all());
|
||||
$data['url'] = $payment->paymentPdfUrl;
|
||||
|
||||
return $markdown->render('emails.send.payment', ['data' => $data]);
|
||||
}
|
||||
}
|
||||
|
||||
@ -2,24 +2,25 @@
|
||||
|
||||
namespace Crater\Http\Controllers\V1\Admin\Report;
|
||||
|
||||
use PDF;
|
||||
use Carbon\Carbon;
|
||||
use Crater\Http\Controllers\Controller;
|
||||
use Crater\Models\Company;
|
||||
use Crater\Models\CompanySetting;
|
||||
use Crater\Models\Currency;
|
||||
use Crater\Models\Customer;
|
||||
use Illuminate\Http\Request;
|
||||
use Crater\Models\CompanySetting;
|
||||
use Illuminate\Support\Facades\App;
|
||||
use PDF;
|
||||
use Crater\Http\Controllers\Controller;
|
||||
|
||||
class CustomerSalesReportController extends Controller
|
||||
{
|
||||
/**
|
||||
* Handle the incoming request.
|
||||
*
|
||||
* @param \Illuminate\Http\Request $request
|
||||
* @param string $hash
|
||||
* @return \Illuminate\Http\JsonResponse
|
||||
*/
|
||||
* Handle the incoming request.
|
||||
*
|
||||
* @param \Illuminate\Http\Request $request
|
||||
* @param string $hash
|
||||
* @return \Illuminate\Http\JsonResponse
|
||||
*/
|
||||
public function __invoke(Request $request, $hash)
|
||||
{
|
||||
$company = Company::where('unique_hash', $hash)->first();
|
||||
@ -56,6 +57,7 @@ class CustomerSalesReportController extends Controller
|
||||
$dateFormat = CompanySetting::getSetting('carbon_date_format', $company->id);
|
||||
$from_date = Carbon::createFromFormat('Y-m-d', $request->from_date)->format($dateFormat);
|
||||
$to_date = Carbon::createFromFormat('Y-m-d', $request->to_date)->format($dateFormat);
|
||||
$currency = Currency::findOrFail(CompanySetting::getSetting('currency', $company->id));
|
||||
|
||||
$colors = [
|
||||
'primary_text_color',
|
||||
@ -80,6 +82,7 @@ class CustomerSalesReportController extends Controller
|
||||
'company' => $company,
|
||||
'from_date' => $from_date,
|
||||
'to_date' => $to_date,
|
||||
'currency' => $currency,
|
||||
]);
|
||||
|
||||
$pdf = PDF::loadView('app.pdf.reports.sales-customers');
|
||||
|
||||
@ -2,24 +2,25 @@
|
||||
|
||||
namespace Crater\Http\Controllers\V1\Admin\Report;
|
||||
|
||||
use Carbon\Carbon;
|
||||
use Crater\Http\Controllers\Controller;
|
||||
use Crater\Models\Company;
|
||||
use Crater\Models\CompanySetting;
|
||||
use Crater\Models\Expense;
|
||||
use Illuminate\Http\Request;
|
||||
use Illuminate\Support\Facades\App;
|
||||
use PDF;
|
||||
use Carbon\Carbon;
|
||||
use Crater\Models\Company;
|
||||
use Crater\Models\Expense;
|
||||
use Crater\Models\Currency;
|
||||
use Illuminate\Http\Request;
|
||||
use Crater\Models\CompanySetting;
|
||||
use Illuminate\Support\Facades\App;
|
||||
use Crater\Http\Controllers\Controller;
|
||||
|
||||
class ExpensesReportController extends Controller
|
||||
{
|
||||
/**
|
||||
* Handle the incoming request.
|
||||
*
|
||||
* @param \Illuminate\Http\Request $request
|
||||
* @param string $hash
|
||||
* @return \Illuminate\Http\JsonResponse
|
||||
*/
|
||||
* Handle the incoming request.
|
||||
*
|
||||
* @param \Illuminate\Http\Request $request
|
||||
* @param string $hash
|
||||
* @return \Illuminate\Http\JsonResponse
|
||||
*/
|
||||
public function __invoke(Request $request, $hash)
|
||||
{
|
||||
$company = Company::where('unique_hash', $hash)->first();
|
||||
@ -43,6 +44,7 @@ class ExpensesReportController extends Controller
|
||||
$dateFormat = CompanySetting::getSetting('carbon_date_format', $company->id);
|
||||
$from_date = Carbon::createFromFormat('Y-m-d', $request->from_date)->format($dateFormat);
|
||||
$to_date = Carbon::createFromFormat('Y-m-d', $request->to_date)->format($dateFormat);
|
||||
$currency = Currency::findOrFail(CompanySetting::getSetting('currency', $company->id));
|
||||
|
||||
$colors = [
|
||||
'primary_text_color',
|
||||
@ -66,6 +68,7 @@ class ExpensesReportController extends Controller
|
||||
'company' => $company,
|
||||
'from_date' => $from_date,
|
||||
'to_date' => $to_date,
|
||||
'currency' => $currency,
|
||||
]);
|
||||
$pdf = PDF::loadView('app.pdf.reports.expenses');
|
||||
|
||||
|
||||
@ -2,24 +2,25 @@
|
||||
|
||||
namespace Crater\Http\Controllers\V1\Admin\Report;
|
||||
|
||||
use Carbon\Carbon;
|
||||
use Crater\Http\Controllers\Controller;
|
||||
use Crater\Models\Company;
|
||||
use Crater\Models\CompanySetting;
|
||||
use Crater\Models\InvoiceItem;
|
||||
use Illuminate\Http\Request;
|
||||
use Illuminate\Support\Facades\App;
|
||||
use PDF;
|
||||
use Carbon\Carbon;
|
||||
use Crater\Models\Company;
|
||||
use Crater\Models\Currency;
|
||||
use Illuminate\Http\Request;
|
||||
use Crater\Models\InvoiceItem;
|
||||
use Crater\Models\CompanySetting;
|
||||
use Illuminate\Support\Facades\App;
|
||||
use Crater\Http\Controllers\Controller;
|
||||
|
||||
class ItemSalesReportController extends Controller
|
||||
{
|
||||
/**
|
||||
* Handle the incoming request.
|
||||
*
|
||||
* @param \Illuminate\Http\Request $request
|
||||
* @param string $hash
|
||||
* @return \Illuminate\Http\JsonResponse
|
||||
*/
|
||||
* Handle the incoming request.
|
||||
*
|
||||
* @param \Illuminate\Http\Request $request
|
||||
* @param string $hash
|
||||
* @return \Illuminate\Http\JsonResponse
|
||||
*/
|
||||
public function __invoke(Request $request, $hash)
|
||||
{
|
||||
$company = Company::where('unique_hash', $hash)->first();
|
||||
@ -43,6 +44,7 @@ class ItemSalesReportController extends Controller
|
||||
$dateFormat = CompanySetting::getSetting('carbon_date_format', $company->id);
|
||||
$from_date = Carbon::createFromFormat('Y-m-d', $request->from_date)->format($dateFormat);
|
||||
$to_date = Carbon::createFromFormat('Y-m-d', $request->to_date)->format($dateFormat);
|
||||
$currency = Currency::findOrFail(CompanySetting::getSetting('currency', $company->id));
|
||||
|
||||
$colors = [
|
||||
'primary_text_color',
|
||||
@ -66,6 +68,7 @@ class ItemSalesReportController extends Controller
|
||||
'company' => $company,
|
||||
'from_date' => $from_date,
|
||||
'to_date' => $to_date,
|
||||
'currency' => $currency,
|
||||
]);
|
||||
$pdf = PDF::loadView('app.pdf.reports.sales-items');
|
||||
|
||||
|
||||
@ -2,25 +2,26 @@
|
||||
|
||||
namespace Crater\Http\Controllers\V1\Admin\Report;
|
||||
|
||||
use PDF;
|
||||
use Carbon\Carbon;
|
||||
use Crater\Http\Controllers\Controller;
|
||||
use Crater\Models\Company;
|
||||
use Crater\Models\CompanySetting;
|
||||
use Crater\Models\Expense;
|
||||
use Crater\Models\Payment;
|
||||
use Crater\Models\Currency;
|
||||
use Illuminate\Http\Request;
|
||||
use Crater\Models\CompanySetting;
|
||||
use Illuminate\Support\Facades\App;
|
||||
use PDF;
|
||||
use Crater\Http\Controllers\Controller;
|
||||
|
||||
class ProfitLossReportController extends Controller
|
||||
{
|
||||
/**
|
||||
* Handle the incoming request.
|
||||
*
|
||||
* @param \Illuminate\Http\Request $request
|
||||
* @param string $hash
|
||||
* @return \Illuminate\Http\JsonResponse
|
||||
*/
|
||||
* Handle the incoming request.
|
||||
*
|
||||
* @param \Illuminate\Http\Request $request
|
||||
* @param string $hash
|
||||
* @return \Illuminate\Http\JsonResponse
|
||||
*/
|
||||
public function __invoke(Request $request, $hash)
|
||||
{
|
||||
$company = Company::where('unique_hash', $hash)->first();
|
||||
@ -49,6 +50,8 @@ class ProfitLossReportController extends Controller
|
||||
$dateFormat = CompanySetting::getSetting('carbon_date_format', $company->id);
|
||||
$from_date = Carbon::createFromFormat('Y-m-d', $request->from_date)->format($dateFormat);
|
||||
$to_date = Carbon::createFromFormat('Y-m-d', $request->to_date)->format($dateFormat);
|
||||
$currency = Currency::findOrFail(CompanySetting::getSetting('currency', $company->id));
|
||||
|
||||
|
||||
$colors = [
|
||||
'primary_text_color',
|
||||
@ -74,6 +77,7 @@ class ProfitLossReportController extends Controller
|
||||
'company' => $company,
|
||||
'from_date' => $from_date,
|
||||
'to_date' => $to_date,
|
||||
'currency' => $currency,
|
||||
]);
|
||||
$pdf = PDF::loadView('app.pdf.reports.profit-loss');
|
||||
|
||||
|
||||
@ -2,24 +2,25 @@
|
||||
|
||||
namespace Crater\Http\Controllers\V1\Admin\Report;
|
||||
|
||||
use Carbon\Carbon;
|
||||
use Crater\Http\Controllers\Controller;
|
||||
use Crater\Models\Company;
|
||||
use Crater\Models\CompanySetting;
|
||||
use Crater\Models\Tax;
|
||||
use Illuminate\Http\Request;
|
||||
use Illuminate\Support\Facades\App;
|
||||
use PDF;
|
||||
use Carbon\Carbon;
|
||||
use Crater\Models\Tax;
|
||||
use Crater\Models\Company;
|
||||
use Crater\Models\Currency;
|
||||
use Illuminate\Http\Request;
|
||||
use Crater\Models\CompanySetting;
|
||||
use Illuminate\Support\Facades\App;
|
||||
use Crater\Http\Controllers\Controller;
|
||||
|
||||
class TaxSummaryReportController extends Controller
|
||||
{
|
||||
/**
|
||||
* Handle the incoming request.
|
||||
*
|
||||
* @param \Illuminate\Http\Request $request
|
||||
* @param string $hash
|
||||
* @return \Illuminate\Http\JsonResponse
|
||||
*/
|
||||
* Handle the incoming request.
|
||||
*
|
||||
* @param \Illuminate\Http\Request $request
|
||||
* @param string $hash
|
||||
* @return \Illuminate\Http\JsonResponse
|
||||
*/
|
||||
public function __invoke(Request $request, $hash)
|
||||
{
|
||||
$company = Company::where('unique_hash', $hash)->first();
|
||||
@ -44,6 +45,8 @@ class TaxSummaryReportController extends Controller
|
||||
$dateFormat = CompanySetting::getSetting('carbon_date_format', $company->id);
|
||||
$from_date = Carbon::createFromFormat('Y-m-d', $request->from_date)->format($dateFormat);
|
||||
$to_date = Carbon::createFromFormat('Y-m-d', $request->to_date)->format($dateFormat);
|
||||
$currency = Currency::findOrFail(CompanySetting::getSetting('currency', $company->id));
|
||||
|
||||
|
||||
$colors = [
|
||||
'primary_text_color',
|
||||
@ -68,6 +71,7 @@ class TaxSummaryReportController extends Controller
|
||||
'company' => $company,
|
||||
'from_date' => $from_date,
|
||||
'to_date' => $to_date,
|
||||
'currency' => $currency,
|
||||
]);
|
||||
|
||||
$pdf = PDF::loadView('app.pdf.reports.tax-summary');
|
||||
|
||||
@ -3,6 +3,8 @@
|
||||
namespace Crater\Http\Controllers\V1\Admin\Settings;
|
||||
|
||||
use Crater\Http\Controllers\Controller;
|
||||
use Crater\Http\Requests\AvatarRequest;
|
||||
use Crater\Http\Requests\CompanyLogoRequest;
|
||||
use Crater\Http\Requests\CompanyRequest;
|
||||
use Crater\Http\Requests\ProfileRequest;
|
||||
use Crater\Http\Resources\CompanyResource;
|
||||
@ -48,7 +50,7 @@ class CompanyController extends Controller
|
||||
|
||||
$this->authorize('manage company', $company);
|
||||
|
||||
$company->update($request->only('name'));
|
||||
$company->update($request->getCompanyPayload());
|
||||
|
||||
$company->address()->updateOrCreate(['company_id' => $company->id], $request->address);
|
||||
|
||||
@ -58,10 +60,10 @@ class CompanyController extends Controller
|
||||
/**
|
||||
* Upload the company logo to storage.
|
||||
*
|
||||
* @param \Illuminate\Http\Request $request
|
||||
* @param \Crater\Http\Requests\CompanyLogoRequest $request
|
||||
* @return \Illuminate\Http\JsonResponse
|
||||
*/
|
||||
public function uploadCompanyLogo(Request $request)
|
||||
public function uploadCompanyLogo(CompanyLogoRequest $request)
|
||||
{
|
||||
$company = Company::find($request->header('company'));
|
||||
|
||||
@ -69,6 +71,9 @@ class CompanyController extends Controller
|
||||
|
||||
$data = json_decode($request->company_logo);
|
||||
|
||||
if (isset($request->is_company_logo_removed) && (bool) $request->is_company_logo_removed) {
|
||||
$company->clearMediaCollection('logo');
|
||||
}
|
||||
if ($data) {
|
||||
$company = Company::find($request->header('company'));
|
||||
|
||||
@ -89,13 +94,16 @@ class CompanyController extends Controller
|
||||
/**
|
||||
* Upload the Admin Avatar to public storage.
|
||||
*
|
||||
* @param \Illuminate\Http\Request $request
|
||||
* @param \Crater\Http\Requests\AvatarRequest $request
|
||||
* @return \Illuminate\Http\JsonResponse
|
||||
*/
|
||||
public function uploadAvatar(Request $request)
|
||||
public function uploadAvatar(AvatarRequest $request)
|
||||
{
|
||||
$user = auth()->user();
|
||||
|
||||
if (isset($request->is_admin_avatar_removed) && (bool) $request->is_admin_avatar_removed) {
|
||||
$user->clearMediaCollection('admin_avatar');
|
||||
}
|
||||
if ($user && $request->hasFile('admin_avatar')) {
|
||||
$user->clearMediaCollection('admin_avatar');
|
||||
|
||||
|
||||
@ -0,0 +1,27 @@
|
||||
<?php
|
||||
|
||||
namespace Crater\Http\Controllers\V1\Admin\Settings;
|
||||
|
||||
use Crater\Http\Controllers\Controller;
|
||||
use Crater\Models\Company;
|
||||
use Illuminate\Http\Request;
|
||||
|
||||
class CompanyCurrencyCheckTransactionsController extends Controller
|
||||
{
|
||||
/**
|
||||
* Handle the incoming request.
|
||||
*
|
||||
* @param \Illuminate\Http\Request $request
|
||||
* @return \Illuminate\Http\Response
|
||||
*/
|
||||
public function __invoke(Request $request)
|
||||
{
|
||||
$company = Company::find($request->header('company'));
|
||||
|
||||
$this->authorize('manage company', $company);
|
||||
|
||||
return response()->json([
|
||||
'has_transactions' => $company->hasTransactions(),
|
||||
]);
|
||||
}
|
||||
}
|
||||
@ -0,0 +1,28 @@
|
||||
<?php
|
||||
|
||||
namespace Crater\Http\Controllers\V1\Admin\Settings;
|
||||
|
||||
use Crater\Http\Controllers\Controller;
|
||||
use Crater\Http\Requests\GetSettingRequest;
|
||||
use Crater\Models\Setting;
|
||||
use Illuminate\Http\Request;
|
||||
|
||||
class GetSettingsController extends Controller
|
||||
{
|
||||
/**
|
||||
* Handle the incoming request.
|
||||
*
|
||||
* @param \Illuminate\Http\Request $request
|
||||
* @return \Illuminate\Http\Response
|
||||
*/
|
||||
public function __invoke(GetSettingRequest $request)
|
||||
{
|
||||
$this->authorize('manage settings');
|
||||
|
||||
$setting = Setting::getSetting($request->key);
|
||||
|
||||
return response()->json([
|
||||
$request->key => $setting
|
||||
]);
|
||||
}
|
||||
}
|
||||
@ -22,6 +22,7 @@ class TaxTypesController extends Controller
|
||||
$limit = $request->has('limit') ? $request->limit : 5;
|
||||
|
||||
$taxTypes = TaxType::applyFilters($request->all())
|
||||
->where('type', TaxType::TYPE_GENERAL)
|
||||
->whereCompany()
|
||||
->latest()
|
||||
->paginateData($limit);
|
||||
|
||||
@ -6,6 +6,7 @@ use Crater\Http\Controllers\Controller;
|
||||
use Crater\Http\Requests\UpdateSettingsRequest;
|
||||
use Crater\Models\Company;
|
||||
use Crater\Models\CompanySetting;
|
||||
use Illuminate\Support\Arr;
|
||||
|
||||
class UpdateCompanySettingsController extends Controller
|
||||
{
|
||||
@ -17,9 +18,23 @@ class UpdateCompanySettingsController extends Controller
|
||||
*/
|
||||
public function __invoke(UpdateSettingsRequest $request)
|
||||
{
|
||||
$this->authorize('manage company', Company::find($request->header('company')));
|
||||
$company = Company::find($request->header('company'));
|
||||
$this->authorize('manage company', $company);
|
||||
|
||||
CompanySetting::setSettings($request->settings, $request->header('company'));
|
||||
$data = $request->settings;
|
||||
|
||||
if (
|
||||
Arr::exists($data, 'currency') &&
|
||||
(CompanySetting::getSetting('currency', $company->id) !== $data['currency']) &&
|
||||
$company->hasTransactions()
|
||||
) {
|
||||
return response()->json([
|
||||
'success' => false,
|
||||
'message' => 'Cannot update company currency after transactions are created.'
|
||||
]);
|
||||
}
|
||||
|
||||
CompanySetting::setSettings($data, $request->header('company'));
|
||||
|
||||
return response()->json([
|
||||
'success' => true,
|
||||
|
||||
@ -0,0 +1,29 @@
|
||||
<?php
|
||||
|
||||
namespace Crater\Http\Controllers\V1\Admin\Settings;
|
||||
|
||||
use Crater\Http\Controllers\Controller;
|
||||
use Crater\Http\Requests\SettingRequest;
|
||||
use Crater\Models\Setting;
|
||||
use Illuminate\Http\Request;
|
||||
|
||||
class UpdateSettingsController extends Controller
|
||||
{
|
||||
/**
|
||||
* Handle the incoming request.
|
||||
*
|
||||
* @param \Illuminate\Http\Request $request
|
||||
* @return \Illuminate\Http\Response
|
||||
*/
|
||||
public function __invoke(SettingRequest $request)
|
||||
{
|
||||
$this->authorize('manage settings');
|
||||
|
||||
Setting::setSettings($request->settings);
|
||||
|
||||
return response()->json([
|
||||
'success' => true,
|
||||
$request->settings
|
||||
]);
|
||||
}
|
||||
}
|
||||
@ -0,0 +1,56 @@
|
||||
<?php
|
||||
|
||||
namespace Crater\Http\Controllers\V1\Customer\Auth;
|
||||
|
||||
use Crater\Http\Controllers\Controller;
|
||||
use Illuminate\Foundation\Auth\SendsPasswordResetEmails;
|
||||
use Illuminate\Http\Request;
|
||||
use Password;
|
||||
|
||||
class ForgotPasswordController extends Controller
|
||||
{
|
||||
/*
|
||||
|--------------------------------------------------------------------------
|
||||
| Password Reset Controller
|
||||
|--------------------------------------------------------------------------
|
||||
|
|
||||
| This controller is responsible for handling password reset emails and
|
||||
| includes a trait which assists in sending these notifications from
|
||||
| your application to your users. Feel free to explore this trait.
|
||||
|
|
||||
*/
|
||||
|
||||
use SendsPasswordResetEmails;
|
||||
|
||||
public function broker()
|
||||
{
|
||||
return Password::broker('customers');
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the response for a successful password reset link.
|
||||
*
|
||||
* @param \Illuminate\Http\Request $request
|
||||
* @param string $response
|
||||
* @return \Illuminate\Http\RedirectResponse|\Illuminate\Http\JsonResponse
|
||||
*/
|
||||
protected function sendResetLinkResponse(Request $request, $response)
|
||||
{
|
||||
return response()->json([
|
||||
'message' => 'Password reset email sent.',
|
||||
'data' => $response,
|
||||
]);
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the response for a failed password reset link.
|
||||
*
|
||||
* @param \Illuminate\Http\Request $request
|
||||
* @param string $response
|
||||
* @return \Illuminate\Http\RedirectResponse|\Illuminate\Http\JsonResponse
|
||||
*/
|
||||
protected function sendResetLinkFailedResponse(Request $request, $response)
|
||||
{
|
||||
return response('Email could not be sent to this email address.', 403);
|
||||
}
|
||||
}
|
||||
45
app/Http/Controllers/V1/Customer/Auth/LoginController.php
Normal file
45
app/Http/Controllers/V1/Customer/Auth/LoginController.php
Normal file
@ -0,0 +1,45 @@
|
||||
<?php
|
||||
|
||||
namespace Crater\Http\Controllers\V1\Customer\Auth;
|
||||
|
||||
use Crater\Http\Controllers\Controller;
|
||||
use Crater\Http\Requests\Customer\CustomerLoginRequest;
|
||||
use Crater\Models\Company;
|
||||
use Crater\Models\Customer;
|
||||
use Hash;
|
||||
use Illuminate\Support\Facades\Auth;
|
||||
use Illuminate\Validation\ValidationException;
|
||||
|
||||
class LoginController extends Controller
|
||||
{
|
||||
/**
|
||||
* Handle the incoming request.
|
||||
*
|
||||
* @param \Crater\Http\Requests\Customer\CustomerLoginRequest $request
|
||||
* @return \Illuminate\Http\Response
|
||||
*/
|
||||
public function __invoke(CustomerLoginRequest $request, Company $company)
|
||||
{
|
||||
$user = Customer::where('email', $request->email)
|
||||
->where('company_id', $company->id)
|
||||
->first();
|
||||
|
||||
if (! $user || ! Hash::check($request->password, $user->password)) {
|
||||
throw ValidationException::withMessages([
|
||||
'email' => ['The provided credentials are incorrect.'],
|
||||
]);
|
||||
}
|
||||
|
||||
if (! $user->enable_portal) {
|
||||
throw ValidationException::withMessages([
|
||||
'email' => ['Customer portal not available for this user.'],
|
||||
]);
|
||||
}
|
||||
|
||||
Auth::guard('customer')->login($user);
|
||||
|
||||
return response()->json([
|
||||
'success' => true
|
||||
]);
|
||||
}
|
||||
}
|
||||
@ -0,0 +1,83 @@
|
||||
<?php
|
||||
|
||||
namespace Crater\Http\Controllers\V1\Customer\Auth;
|
||||
|
||||
use Crater\Http\Controllers\Controller;
|
||||
use Crater\Providers\RouteServiceProvider;
|
||||
use Illuminate\Auth\Events\PasswordReset;
|
||||
use Illuminate\Foundation\Auth\ResetsPasswords;
|
||||
use Illuminate\Http\Request;
|
||||
use Illuminate\Support\Str;
|
||||
use Password;
|
||||
|
||||
class ResetPasswordController extends Controller
|
||||
{
|
||||
/*
|
||||
|--------------------------------------------------------------------------
|
||||
| Password Reset Controller
|
||||
|--------------------------------------------------------------------------
|
||||
|
|
||||
| This controller is responsible for handling password reset requests
|
||||
| and uses a simple trait to include this behavior. You're free to
|
||||
| explore this trait and override any methods you wish to tweak.
|
||||
|
|
||||
*/
|
||||
|
||||
use ResetsPasswords;
|
||||
|
||||
/**
|
||||
* Where to redirect users after resetting their password.
|
||||
*
|
||||
* @var string
|
||||
*/
|
||||
protected $redirectTo = RouteServiceProvider::CUSTOMER_HOME;
|
||||
|
||||
public function broker()
|
||||
{
|
||||
return Password::broker('customers');
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the response for a successful password reset.
|
||||
*
|
||||
* @param \Illuminate\Http\Request $request
|
||||
* @param string $response
|
||||
* @return \Illuminate\Http\RedirectResponse|\Illuminate\Http\JsonResponse
|
||||
*/
|
||||
protected function sendResetResponse(Request $request, $response)
|
||||
{
|
||||
return response()->json([
|
||||
'message' => 'Password reset successfully.',
|
||||
]);
|
||||
}
|
||||
|
||||
/**
|
||||
* Reset the given user's password.
|
||||
*
|
||||
* @param \Illuminate\Contracts\Auth\CanResetPassword $user
|
||||
* @param string $password
|
||||
* @return void
|
||||
*/
|
||||
protected function resetPassword($user, $password)
|
||||
{
|
||||
$user->password = $password;
|
||||
|
||||
$user->setRememberToken(Str::random(60));
|
||||
|
||||
$user->save();
|
||||
|
||||
event(new PasswordReset($user));
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the response for a failed password reset.
|
||||
*
|
||||
* @param \Illuminate\Http\Request $request
|
||||
* @param string $response
|
||||
* @return \Illuminate\Http\RedirectResponse|\Illuminate\Http\JsonResponse
|
||||
*/
|
||||
protected function sendResetFailedResponse(Request $request, $response)
|
||||
{
|
||||
return response('Failed, Invalid Token.', 403);
|
||||
}
|
||||
}
|
||||
@ -0,0 +1,36 @@
|
||||
<?php
|
||||
|
||||
namespace Crater\Http\Controllers\V1\Customer\Estimate;
|
||||
|
||||
use Crater\Http\Controllers\Controller;
|
||||
use Crater\Http\Resources\Customer\EstimateResource;
|
||||
use Crater\Models\Company;
|
||||
use Crater\Models\Estimate;
|
||||
use Illuminate\Http\Request;
|
||||
use Illuminate\Support\Facades\Auth;
|
||||
|
||||
class AcceptEstimateController extends Controller
|
||||
{
|
||||
/**
|
||||
* Handle the incoming request.
|
||||
*
|
||||
* @param \Illuminate\Http\Request $request
|
||||
* @param Estimate $estimate
|
||||
* @return \Illuminate\Http\Response
|
||||
*/
|
||||
public function __invoke(Request $request, Company $company, $id)
|
||||
{
|
||||
$estimate = $company->estimates()
|
||||
->whereCustomer(Auth::guard('customer')->id())
|
||||
->where('id', $id)
|
||||
->first();
|
||||
|
||||
if (! $estimate) {
|
||||
return response()->json(['error' => 'estimate_not_found'], 404);
|
||||
}
|
||||
|
||||
$estimate->update($request->only('status'));
|
||||
|
||||
return new EstimateResource($estimate);
|
||||
}
|
||||
}
|
||||
@ -0,0 +1,67 @@
|
||||
<?php
|
||||
|
||||
namespace Crater\Http\Controllers\V1\Customer\Estimate;
|
||||
|
||||
use Crater\Http\Controllers\Controller;
|
||||
use Crater\Http\Resources\Customer\EstimateResource;
|
||||
use Crater\Models\Company;
|
||||
use Crater\Models\Estimate;
|
||||
use Illuminate\Http\Request;
|
||||
use Illuminate\Support\Facades\Auth;
|
||||
|
||||
class EstimatesController extends Controller
|
||||
{
|
||||
/**
|
||||
* Display a listing of the resource.
|
||||
*
|
||||
* @return \Illuminate\Http\Response
|
||||
*/
|
||||
public function index(Request $request)
|
||||
{
|
||||
$limit = $request->has('limit') ? $request->limit : 10;
|
||||
|
||||
$estimates = Estimate::with([
|
||||
'items',
|
||||
'customer',
|
||||
'taxes',
|
||||
'creator',
|
||||
])
|
||||
->where('status', '<>', 'DRAFT')
|
||||
->whereCustomer(Auth::guard('customer')->id())
|
||||
->applyFilters($request->only([
|
||||
'status',
|
||||
'estimate_number',
|
||||
'from_date',
|
||||
'to_date',
|
||||
'orderByField',
|
||||
'orderBy',
|
||||
]))
|
||||
->latest()
|
||||
->paginateData($limit);
|
||||
|
||||
return (EstimateResource::collection($estimates))
|
||||
->additional(['meta' => [
|
||||
'estimateTotalCount' => Estimate::where('status', '<>', 'DRAFT')->whereCustomer(Auth::guard('customer')->id())->count(),
|
||||
]]);
|
||||
}
|
||||
|
||||
/**
|
||||
* Display the specified resource.
|
||||
*
|
||||
* @param Estimate $estimate
|
||||
* @return \Illuminate\Http\Response
|
||||
*/
|
||||
public function show(Company $company, $id)
|
||||
{
|
||||
$estimate = $company->estimates()
|
||||
->whereCustomer(Auth::guard('customer')->id())
|
||||
->where('id', $id)
|
||||
->first();
|
||||
|
||||
if (! $estimate) {
|
||||
return response()->json(['error' => 'estimate_not_found'], 404);
|
||||
}
|
||||
|
||||
return new EstimateResource($estimate);
|
||||
}
|
||||
}
|
||||
@ -3,41 +3,51 @@
|
||||
namespace Crater\Http\Controllers\V1\Customer;
|
||||
|
||||
use Crater\Http\Controllers\Controller;
|
||||
use Crater\Http\Resources\EstimateResource;
|
||||
use Crater\Mail\EstimateViewedMail;
|
||||
use Crater\Models\CompanySetting;
|
||||
use Crater\Models\Customer;
|
||||
use Crater\Models\EmailLog;
|
||||
use Crater\Models\Estimate;
|
||||
use Illuminate\Http\Request;
|
||||
|
||||
class EstimatePdfController extends Controller
|
||||
{
|
||||
/**
|
||||
* Handle the incoming request.
|
||||
*
|
||||
* @param \Illuminate\Http\Request $request
|
||||
* @return \Illuminate\Http\Response
|
||||
*/
|
||||
public function __invoke(Estimate $estimate)
|
||||
public function getPdf(EmailLog $emailLog, Request $request)
|
||||
{
|
||||
if ($estimate && ($estimate->status == Estimate::STATUS_SENT || $estimate->status == Estimate::STATUS_DRAFT)) {
|
||||
$estimate->status = Estimate::STATUS_VIEWED;
|
||||
$estimate->save();
|
||||
$notifyEstimateViewed = CompanySetting::getSetting(
|
||||
'notify_estimate_viewed',
|
||||
$estimate->company_id
|
||||
);
|
||||
$estimate = Estimate::find($emailLog->mailable_id);
|
||||
|
||||
if ($notifyEstimateViewed == 'YES') {
|
||||
$data['estimate'] = Estimate::findOrFail($estimate->id)->toArray();
|
||||
$data['user'] = Customer::find($estimate->customer_id)->toArray();
|
||||
$notificationEmail = CompanySetting::getSetting(
|
||||
'notification_email',
|
||||
if (! $emailLog->isExpired()) {
|
||||
if ($estimate && ($estimate->status == Estimate::STATUS_SENT || $estimate->status == Estimate::STATUS_DRAFT)) {
|
||||
$estimate->status = Estimate::STATUS_VIEWED;
|
||||
$estimate->save();
|
||||
$notifyEstimateViewed = CompanySetting::getSetting(
|
||||
'notify_estimate_viewed',
|
||||
$estimate->company_id
|
||||
);
|
||||
|
||||
\Mail::to($notificationEmail)->send(new EstimateViewedMail($data));
|
||||
if ($notifyEstimateViewed == 'YES') {
|
||||
$data['estimate'] = Estimate::findOrFail($estimate->id)->toArray();
|
||||
$data['user'] = Customer::find($estimate->customer_id)->toArray();
|
||||
$notificationEmail = CompanySetting::getSetting(
|
||||
'notification_email',
|
||||
$estimate->company_id
|
||||
);
|
||||
|
||||
\Mail::to($notificationEmail)->send(new EstimateViewedMail($data));
|
||||
}
|
||||
}
|
||||
|
||||
return $estimate->getGeneratedPDFOrStream('estimate');
|
||||
}
|
||||
|
||||
return $estimate->getGeneratedPDFOrStream('estimate');
|
||||
abort(403, 'Link Expired.');
|
||||
}
|
||||
|
||||
public function getEstimate(EmailLog $emailLog)
|
||||
{
|
||||
$estimate = Estimate::find($emailLog->mailable_id);
|
||||
|
||||
return new EstimateResource($estimate);
|
||||
}
|
||||
}
|
||||
|
||||
@ -0,0 +1,59 @@
|
||||
<?php
|
||||
|
||||
namespace Crater\Http\Controllers\V1\Customer\Expense;
|
||||
|
||||
use Crater\Http\Controllers\Controller;
|
||||
use Crater\Http\Resources\Customer\ExpenseResource;
|
||||
use Crater\Models\Company;
|
||||
use Crater\Models\Expense;
|
||||
use Illuminate\Http\Request;
|
||||
use Illuminate\Support\Facades\Auth;
|
||||
|
||||
class ExpensesController extends Controller
|
||||
{
|
||||
/**
|
||||
* Display a listing of the resource.
|
||||
*
|
||||
* @return \Illuminate\Http\Response
|
||||
*/
|
||||
public function index(Request $request)
|
||||
{
|
||||
$limit = $request->has('limit') ? $request->limit : 10;
|
||||
|
||||
$expenses = Expense::with('category', 'creator', 'fields')
|
||||
->whereUser(Auth::guard('customer')->id())
|
||||
->applyFilters($request->only([
|
||||
'expense_category_id',
|
||||
'from_date',
|
||||
'to_date',
|
||||
'orderByField',
|
||||
'orderBy',
|
||||
]))
|
||||
->paginateData($limit);
|
||||
|
||||
return (ExpenseResource::collection($expenses))
|
||||
->additional(['meta' => [
|
||||
'expenseTotalCount' => Expense::whereCustomer(Auth::guard('customer')->id())->count(),
|
||||
]]);
|
||||
}
|
||||
|
||||
/**
|
||||
* Display the specified resource.
|
||||
*
|
||||
* @param \Crater\Models\Expense $expense
|
||||
* @return \Illuminate\Http\Response
|
||||
*/
|
||||
public function show(Company $company, $id)
|
||||
{
|
||||
$expense = $company->expenses()
|
||||
->whereUser(Auth::guard('customer')->id())
|
||||
->where('id', $id)
|
||||
->first();
|
||||
|
||||
if (! $expense) {
|
||||
return response()->json(['error' => 'expense_not_found'], 404);
|
||||
}
|
||||
|
||||
return new ExpenseResource($expense);
|
||||
}
|
||||
}
|
||||
@ -0,0 +1,40 @@
|
||||
<?php
|
||||
|
||||
namespace Crater\Http\Controllers\V1\Customer\General;
|
||||
|
||||
use Crater\Http\Controllers\Controller;
|
||||
use Crater\Http\Resources\Customer\CustomerResource;
|
||||
use Crater\Models\Currency;
|
||||
use Crater\Models\Module;
|
||||
use Illuminate\Http\Request;
|
||||
use Illuminate\Support\Facades\Auth;
|
||||
|
||||
class BootstrapController extends Controller
|
||||
{
|
||||
/**
|
||||
* Handle the incoming request.
|
||||
*
|
||||
* @param \Illuminate\Http\Request $request
|
||||
* @return \Illuminate\Http\Response
|
||||
*/
|
||||
public function __invoke(Request $request)
|
||||
{
|
||||
$customer = Auth::guard('customer')->user();
|
||||
|
||||
foreach (\Menu::get('customer_portal_menu')->items->toArray() as $data) {
|
||||
if ($customer) {
|
||||
$menu[] = [
|
||||
'title' => $data->title,
|
||||
'link' => $data->link->path['url'],
|
||||
];
|
||||
}
|
||||
}
|
||||
|
||||
return (new CustomerResource($customer))
|
||||
->additional(['meta' => [
|
||||
'menu' => $menu,
|
||||
'current_customer_currency' => Currency::find($customer->currency_id),
|
||||
'modules' => Module::where('enabled', true)->pluck('name'),
|
||||
]]);
|
||||
}
|
||||
}
|
||||
@ -0,0 +1,45 @@
|
||||
<?php
|
||||
|
||||
namespace Crater\Http\Controllers\V1\Customer\General;
|
||||
|
||||
use Crater\Http\Controllers\Controller;
|
||||
use Crater\Models\Estimate;
|
||||
use Crater\Models\Invoice;
|
||||
use Crater\Models\Payment;
|
||||
use Illuminate\Http\Request;
|
||||
use Illuminate\Support\Facades\Auth;
|
||||
|
||||
class DashboardController extends Controller
|
||||
{
|
||||
/**
|
||||
* Handle the incoming request.
|
||||
*
|
||||
* @param \Illuminate\Http\Request $request
|
||||
* @return \Illuminate\Http\Response
|
||||
*/
|
||||
public function __invoke(Request $request)
|
||||
{
|
||||
$user = Auth::guard('customer')->user();
|
||||
|
||||
$amountDue = Invoice::whereCustomer($user->id)
|
||||
->where('status', '<>', 'DRAFT')
|
||||
->sum('due_amount');
|
||||
$invoiceCount = Invoice::whereCustomer($user->id)
|
||||
->where('status', '<>', 'DRAFT')
|
||||
->count();
|
||||
$estimatesCount = Estimate::whereCustomer($user->id)
|
||||
->where('status', '<>', 'DRAFT')
|
||||
->count();
|
||||
$paymentCount = Payment::whereCustomer($user->id)
|
||||
->count();
|
||||
|
||||
return response()->json([
|
||||
'due_amount' => $amountDue,
|
||||
'recentInvoices' => Invoice::whereCustomer($user->id)->where('status', '<>', 'DRAFT')->take(5)->latest()->get(),
|
||||
'recentEstimates' => Estimate::whereCustomer($user->id)->where('status', '<>', 'DRAFT')->take(5)->latest()->get(),
|
||||
'invoice_count' => $invoiceCount,
|
||||
'estimate_count' => $estimatesCount,
|
||||
'payment_count' => $paymentCount,
|
||||
]);
|
||||
}
|
||||
}
|
||||
@ -0,0 +1,49 @@
|
||||
<?php
|
||||
|
||||
namespace Crater\Http\Controllers\V1\Customer\General;
|
||||
|
||||
use Crater\Http\Controllers\Controller;
|
||||
use Crater\Http\Requests\Customer\CustomerProfileRequest;
|
||||
use Crater\Http\Resources\Customer\CustomerResource;
|
||||
use Crater\Models\Company;
|
||||
use Illuminate\Http\Request;
|
||||
use Illuminate\Support\Facades\Auth;
|
||||
|
||||
class ProfileController extends Controller
|
||||
{
|
||||
public function updateProfile(Company $company, CustomerProfileRequest $request)
|
||||
{
|
||||
$customer = Auth::guard('customer')->user();
|
||||
|
||||
$customer->update($request->validated());
|
||||
|
||||
if (isset($request->is_customer_avatar_removed) && (bool) $request->is_customer_avatar_removed) {
|
||||
$customer->clearMediaCollection('customer_avatar');
|
||||
}
|
||||
if ($customer && $request->hasFile('customer_avatar')) {
|
||||
$customer->clearMediaCollection('customer_avatar');
|
||||
|
||||
$customer->addMediaFromRequest('customer_avatar')
|
||||
->toMediaCollection('customer_avatar');
|
||||
}
|
||||
|
||||
if ($request->billing !== null) {
|
||||
$customer->shippingAddress()->delete();
|
||||
$customer->addresses()->create($request->getShippingAddress());
|
||||
}
|
||||
|
||||
if ($request->shipping !== null) {
|
||||
$customer->billingAddress()->delete();
|
||||
$customer->addresses()->create($request->getBillingAddress());
|
||||
}
|
||||
|
||||
return new CustomerResource($customer);
|
||||
}
|
||||
|
||||
public function getUser(Request $request)
|
||||
{
|
||||
$customer = Auth::guard('customer')->user();
|
||||
|
||||
return new CustomerResource($customer);
|
||||
}
|
||||
}
|
||||
@ -0,0 +1,49 @@
|
||||
<?php
|
||||
|
||||
namespace Crater\Http\Controllers\V1\Customer\Invoice;
|
||||
|
||||
use Crater\Http\Controllers\Controller;
|
||||
use Crater\Http\Resources\Customer\InvoiceResource;
|
||||
use Crater\Models\Company;
|
||||
use Crater\Models\Invoice;
|
||||
use Illuminate\Http\Request;
|
||||
use Illuminate\Support\Facades\Auth;
|
||||
|
||||
class InvoicesController extends Controller
|
||||
{
|
||||
/**
|
||||
* Display a listing of the resource.
|
||||
*
|
||||
* @return \Illuminate\Http\Response
|
||||
*/
|
||||
public function index(Request $request)
|
||||
{
|
||||
$limit = $request->has('limit') ? $request->limit : 10;
|
||||
|
||||
$invoices = Invoice::with(['items', 'customer', 'creator', 'taxes'])
|
||||
->where('status', '<>', 'DRAFT')
|
||||
->applyFilters($request->all())
|
||||
->whereCustomer(Auth::guard('customer')->id())
|
||||
->latest()
|
||||
->paginateData($limit);
|
||||
|
||||
return (InvoiceResource::collection($invoices))
|
||||
->additional(['meta' => [
|
||||
'invoiceTotalCount' => Invoice::where('status', '<>', 'DRAFT')->whereCustomer(Auth::guard('customer')->id())->count(),
|
||||
]]);
|
||||
}
|
||||
|
||||
public function show(Company $company, $id)
|
||||
{
|
||||
$invoice = $company->invoices()
|
||||
->whereCustomer(Auth::guard('customer')->id())
|
||||
->where('id', $id)
|
||||
->first();
|
||||
|
||||
if (! $invoice) {
|
||||
return response()->json(['error' => 'invoice_not_found'], 404);
|
||||
}
|
||||
|
||||
return new InvoiceResource($invoice);
|
||||
}
|
||||
}
|
||||
@ -3,42 +3,59 @@
|
||||
namespace Crater\Http\Controllers\V1\Customer;
|
||||
|
||||
use Crater\Http\Controllers\Controller;
|
||||
use Crater\Http\Resources\Customer\InvoiceResource as CustomerInvoiceResource;
|
||||
use Crater\Mail\InvoiceViewedMail;
|
||||
use Crater\Models\CompanySetting;
|
||||
use Crater\Models\Customer;
|
||||
use Crater\Models\EmailLog;
|
||||
use Crater\Models\Invoice;
|
||||
use Illuminate\Http\Request;
|
||||
|
||||
class InvoicePdfController extends Controller
|
||||
{
|
||||
/**
|
||||
* Handle the incoming request.
|
||||
*
|
||||
* @param \Illuminate\Http\Request $request
|
||||
* @return \Illuminate\Http\Response
|
||||
*/
|
||||
public function __invoke(Invoice $invoice)
|
||||
public function getPdf(EmailLog $emailLog, Request $request)
|
||||
{
|
||||
if ($invoice && ($invoice->status == Invoice::STATUS_SENT || $invoice->status == Invoice::STATUS_DRAFT)) {
|
||||
$invoice->status = Invoice::STATUS_VIEWED;
|
||||
$invoice->viewed = true;
|
||||
$invoice->save();
|
||||
$notifyInvoiceViewed = CompanySetting::getSetting(
|
||||
'notify_invoice_viewed',
|
||||
$invoice->company_id
|
||||
);
|
||||
$invoice = Invoice::find($emailLog->mailable_id);
|
||||
|
||||
if ($notifyInvoiceViewed == 'YES') {
|
||||
$data['invoice'] = Invoice::findOrFail($invoice->id)->toArray();
|
||||
$data['user'] = Customer::find($invoice->customer_id)->toArray();
|
||||
$notificationEmail = CompanySetting::getSetting(
|
||||
'notification_email',
|
||||
if (! $emailLog->isExpired()) {
|
||||
if ($invoice && ($invoice->status == Invoice::STATUS_SENT || $invoice->status == Invoice::STATUS_DRAFT)) {
|
||||
$invoice->status = Invoice::STATUS_VIEWED;
|
||||
$invoice->viewed = true;
|
||||
$invoice->save();
|
||||
$notifyInvoiceViewed = CompanySetting::getSetting(
|
||||
'notify_invoice_viewed',
|
||||
$invoice->company_id
|
||||
);
|
||||
|
||||
\Mail::to($notificationEmail)->send(new InvoiceViewedMail($data));
|
||||
if ($notifyInvoiceViewed == 'YES') {
|
||||
$data['invoice'] = Invoice::findOrFail($invoice->id)->toArray();
|
||||
$data['user'] = Customer::find($invoice->customer_id)->toArray();
|
||||
$notificationEmail = CompanySetting::getSetting(
|
||||
'notification_email',
|
||||
$invoice->company_id
|
||||
);
|
||||
|
||||
\Mail::to($notificationEmail)->send(new InvoiceViewedMail($data));
|
||||
}
|
||||
}
|
||||
|
||||
if ($request->has('pdf')) {
|
||||
return $invoice->getGeneratedPDFOrStream('invoice');
|
||||
}
|
||||
|
||||
return view('app')->with([
|
||||
'customer_logo' => get_company_setting('customer_portal_logo', $invoice->company_id),
|
||||
'current_theme' => get_company_setting('customer_portal_theme', $invoice->company_id)
|
||||
]);
|
||||
}
|
||||
|
||||
return $invoice->getGeneratedPDFOrStream('invoice');
|
||||
abort(403, 'Link Expired.');
|
||||
}
|
||||
|
||||
public function getInvoice(EmailLog $emailLog)
|
||||
{
|
||||
$invoice = Invoice::find($emailLog->mailable_id);
|
||||
|
||||
return new CustomerInvoiceResource($invoice);
|
||||
}
|
||||
}
|
||||
|
||||
@ -0,0 +1,23 @@
|
||||
<?php
|
||||
|
||||
namespace Crater\Http\Controllers\V1\Customer\Payment;
|
||||
|
||||
use Crater\Http\Controllers\Controller;
|
||||
use Crater\Http\Resources\Customer\PaymentMethodResource;
|
||||
use Crater\Models\Company;
|
||||
use Crater\Models\PaymentMethod;
|
||||
use Illuminate\Http\Request;
|
||||
|
||||
class PaymentMethodController extends Controller
|
||||
{
|
||||
/**
|
||||
* Handle the incoming request.
|
||||
*
|
||||
* @param \Illuminate\Http\Request $request
|
||||
* @return \Illuminate\Http\Response
|
||||
*/
|
||||
public function __invoke(Request $request, Company $company)
|
||||
{
|
||||
return PaymentMethodResource::collection(PaymentMethod::where('company_id', $company->id)->get());
|
||||
}
|
||||
}
|
||||
@ -0,0 +1,61 @@
|
||||
<?php
|
||||
|
||||
namespace Crater\Http\Controllers\V1\Customer\Payment;
|
||||
|
||||
use Crater\Http\Controllers\Controller;
|
||||
use Crater\Http\Resources\Customer\PaymentResource;
|
||||
use Crater\Models\Company;
|
||||
use Crater\Models\Payment;
|
||||
use Illuminate\Http\Request;
|
||||
use Illuminate\Support\Facades\Auth;
|
||||
|
||||
class PaymentsController extends Controller
|
||||
{
|
||||
/**
|
||||
* Display a listing of the resource.
|
||||
*
|
||||
* @return \Illuminate\Http\Response
|
||||
*/
|
||||
public function index(Request $request)
|
||||
{
|
||||
$limit = $request->has('limit') ? $request->limit : 10;
|
||||
|
||||
$payments = Payment::with(['customer', 'invoice', 'paymentMethod', 'creator'])
|
||||
->whereCustomer(Auth::guard('customer')->id())
|
||||
->leftJoin('invoices', 'invoices.id', '=', 'payments.invoice_id')
|
||||
->applyFilters($request->only([
|
||||
'payment_number',
|
||||
'payment_method_id',
|
||||
'orderByField',
|
||||
'orderBy',
|
||||
]))
|
||||
->select('payments.*', 'invoices.invoice_number')
|
||||
->latest()
|
||||
->paginateData($limit);
|
||||
|
||||
return (PaymentResource::collection($payments))
|
||||
->additional(['meta' => [
|
||||
'paymentTotalCount' => Payment::whereCustomer(Auth::guard('customer')->id())->count(),
|
||||
]]);
|
||||
}
|
||||
|
||||
/**
|
||||
* Display the specified resource.
|
||||
*
|
||||
* @param \Crater\Models\Payment $payment
|
||||
* @return \Illuminate\Http\Response
|
||||
*/
|
||||
public function show(Company $company, $id)
|
||||
{
|
||||
$payment = $company->payments()
|
||||
->whereCustomer(Auth::guard('customer')->id())
|
||||
->where('id', $id)
|
||||
->first();
|
||||
|
||||
if (! $payment) {
|
||||
return response()->json(['error' => 'payment_not_found'], 404);
|
||||
}
|
||||
|
||||
return new PaymentResource($payment);
|
||||
}
|
||||
}
|
||||
28
app/Http/Controllers/V1/Customer/PaymentPdfController.php
Normal file
28
app/Http/Controllers/V1/Customer/PaymentPdfController.php
Normal file
@ -0,0 +1,28 @@
|
||||
<?php
|
||||
|
||||
namespace Crater\Http\Controllers\V1\Customer;
|
||||
|
||||
use Crater\Http\Controllers\Controller;
|
||||
use Crater\Http\Resources\PaymentResource;
|
||||
use Crater\Models\EmailLog;
|
||||
use Crater\Models\Payment;
|
||||
use Illuminate\Http\Request;
|
||||
|
||||
class PaymentPdfController extends Controller
|
||||
{
|
||||
public function getPdf(EmailLog $emailLog, Request $request)
|
||||
{
|
||||
if (! $emailLog->isExpired()) {
|
||||
return $emailLog->mailable->getGeneratedPDFOrStream('payment');
|
||||
}
|
||||
|
||||
abort(403, 'Link Expired.');
|
||||
}
|
||||
|
||||
public function getPayment(EmailLog $emailLog)
|
||||
{
|
||||
$payment = Payment::find($emailLog->mailable_id);
|
||||
|
||||
return new PaymentResource($payment);
|
||||
}
|
||||
}
|
||||
35
app/Http/Controllers/V1/Modules/ScriptController.php
Normal file
35
app/Http/Controllers/V1/Modules/ScriptController.php
Normal file
@ -0,0 +1,35 @@
|
||||
<?php
|
||||
|
||||
namespace Crater\Http\Controllers\V1\Modules;
|
||||
|
||||
use Crater\Http\Controllers\Controller;
|
||||
use Crater\Services\Module\ModuleFacade;
|
||||
use DateTime;
|
||||
use Illuminate\Support\Arr;
|
||||
use Request;
|
||||
|
||||
class ScriptController extends Controller
|
||||
{
|
||||
/**
|
||||
* Serve the requested script.
|
||||
*
|
||||
* @param \Request $request
|
||||
* @return \Illuminate\Http\Response
|
||||
*
|
||||
* @throws \Symfony\Component\HttpKernel\Exception\NotFoundHttpException
|
||||
*/
|
||||
public function __invoke(Request $request, string $script)
|
||||
{
|
||||
$path = Arr::get(ModuleFacade::allScripts(), $script);
|
||||
|
||||
abort_if(is_null($path), 404);
|
||||
|
||||
return response(
|
||||
file_get_contents($path),
|
||||
200,
|
||||
[
|
||||
'Content-Type' => 'application/javascript',
|
||||
]
|
||||
)->setLastModified(DateTime::createFromFormat('U', filemtime($path)));
|
||||
}
|
||||
}
|
||||
35
app/Http/Controllers/V1/Modules/StyleController.php
Normal file
35
app/Http/Controllers/V1/Modules/StyleController.php
Normal file
@ -0,0 +1,35 @@
|
||||
<?php
|
||||
|
||||
namespace Crater\Http\Controllers\V1\Modules;
|
||||
|
||||
use Crater\Http\Controllers\Controller;
|
||||
use Crater\Services\Module\ModuleFacade;
|
||||
use DateTime;
|
||||
use Illuminate\Support\Arr;
|
||||
use Request;
|
||||
|
||||
class StyleController extends Controller
|
||||
{
|
||||
/**
|
||||
* Serve the requested stylesheet.
|
||||
*
|
||||
* @param \Request $request
|
||||
* @return \Illuminate\Http\Response
|
||||
*
|
||||
* @throws \Symfony\Component\HttpKernel\Exception\NotFoundHttpException
|
||||
*/
|
||||
public function __invoke(Request $request, string $style)
|
||||
{
|
||||
$path = Arr::get(ModuleFacade::allStyles(), $style);
|
||||
|
||||
abort_if(is_null($path), 404);
|
||||
|
||||
return response(
|
||||
file_get_contents($path),
|
||||
200,
|
||||
[
|
||||
'Content-Type' => 'text/css',
|
||||
]
|
||||
)->setLastModified(DateTime::createFromFormat('U', filemtime($path)));
|
||||
}
|
||||
}
|
||||
@ -17,6 +17,8 @@ class DownloadReceiptController extends Controller
|
||||
*/
|
||||
public function __invoke(Expense $expense)
|
||||
{
|
||||
$this->authorize('view', $expense);
|
||||
|
||||
if ($expense) {
|
||||
$media = $expense->getFirstMedia('receipts');
|
||||
if ($media) {
|
||||
|
||||
@ -4,6 +4,7 @@ namespace Crater\Http\Controllers\V1\PDF;
|
||||
|
||||
use Crater\Http\Controllers\Controller;
|
||||
use Crater\Models\Estimate;
|
||||
use Illuminate\Http\Request;
|
||||
|
||||
class EstimatePdfController extends Controller
|
||||
{
|
||||
@ -13,8 +14,13 @@ class EstimatePdfController extends Controller
|
||||
* @param \Illuminate\Http\Request $request
|
||||
* @return \Illuminate\Http\Response
|
||||
*/
|
||||
public function __invoke(Estimate $estimate)
|
||||
public function __invoke(Request $request, Estimate $estimate)
|
||||
{
|
||||
if ($request->has('preview')) {
|
||||
return $estimate->getPDFData();
|
||||
}
|
||||
|
||||
|
||||
return $estimate->getGeneratedPDFOrStream('estimate');
|
||||
}
|
||||
}
|
||||
|
||||
@ -4,6 +4,7 @@ namespace Crater\Http\Controllers\V1\PDF;
|
||||
|
||||
use Crater\Http\Controllers\Controller;
|
||||
use Crater\Models\Invoice;
|
||||
use Illuminate\Http\Request;
|
||||
|
||||
class InvoicePdfController extends Controller
|
||||
{
|
||||
@ -13,8 +14,12 @@ class InvoicePdfController extends Controller
|
||||
* @param \Illuminate\Http\Request $request
|
||||
* @return \Illuminate\Http\Response
|
||||
*/
|
||||
public function __invoke(Invoice $invoice)
|
||||
public function __invoke(Request $request, Invoice $invoice)
|
||||
{
|
||||
if ($request->has('preview')) {
|
||||
return $invoice->getPDFData();
|
||||
}
|
||||
|
||||
return $invoice->getGeneratedPDFOrStream('invoice');
|
||||
}
|
||||
}
|
||||
|
||||
@ -4,6 +4,7 @@ namespace Crater\Http\Controllers\V1\PDF;
|
||||
|
||||
use Crater\Http\Controllers\Controller;
|
||||
use Crater\Models\Payment;
|
||||
use Illuminate\Http\Request;
|
||||
|
||||
class PaymentPdfController extends Controller
|
||||
{
|
||||
@ -13,8 +14,12 @@ class PaymentPdfController extends Controller
|
||||
* @param \Illuminate\Http\Request $request
|
||||
* @return \Illuminate\Http\Response
|
||||
*/
|
||||
public function __invoke(Payment $payment)
|
||||
public function __invoke(Request $request, Payment $payment)
|
||||
{
|
||||
if ($request->has('preview')) {
|
||||
return view('app.pdf.payment.payment');
|
||||
}
|
||||
|
||||
return $payment->getGeneratedPDFOrStream('payment');
|
||||
}
|
||||
}
|
||||
|
||||
23
app/Http/Controllers/V1/Webhook/CronJobController.php
Normal file
23
app/Http/Controllers/V1/Webhook/CronJobController.php
Normal file
@ -0,0 +1,23 @@
|
||||
<?php
|
||||
|
||||
namespace Crater\Http\Controllers\V1\Webhook;
|
||||
|
||||
use Crater\Http\Controllers\Controller;
|
||||
use Illuminate\Http\Request;
|
||||
use Illuminate\Support\Facades\Artisan;
|
||||
|
||||
class CronJobController extends Controller
|
||||
{
|
||||
/**
|
||||
* Handle the incoming request.
|
||||
*
|
||||
* @param \Illuminate\Http\Request $request
|
||||
* @return \Illuminate\Http\Response
|
||||
*/
|
||||
public function __invoke(Request $request)
|
||||
{
|
||||
Artisan::call('schedule:run');
|
||||
|
||||
return response()->json(['success' => true]);
|
||||
}
|
||||
}
|
||||
@ -69,6 +69,9 @@ class Kernel extends HttpKernel
|
||||
'redirect-if-unauthenticated' => \Crater\Http\Middleware\RedirectIfUnauthorized::class,
|
||||
'customer-guest' => \Crater\Http\Middleware\CustomerGuest::class,
|
||||
'company' => \Crater\Http\Middleware\CompanyMiddleware::class,
|
||||
'pdf-auth' => \Crater\Http\Middleware\PdfMiddleware::class,
|
||||
'cron-job' => \Crater\Http\Middleware\CronJobMiddleware::class,
|
||||
'customer-portal' => \Crater\Http\Middleware\CustomerPortalMiddleware::class,
|
||||
];
|
||||
|
||||
/**
|
||||
|
||||
@ -3,7 +3,6 @@
|
||||
namespace Crater\Http\Middleware;
|
||||
|
||||
use Closure;
|
||||
use Crater\Models\CompanySetting;
|
||||
use Crater\Models\FileDisk;
|
||||
|
||||
class ConfigMiddleware
|
||||
@ -18,15 +17,6 @@ class ConfigMiddleware
|
||||
public function handle($request, Closure $next)
|
||||
{
|
||||
if (\Storage::disk('local')->has('database_created')) {
|
||||
$setting = CompanySetting::getSetting('time_zone', $request->header('company'));
|
||||
|
||||
$timezone = config('app.timezone');
|
||||
|
||||
if ($setting && $setting != null && $setting != $timezone) {
|
||||
config(['app.timezone' => $setting]);
|
||||
date_default_timezone_set($setting);
|
||||
}
|
||||
|
||||
if ($request->has('file_disk_id')) {
|
||||
$file_disk = FileDisk::find($request->file_disk_id);
|
||||
} else {
|
||||
|
||||
25
app/Http/Middleware/CronJobMiddleware.php
Normal file
25
app/Http/Middleware/CronJobMiddleware.php
Normal file
@ -0,0 +1,25 @@
|
||||
<?php
|
||||
|
||||
namespace Crater\Http\Middleware;
|
||||
|
||||
use Closure;
|
||||
use Illuminate\Http\Request;
|
||||
|
||||
class CronJobMiddleware
|
||||
{
|
||||
/**
|
||||
* Handle an incoming request.
|
||||
*
|
||||
* @param \Illuminate\Http\Request $request
|
||||
* @param \Closure $next
|
||||
* @return mixed
|
||||
*/
|
||||
public function handle(Request $request, Closure $next)
|
||||
{
|
||||
if ($request->header('x-authorization-token') && $request->header('x-authorization-token') == config('services.cron_job.auth_token')) {
|
||||
return $next($request);
|
||||
}
|
||||
|
||||
return response()->json(['unauthorized'], 401);
|
||||
}
|
||||
}
|
||||
30
app/Http/Middleware/CustomerPortalMiddleware.php
Normal file
30
app/Http/Middleware/CustomerPortalMiddleware.php
Normal file
@ -0,0 +1,30 @@
|
||||
<?php
|
||||
|
||||
namespace Crater\Http\Middleware;
|
||||
|
||||
use Closure;
|
||||
use Illuminate\Http\Request;
|
||||
use Illuminate\Support\Facades\Auth;
|
||||
|
||||
class CustomerPortalMiddleware
|
||||
{
|
||||
/**
|
||||
* Handle an incoming request.
|
||||
*
|
||||
* @param \Illuminate\Http\Request $request
|
||||
* @param \Closure(\Illuminate\Http\Request): (\Illuminate\Http\Response|\Illuminate\Http\RedirectResponse) $next
|
||||
* @return \Illuminate\Http\Response|\Illuminate\Http\RedirectResponse
|
||||
*/
|
||||
public function handle(Request $request, Closure $next)
|
||||
{
|
||||
$user = Auth::guard('customer')->user();
|
||||
|
||||
if (! $user->enable_portal) {
|
||||
Auth::guard('customer')->logout();
|
||||
|
||||
return response('Unauthorized.', 401);
|
||||
}
|
||||
|
||||
return $next($request);
|
||||
}
|
||||
}
|
||||
26
app/Http/Middleware/PdfMiddleware.php
Normal file
26
app/Http/Middleware/PdfMiddleware.php
Normal file
@ -0,0 +1,26 @@
|
||||
<?php
|
||||
|
||||
namespace Crater\Http\Middleware;
|
||||
|
||||
use Closure;
|
||||
use Illuminate\Http\Request;
|
||||
use Illuminate\Support\Facades\Auth;
|
||||
|
||||
class PdfMiddleware
|
||||
{
|
||||
/**
|
||||
* Handle an incoming request.
|
||||
*
|
||||
* @param \Illuminate\Http\Request $request
|
||||
* @param \Closure(\Illuminate\Http\Request): (\Illuminate\Http\Response|\Illuminate\Http\RedirectResponse) $next
|
||||
* @return \Illuminate\Http\Response|\Illuminate\Http\RedirectResponse
|
||||
*/
|
||||
public function handle(Request $request, Closure $next)
|
||||
{
|
||||
if (Auth::guard('web')->check() || Auth::guard('sanctum')->check() || Auth::guard('customer')->check()) {
|
||||
return $next($request);
|
||||
}
|
||||
|
||||
return redirect('/login');
|
||||
}
|
||||
}
|
||||
40
app/Http/Requests/AvatarRequest.php
Normal file
40
app/Http/Requests/AvatarRequest.php
Normal file
@ -0,0 +1,40 @@
|
||||
<?php
|
||||
|
||||
namespace Crater\Http\Requests;
|
||||
|
||||
use Crater\Rules\Base64Mime;
|
||||
use Illuminate\Foundation\Http\FormRequest;
|
||||
|
||||
class AvatarRequest extends FormRequest
|
||||
{
|
||||
/**
|
||||
* Determine if the user is authorized to make this request.
|
||||
*
|
||||
* @return bool
|
||||
*/
|
||||
public function authorize()
|
||||
{
|
||||
return true;
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the validation rules that apply to the request.
|
||||
*
|
||||
* @return array
|
||||
*/
|
||||
public function rules()
|
||||
{
|
||||
return [
|
||||
'admin_avatar' => [
|
||||
'nullable',
|
||||
'file',
|
||||
'mimes:gif,jpg,png',
|
||||
'max:20000'
|
||||
],
|
||||
'avatar' => [
|
||||
'nullable',
|
||||
new Base64Mime(['gif', 'jpg', 'png'])
|
||||
]
|
||||
];
|
||||
}
|
||||
}
|
||||
@ -33,6 +33,10 @@ class CompaniesRequest extends FormRequest
|
||||
'currency' => [
|
||||
'required'
|
||||
],
|
||||
'slug' => [
|
||||
'required',
|
||||
Rule::unique('companies')
|
||||
],
|
||||
'address.name' => [
|
||||
'nullable',
|
||||
],
|
||||
@ -67,7 +71,8 @@ class CompaniesRequest extends FormRequest
|
||||
{
|
||||
return collect($this->validated())
|
||||
->only([
|
||||
'name'
|
||||
'name',
|
||||
'slug'
|
||||
])
|
||||
->merge([
|
||||
'owner_id' => $this->user()->id
|
||||
|
||||
34
app/Http/Requests/CompanyLogoRequest.php
Normal file
34
app/Http/Requests/CompanyLogoRequest.php
Normal file
@ -0,0 +1,34 @@
|
||||
<?php
|
||||
|
||||
namespace Crater\Http\Requests;
|
||||
|
||||
use Crater\Rules\Base64Mime;
|
||||
use Illuminate\Foundation\Http\FormRequest;
|
||||
|
||||
class CompanyLogoRequest extends FormRequest
|
||||
{
|
||||
/**
|
||||
* Determine if the user is authorized to make this request.
|
||||
*
|
||||
* @return bool
|
||||
*/
|
||||
public function authorize()
|
||||
{
|
||||
return true;
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the validation rules that apply to the request.
|
||||
*
|
||||
* @return array
|
||||
*/
|
||||
public function rules()
|
||||
{
|
||||
return [
|
||||
'company_logo' => [
|
||||
'nullable',
|
||||
new Base64Mime(['gif', 'jpg', 'png'])
|
||||
]
|
||||
];
|
||||
}
|
||||
}
|
||||
@ -29,9 +29,23 @@ class CompanyRequest extends FormRequest
|
||||
'required',
|
||||
Rule::unique('companies')->ignore($this->header('company'), 'id'),
|
||||
],
|
||||
'slug' => [
|
||||
'required',
|
||||
Rule::unique('companies')->ignore($this->header('company'), 'id'),
|
||||
],
|
||||
'address.country_id' => [
|
||||
'required',
|
||||
],
|
||||
];
|
||||
}
|
||||
|
||||
public function getCompanyPayload()
|
||||
{
|
||||
return collect($this->validated())
|
||||
->only([
|
||||
'name',
|
||||
'slug'
|
||||
])
|
||||
->toArray();
|
||||
}
|
||||
}
|
||||
|
||||
37
app/Http/Requests/Customer/CustomerLoginRequest.php
Normal file
37
app/Http/Requests/Customer/CustomerLoginRequest.php
Normal file
@ -0,0 +1,37 @@
|
||||
<?php
|
||||
|
||||
namespace Crater\Http\Requests\Customer;
|
||||
|
||||
use Illuminate\Foundation\Http\FormRequest;
|
||||
|
||||
class CustomerLoginRequest extends FormRequest
|
||||
{
|
||||
/**
|
||||
* Determine if the user is authorized to make this request.
|
||||
*
|
||||
* @return bool
|
||||
*/
|
||||
public function authorize()
|
||||
{
|
||||
return true;
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the validation rules that apply to the request.
|
||||
*
|
||||
* @return array
|
||||
*/
|
||||
public function rules()
|
||||
{
|
||||
return [
|
||||
'email' => [
|
||||
'required',
|
||||
'string'
|
||||
],
|
||||
'password' => [
|
||||
'required',
|
||||
'string'
|
||||
]
|
||||
];
|
||||
}
|
||||
}
|
||||
@ -1,44 +1,43 @@
|
||||
<?php
|
||||
|
||||
use Crater\Http\Requests\CustomerRequest;
|
||||
namespace Crater\Http\Requests\Customer;
|
||||
|
||||
use Crater\Models\Address;
|
||||
use Illuminate\Foundation\Http\FormRequest;
|
||||
use Illuminate\Support\Facades\Auth;
|
||||
use Illuminate\Validation\Rule;
|
||||
|
||||
test('customer request validation rules', function () {
|
||||
$request = new CustomerRequest();
|
||||
class CustomerProfileRequest extends FormRequest
|
||||
{
|
||||
/**
|
||||
* Determine if the user is authorized to make this request.
|
||||
*
|
||||
* @return bool
|
||||
*/
|
||||
public function authorize()
|
||||
{
|
||||
return true;
|
||||
}
|
||||
|
||||
$this->assertEquals(
|
||||
[
|
||||
/**
|
||||
* Get the validation rules that apply to the request.
|
||||
*
|
||||
* @return array
|
||||
*/
|
||||
public function rules()
|
||||
{
|
||||
return [
|
||||
'name' => [
|
||||
'required',
|
||||
],
|
||||
'email' => [
|
||||
'email',
|
||||
'nullable',
|
||||
Rule::unique('customers')->where('company_id', $request->header('company'))
|
||||
],
|
||||
'password' => [
|
||||
'nullable',
|
||||
'min:8',
|
||||
],
|
||||
'phone' => [
|
||||
'nullable',
|
||||
],
|
||||
'company_name' => [
|
||||
'nullable',
|
||||
],
|
||||
'contact_name' => [
|
||||
'nullable',
|
||||
],
|
||||
'website' => [
|
||||
'nullable',
|
||||
],
|
||||
'prefix' => [
|
||||
'nullable',
|
||||
],
|
||||
'enable_portal' => [
|
||||
'nullable',
|
||||
],
|
||||
'currency_id' => [
|
||||
'email' => [
|
||||
'nullable',
|
||||
'email',
|
||||
Rule::unique('customers')->where('company_id', $this->header('company'))->ignore(Auth::id(), 'id'),
|
||||
],
|
||||
'billing.name' => [
|
||||
'nullable',
|
||||
@ -93,14 +92,31 @@ test('customer request validation rules', function () {
|
||||
],
|
||||
'shipping.fax' => [
|
||||
'nullable',
|
||||
],
|
||||
'customer_avatar' => [
|
||||
'nullable',
|
||||
'file',
|
||||
'mimes:gif,jpg,png',
|
||||
'max:20000'
|
||||
]
|
||||
],
|
||||
$request->rules()
|
||||
);
|
||||
});
|
||||
];
|
||||
}
|
||||
|
||||
test('customer request authorize', function () {
|
||||
$request = new CustomerRequest();
|
||||
public function getShippingAddress()
|
||||
{
|
||||
return collect($this->shipping)
|
||||
->merge([
|
||||
'type' => Address::SHIPPING_TYPE
|
||||
])
|
||||
->toArray();
|
||||
}
|
||||
|
||||
$this->assertTrue($request->authorize());
|
||||
});
|
||||
public function getBillingAddress()
|
||||
{
|
||||
return collect($this->billing)
|
||||
->merge([
|
||||
'type' => Address::BILLING_TYPE
|
||||
])
|
||||
->toArray();
|
||||
}
|
||||
}
|
||||
33
app/Http/Requests/CustomerEstimateStatusRequest.php
Normal file
33
app/Http/Requests/CustomerEstimateStatusRequest.php
Normal file
@ -0,0 +1,33 @@
|
||||
<?php
|
||||
|
||||
namespace Crater\Http\Requests;
|
||||
|
||||
use Illuminate\Foundation\Http\FormRequest;
|
||||
|
||||
class CustomerEstimateStatusRequest extends FormRequest
|
||||
{
|
||||
/**
|
||||
* Determine if the user is authorized to make this request.
|
||||
*
|
||||
* @return bool
|
||||
*/
|
||||
public function authorize()
|
||||
{
|
||||
return true;
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the validation rules that apply to the request.
|
||||
*
|
||||
* @return array
|
||||
*/
|
||||
public function rules()
|
||||
{
|
||||
return [
|
||||
'status' => [
|
||||
'required',
|
||||
'in:ACCEPTED,REJECTED',
|
||||
]
|
||||
];
|
||||
}
|
||||
}
|
||||
@ -54,7 +54,8 @@ class CustomerRequest extends FormRequest
|
||||
'nullable',
|
||||
],
|
||||
'enable_portal' => [
|
||||
'nullable',
|
||||
|
||||
'boolean'
|
||||
],
|
||||
'currency_id' => [
|
||||
'nullable',
|
||||
@ -119,7 +120,7 @@ class CustomerRequest extends FormRequest
|
||||
$rules['email'] = [
|
||||
'email',
|
||||
'nullable',
|
||||
Rule::unique('customers')->ignore($this->route('customer')->id),
|
||||
Rule::unique('customers')->where('company_id', $this->header('company'))->ignore($this->route('customer')->id),
|
||||
];
|
||||
};
|
||||
|
||||
|
||||
@ -51,6 +51,12 @@ class ExpenseRequest extends FormRequest
|
||||
'currency_id' => [
|
||||
'required'
|
||||
],
|
||||
'attachment_receipt' => [
|
||||
'nullable',
|
||||
'file',
|
||||
'mimes:jpg,png,pdf,doc,docx,xls,xlsx,ppt,pptx',
|
||||
'max:20000'
|
||||
]
|
||||
];
|
||||
|
||||
if ($companyCurrency && $this->currency_id) {
|
||||
|
||||
33
app/Http/Requests/GetSettingRequest.php
Normal file
33
app/Http/Requests/GetSettingRequest.php
Normal file
@ -0,0 +1,33 @@
|
||||
<?php
|
||||
|
||||
namespace Crater\Http\Requests;
|
||||
|
||||
use Illuminate\Foundation\Http\FormRequest;
|
||||
|
||||
class GetSettingRequest extends FormRequest
|
||||
{
|
||||
/**
|
||||
* Determine if the user is authorized to make this request.
|
||||
*
|
||||
* @return bool
|
||||
*/
|
||||
public function authorize()
|
||||
{
|
||||
return true;
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the validation rules that apply to the request.
|
||||
*
|
||||
* @return array
|
||||
*/
|
||||
public function rules()
|
||||
{
|
||||
return [
|
||||
'key' => [
|
||||
'required',
|
||||
'string'
|
||||
]
|
||||
];
|
||||
}
|
||||
}
|
||||
@ -2,6 +2,7 @@
|
||||
|
||||
namespace Crater\Http\Requests;
|
||||
|
||||
use Crater\Models\PaymentMethod;
|
||||
use Illuminate\Foundation\Http\FormRequest;
|
||||
use Illuminate\Validation\Rule;
|
||||
|
||||
@ -43,4 +44,14 @@ class PaymentMethodRequest extends FormRequest
|
||||
|
||||
return $data;
|
||||
}
|
||||
|
||||
public function getPaymentMethodPayload()
|
||||
{
|
||||
return collect($this->validated())
|
||||
->merge([
|
||||
'company_id' => $this->header('company'),
|
||||
'type' => PaymentMethod::TYPE_GENERAL,
|
||||
])
|
||||
->toArray();
|
||||
}
|
||||
}
|
||||
|
||||
@ -24,10 +24,7 @@ class SettingRequest extends FormRequest
|
||||
public function rules()
|
||||
{
|
||||
return [
|
||||
'key' => [
|
||||
'required',
|
||||
],
|
||||
'value' => [
|
||||
'settings' => [
|
||||
'required',
|
||||
],
|
||||
];
|
||||
|
||||
@ -2,6 +2,7 @@
|
||||
|
||||
namespace Crater\Http\Requests;
|
||||
|
||||
use Crater\Models\TaxType;
|
||||
use Illuminate\Foundation\Http\FormRequest;
|
||||
use Illuminate\Validation\Rule;
|
||||
|
||||
@ -28,6 +29,7 @@ class TaxTypeRequest extends FormRequest
|
||||
'name' => [
|
||||
'required',
|
||||
Rule::unique('tax_types')
|
||||
->where('type', TaxType::TYPE_GENERAL)
|
||||
->where('company_id', $this->header('company'))
|
||||
],
|
||||
'percent' => [
|
||||
@ -49,6 +51,7 @@ class TaxTypeRequest extends FormRequest
|
||||
'required',
|
||||
Rule::unique('tax_types')
|
||||
->ignore($this->route('tax_type')->id)
|
||||
->where('type', TaxType::TYPE_GENERAL)
|
||||
->where('company_id', $this->header('company'))
|
||||
];
|
||||
}
|
||||
@ -60,7 +63,8 @@ class TaxTypeRequest extends FormRequest
|
||||
{
|
||||
return collect($this->validated())
|
||||
->merge([
|
||||
'company_id' => $this->header('company')
|
||||
'company_id' => $this->header('company'),
|
||||
'type' => TaxType::TYPE_GENERAL
|
||||
])
|
||||
->toArray();
|
||||
}
|
||||
|
||||
37
app/Http/Requests/UnzipUpdateRequest.php
Normal file
37
app/Http/Requests/UnzipUpdateRequest.php
Normal file
@ -0,0 +1,37 @@
|
||||
<?php
|
||||
|
||||
namespace Crater\Http\Requests;
|
||||
|
||||
use Illuminate\Foundation\Http\FormRequest;
|
||||
|
||||
class UnzipUpdateRequest extends FormRequest
|
||||
{
|
||||
/**
|
||||
* Determine if the user is authorized to make this request.
|
||||
*
|
||||
* @return bool
|
||||
*/
|
||||
public function authorize()
|
||||
{
|
||||
return true;
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the validation rules that apply to the request.
|
||||
*
|
||||
* @return array
|
||||
*/
|
||||
public function rules()
|
||||
{
|
||||
return [
|
||||
'path' => [
|
||||
'required',
|
||||
'regex:/^[\.\/\w\-]+$/'
|
||||
],
|
||||
'module' => [
|
||||
'required',
|
||||
'string'
|
||||
]
|
||||
];
|
||||
}
|
||||
}
|
||||
34
app/Http/Requests/UploadExpenseReceiptRequest.php
Normal file
34
app/Http/Requests/UploadExpenseReceiptRequest.php
Normal file
@ -0,0 +1,34 @@
|
||||
<?php
|
||||
|
||||
namespace Crater\Http\Requests;
|
||||
|
||||
use Crater\Rules\Base64Mime;
|
||||
use Illuminate\Foundation\Http\FormRequest;
|
||||
|
||||
class UploadExpenseReceiptRequest extends FormRequest
|
||||
{
|
||||
/**
|
||||
* Determine if the user is authorized to make this request.
|
||||
*
|
||||
* @return bool
|
||||
*/
|
||||
public function authorize()
|
||||
{
|
||||
return true;
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the validation rules that apply to the request.
|
||||
*
|
||||
* @return array
|
||||
*/
|
||||
public function rules()
|
||||
{
|
||||
return [
|
||||
'attachment_receipt' => [
|
||||
'nullable',
|
||||
new Base64Mime(['gif', 'jpg', 'png'])
|
||||
]
|
||||
];
|
||||
}
|
||||
}
|
||||
40
app/Http/Requests/UploadModuleRequest.php
Normal file
40
app/Http/Requests/UploadModuleRequest.php
Normal file
@ -0,0 +1,40 @@
|
||||
<?php
|
||||
|
||||
namespace Crater\Http\Requests;
|
||||
|
||||
use Illuminate\Foundation\Http\FormRequest;
|
||||
|
||||
class UploadModuleRequest extends FormRequest
|
||||
{
|
||||
/**
|
||||
* Determine if the user is authorized to make this request.
|
||||
*
|
||||
* @return bool
|
||||
*/
|
||||
public function authorize()
|
||||
{
|
||||
return true;
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the validation rules that apply to the request.
|
||||
*
|
||||
* @return array
|
||||
*/
|
||||
public function rules()
|
||||
{
|
||||
return [
|
||||
'avatar' => [
|
||||
'required',
|
||||
'file',
|
||||
'mimes:zip',
|
||||
'max:20000'
|
||||
],
|
||||
'module' => [
|
||||
'required',
|
||||
'string',
|
||||
'max:100'
|
||||
]
|
||||
];
|
||||
}
|
||||
}
|
||||
@ -21,6 +21,7 @@ class CompanyResource extends JsonResource
|
||||
'logo_path' => $this->logo_path,
|
||||
'unique_hash' => $this->unique_hash,
|
||||
'owner_id' => $this->owner_id,
|
||||
'slug' => $this->slug,
|
||||
'address' => $this->when($this->address()->exists(), function () {
|
||||
return new AddressResource($this->address);
|
||||
}),
|
||||
|
||||
@ -2,6 +2,7 @@
|
||||
|
||||
namespace Crater\Http\Resources;
|
||||
|
||||
use Crater\Models\CompanySetting;
|
||||
use Illuminate\Http\Resources\Json\JsonResource;
|
||||
|
||||
class CustomFieldValueResource extends JsonResource
|
||||
@ -28,6 +29,7 @@ class CustomFieldValueResource extends JsonResource
|
||||
'custom_field_id' => $this->custom_field_id,
|
||||
'company_id' => $this->company_id,
|
||||
'default_answer' => $this->defaultAnswer,
|
||||
'default_formatted_answer' => $this->dateTimeFormat(),
|
||||
'custom_field' => $this->when($this->customField()->exists(), function () {
|
||||
return new CustomFieldResource($this->customField);
|
||||
}),
|
||||
@ -36,4 +38,24 @@ class CustomFieldValueResource extends JsonResource
|
||||
}),
|
||||
];
|
||||
}
|
||||
|
||||
public function dateTimeFormat()
|
||||
{
|
||||
$key = getCustomFieldValueKey($this->type);
|
||||
|
||||
$answer = $this->default_answer;
|
||||
if (! $answer) {
|
||||
return null;
|
||||
}
|
||||
|
||||
if ($key == 'date_time_answer') {
|
||||
return $answer->format('Y-m-d H:i');
|
||||
}
|
||||
|
||||
if ($key == 'date_answer') {
|
||||
return $answer->format(CompanySetting::getSetting('carbon_date_format', $this->company_id));
|
||||
}
|
||||
|
||||
return $answer;
|
||||
}
|
||||
}
|
||||
|
||||
19
app/Http/Resources/Customer/AddressCollection.php
Normal file
19
app/Http/Resources/Customer/AddressCollection.php
Normal file
@ -0,0 +1,19 @@
|
||||
<?php
|
||||
|
||||
namespace Crater\Http\Resources\Customer;
|
||||
|
||||
use Illuminate\Http\Resources\Json\ResourceCollection;
|
||||
|
||||
class AddressCollection extends ResourceCollection
|
||||
{
|
||||
/**
|
||||
* Transform the resource collection into an array.
|
||||
*
|
||||
* @param \Illuminate\Http\Request $request
|
||||
* @return array
|
||||
*/
|
||||
public function toArray($request)
|
||||
{
|
||||
return parent::toArray($request);
|
||||
}
|
||||
}
|
||||
40
app/Http/Resources/Customer/AddressResource.php
Normal file
40
app/Http/Resources/Customer/AddressResource.php
Normal file
@ -0,0 +1,40 @@
|
||||
<?php
|
||||
|
||||
namespace Crater\Http\Resources\Customer;
|
||||
|
||||
use Illuminate\Http\Resources\Json\JsonResource;
|
||||
|
||||
class AddressResource extends JsonResource
|
||||
{
|
||||
/**
|
||||
* Transform the resource into an array.
|
||||
*
|
||||
* @param \Illuminate\Http\Request $request
|
||||
* @return array
|
||||
*/
|
||||
public function toArray($request)
|
||||
{
|
||||
return [
|
||||
'id' => $this->id,
|
||||
'name' => $this->name,
|
||||
'address_street_1' => $this->address_street_1,
|
||||
'address_street_2' => $this->address_street_2,
|
||||
'city' => $this->city,
|
||||
'state' => $this->state,
|
||||
'country_id' => $this->country_id,
|
||||
'zip' => $this->zip,
|
||||
'phone' => $this->phone,
|
||||
'fax' => $this->fax,
|
||||
'type' => $this->type,
|
||||
'user_id' => $this->user_id,
|
||||
'company_id' => $this->company_id,
|
||||
'customer_id' => $this->customer_id,
|
||||
'country' => $this->when($this->country()->exists(), function () {
|
||||
return new CountryResource($this->country);
|
||||
}),
|
||||
'user' => $this->when($this->user()->exists(), function () {
|
||||
return new UserResource($this->user);
|
||||
}),
|
||||
];
|
||||
}
|
||||
}
|
||||
30
app/Http/Resources/Customer/CompanyResource.php
Normal file
30
app/Http/Resources/Customer/CompanyResource.php
Normal file
@ -0,0 +1,30 @@
|
||||
<?php
|
||||
|
||||
namespace Crater\Http\Resources\Customer;
|
||||
|
||||
use Illuminate\Http\Resources\Json\JsonResource;
|
||||
|
||||
class CompanyResource extends JsonResource
|
||||
{
|
||||
/**
|
||||
* Transform the resource into an array.
|
||||
*
|
||||
* @param \Illuminate\Http\Request $request
|
||||
* @return array
|
||||
*/
|
||||
public function toArray($request)
|
||||
{
|
||||
return [
|
||||
'id' => $this->id,
|
||||
'name' => $this->name,
|
||||
'slug' => $this->slug,
|
||||
'logo' => $this->logo,
|
||||
'logo_path' => $this->logo_path,
|
||||
'unique_hash' => $this->unique_hash,
|
||||
'owner_id' => $this->owner_id,
|
||||
'address' => $this->when($this->address()->exists(), function () {
|
||||
return new AddressResource($this->address);
|
||||
}),
|
||||
];
|
||||
}
|
||||
}
|
||||
19
app/Http/Resources/Customer/CountryCollection.php
Normal file
19
app/Http/Resources/Customer/CountryCollection.php
Normal file
@ -0,0 +1,19 @@
|
||||
<?php
|
||||
|
||||
namespace Crater\Http\Resources\Customer;
|
||||
|
||||
use Illuminate\Http\Resources\Json\ResourceCollection;
|
||||
|
||||
class CountryCollection extends ResourceCollection
|
||||
{
|
||||
/**
|
||||
* Transform the resource collection into an array.
|
||||
*
|
||||
* @param \Illuminate\Http\Request $request
|
||||
* @return array
|
||||
*/
|
||||
public function toArray($request)
|
||||
{
|
||||
return parent::toArray($request);
|
||||
}
|
||||
}
|
||||
24
app/Http/Resources/Customer/CountryResource.php
Normal file
24
app/Http/Resources/Customer/CountryResource.php
Normal file
@ -0,0 +1,24 @@
|
||||
<?php
|
||||
|
||||
namespace Crater\Http\Resources\Customer;
|
||||
|
||||
use Illuminate\Http\Resources\Json\JsonResource;
|
||||
|
||||
class CountryResource extends JsonResource
|
||||
{
|
||||
/**
|
||||
* Transform the resource into an array.
|
||||
*
|
||||
* @param \Illuminate\Http\Request $request
|
||||
* @return array
|
||||
*/
|
||||
public function toArray($request)
|
||||
{
|
||||
return [
|
||||
'id' => $this->id,
|
||||
'code' => $this->code,
|
||||
'name' => $this->name,
|
||||
'phonecode' => $this->phonecode,
|
||||
];
|
||||
}
|
||||
}
|
||||
19
app/Http/Resources/Customer/CurrencyCollection.php
Normal file
19
app/Http/Resources/Customer/CurrencyCollection.php
Normal file
@ -0,0 +1,19 @@
|
||||
<?php
|
||||
|
||||
namespace Crater\Http\Resources\Customer;
|
||||
|
||||
use Illuminate\Http\Resources\Json\ResourceCollection;
|
||||
|
||||
class CurrencyCollection extends ResourceCollection
|
||||
{
|
||||
/**
|
||||
* Transform the resource collection into an array.
|
||||
*
|
||||
* @param \Illuminate\Http\Request $request
|
||||
* @return array
|
||||
*/
|
||||
public function toArray($request)
|
||||
{
|
||||
return parent::toArray($request);
|
||||
}
|
||||
}
|
||||
29
app/Http/Resources/Customer/CurrencyResource.php
Normal file
29
app/Http/Resources/Customer/CurrencyResource.php
Normal file
@ -0,0 +1,29 @@
|
||||
<?php
|
||||
|
||||
namespace Crater\Http\Resources\Customer;
|
||||
|
||||
use Illuminate\Http\Resources\Json\JsonResource;
|
||||
|
||||
class CurrencyResource extends JsonResource
|
||||
{
|
||||
/**
|
||||
* Transform the resource into an array.
|
||||
*
|
||||
* @param \Illuminate\Http\Request $request
|
||||
* @return array
|
||||
*/
|
||||
public function toArray($request)
|
||||
{
|
||||
return [
|
||||
'id' => $this->id,
|
||||
'name' => $this->name,
|
||||
'code' => $this->code,
|
||||
'symbol' => $this->symbol,
|
||||
'precision' => $this->precision,
|
||||
'thousand_separator' => $this->thousand_separator,
|
||||
'decimal_separator' => $this->decimal_separator,
|
||||
'swap_currency_symbol' => $this->swap_currency_symbol,
|
||||
'exchange_rate' => $this->exchange_rate
|
||||
];
|
||||
}
|
||||
}
|
||||
19
app/Http/Resources/Customer/CustomFieldCollection.php
Normal file
19
app/Http/Resources/Customer/CustomFieldCollection.php
Normal file
@ -0,0 +1,19 @@
|
||||
<?php
|
||||
|
||||
namespace Crater\Http\Resources\Customer;
|
||||
|
||||
use Illuminate\Http\Resources\Json\ResourceCollection;
|
||||
|
||||
class CustomFieldCollection extends ResourceCollection
|
||||
{
|
||||
/**
|
||||
* Transform the resource collection into an array.
|
||||
*
|
||||
* @param \Illuminate\Http\Request $request
|
||||
* @return array
|
||||
*/
|
||||
public function toArray($request)
|
||||
{
|
||||
return parent::toArray($request);
|
||||
}
|
||||
}
|
||||
42
app/Http/Resources/Customer/CustomFieldResource.php
Normal file
42
app/Http/Resources/Customer/CustomFieldResource.php
Normal file
@ -0,0 +1,42 @@
|
||||
<?php
|
||||
|
||||
namespace Crater\Http\Resources\Customer;
|
||||
|
||||
use Illuminate\Http\Resources\Json\JsonResource;
|
||||
|
||||
class CustomFieldResource extends JsonResource
|
||||
{
|
||||
/**
|
||||
* Transform the resource into an array.
|
||||
*
|
||||
* @param \Illuminate\Http\Request $request
|
||||
* @return array
|
||||
*/
|
||||
public function toArray($request)
|
||||
{
|
||||
return [
|
||||
'id' => $this->id,
|
||||
'name' => $this->name,
|
||||
'slug' => $this->slug,
|
||||
'label' => $this->label,
|
||||
'model_type' => $this->model_type,
|
||||
'type' => $this->type,
|
||||
'placeholder' => $this->placeholder,
|
||||
'options' => $this->options,
|
||||
'boolean_answer' => $this->boolean_answer,
|
||||
'date_answer' => $this->date_answer,
|
||||
'time_answer' => $this->time_answer,
|
||||
'string_answer' => $this->string_answer,
|
||||
'number_answer' => $this->number_answer,
|
||||
'date_time_answer' => $this->date_time_answer,
|
||||
'is_required' => $this->is_required,
|
||||
'in_use' => $this->in_use,
|
||||
'order' => $this->order,
|
||||
'company_id' => $this->company_id,
|
||||
'default_answer' => $this->default_answer,
|
||||
'company' => $this->when($this->company()->exists(), function () {
|
||||
return new CompanyResource($this->company);
|
||||
}),
|
||||
];
|
||||
}
|
||||
}
|
||||
19
app/Http/Resources/Customer/CustomFieldValueCollection.php
Normal file
19
app/Http/Resources/Customer/CustomFieldValueCollection.php
Normal file
@ -0,0 +1,19 @@
|
||||
<?php
|
||||
|
||||
namespace Crater\Http\Resources\Customer;
|
||||
|
||||
use Illuminate\Http\Resources\Json\ResourceCollection;
|
||||
|
||||
class CustomFieldValueCollection extends ResourceCollection
|
||||
{
|
||||
/**
|
||||
* Transform the resource collection into an array.
|
||||
*
|
||||
* @param \Illuminate\Http\Request $request
|
||||
* @return array
|
||||
*/
|
||||
public function toArray($request)
|
||||
{
|
||||
return parent::toArray($request);
|
||||
}
|
||||
}
|
||||
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user