Compare commits
10 commits
c9e1545693
...
ca3eb663fe
| Author | SHA1 | Date | |
|---|---|---|---|
| ca3eb663fe | |||
| 9ce711d6b2 | |||
|
|
02f2a4c23e | ||
|
|
9b54eb0512 | ||
|
|
6167273a48 | ||
|
|
a0f4eda6ea | ||
|
|
38e7fd504a | ||
|
|
3f1fb9377d | ||
|
|
570d428b1c | ||
|
|
1cc8e025a1 |
792 changed files with 92035 additions and 24475 deletions
18
.cursor/mcp.json
Normal file
18
.cursor/mcp.json
Normal file
|
|
@ -0,0 +1,18 @@
|
|||
{
|
||||
"mcpServers": {
|
||||
"laravel-boost": {
|
||||
"command": "php",
|
||||
"args": [
|
||||
"artisan",
|
||||
"boost:mcp"
|
||||
]
|
||||
},
|
||||
"sequential-thinking": {
|
||||
"command": "npx",
|
||||
"args": [
|
||||
"-y",
|
||||
"@modelcontextprotocol/server-sequential-thinking"
|
||||
]
|
||||
}
|
||||
}
|
||||
}
|
||||
248
.cursor/rules/laravel-boost.mdc
Normal file
248
.cursor/rules/laravel-boost.mdc
Normal file
|
|
@ -0,0 +1,248 @@
|
|||
---
|
||||
alwaysApply: true
|
||||
---
|
||||
<laravel-boost-guidelines>
|
||||
=== foundation rules ===
|
||||
|
||||
# Laravel Boost Guidelines
|
||||
|
||||
The Laravel Boost guidelines are specifically curated by Laravel maintainers for this application. These guidelines should be followed closely to enhance the user's satisfaction building Laravel applications.
|
||||
|
||||
## Foundational Context
|
||||
This application is a Laravel application and its main Laravel ecosystems package & versions are below. You are an expert with them all. Ensure you abide by these specific packages & versions.
|
||||
|
||||
- php - 8.4.1
|
||||
- laravel/framework (LARAVEL) - v11
|
||||
- laravel/prompts (PROMPTS) - v0
|
||||
- laravel/pint (PINT) - v1
|
||||
- pestphp/pest (PEST) - v2
|
||||
|
||||
|
||||
## Conventions
|
||||
- You must follow all existing code conventions used in this application. When creating or editing a file, check sibling files for the correct structure, approach, naming.
|
||||
- Use descriptive names for variables and methods. For example, `isRegisteredForDiscounts`, not `discount()`.
|
||||
- Check for existing components to reuse before writing a new one.
|
||||
|
||||
## Verification Scripts
|
||||
- Do not create verification scripts or tinker when tests cover that functionality and prove it works. Unit and feature tests are more important.
|
||||
|
||||
## Application Structure & Architecture
|
||||
- Stick to existing directory structure - don't create new base folders without approval.
|
||||
- Do not change the application's dependencies without approval.
|
||||
|
||||
## Frontend Bundling
|
||||
- If the user doesn't see a frontend change reflected in the UI, it could mean they need to run `npm run build`, `npm run dev`, or `composer run dev`. Ask them.
|
||||
|
||||
## Replies
|
||||
- Be concise in your explanations - focus on what's important rather than explaining obvious details.
|
||||
|
||||
## Documentation Files
|
||||
- You must only create documentation files if explicitly requested by the user.
|
||||
|
||||
|
||||
=== boost rules ===
|
||||
|
||||
## Laravel Boost
|
||||
- Laravel Boost is an MCP server that comes with powerful tools designed specifically for this application. Use them.
|
||||
|
||||
## Artisan
|
||||
- Use the `list-artisan-commands` tool when you need to call an Artisan command to double check the available parameters.
|
||||
|
||||
## URLs
|
||||
- Whenever you share a project URL with the user you should use the `get-absolute-url` tool to ensure you're using the correct scheme, domain / IP, and port.
|
||||
|
||||
## Tinker / Debugging
|
||||
- You should use the `tinker` tool when you need to execute PHP to debug code or query Eloquent models directly.
|
||||
- Use the `database-query` tool when you only need to read from the database.
|
||||
|
||||
## Reading Browser Logs With the `browser-logs` Tool
|
||||
- You can read browser logs, errors, and exceptions using the `browser-logs` tool from Boost.
|
||||
- Only recent browser logs will be useful - ignore old logs.
|
||||
|
||||
## Searching Documentation (Critically Important)
|
||||
- Boost comes with a powerful `search-docs` tool you should use before any other approaches. This tool automatically passes a list of installed packages and their versions to the remote Boost API, so it returns only version-specific documentation specific for the user's circumstance. You should pass an array of packages to filter on if you know you need docs for particular packages.
|
||||
- The 'search-docs' tool is perfect for all Laravel related packages, including Laravel, Inertia, Livewire, Filament, Tailwind, Pest, Nova, Nightwatch, etc.
|
||||
- You must use this tool to search for Laravel-ecosystem documentation before falling back to other approaches.
|
||||
- Search the documentation before making code changes to ensure we are taking the correct approach.
|
||||
- Use multiple, broad, simple, topic based queries to start. For example: `['rate limiting', 'routing rate limiting', 'routing']`.
|
||||
- Do not add package names to queries - package information is already shared. For example, use `test resource table`, not `filament 4 test resource table`.
|
||||
|
||||
### Available Search Syntax
|
||||
- You can and should pass multiple queries at once. The most relevant results will be returned first.
|
||||
|
||||
1. Simple Word Searches with auto-stemming - query=authentication - finds 'authenticate' and 'auth'
|
||||
2. Multiple Words (AND Logic) - query=rate limit - finds knowledge containing both "rate" AND "limit"
|
||||
3. Quoted Phrases (Exact Position) - query="infinite scroll" - Words must be adjacent and in that order
|
||||
4. Mixed Queries - query=middleware "rate limit" - "middleware" AND exact phrase "rate limit"
|
||||
5. Multiple Queries - queries=["authentication", "middleware"] - ANY of these terms
|
||||
|
||||
|
||||
=== php rules ===
|
||||
|
||||
## PHP
|
||||
|
||||
- Always use curly braces for control structures, even if it has one line.
|
||||
|
||||
### Constructors
|
||||
- Use PHP 8 constructor property promotion in `__construct()`.
|
||||
- <code-snippet>public function __construct(public GitHub $github) { }</code-snippet>
|
||||
- Do not allow empty `__construct()` methods with zero parameters.
|
||||
|
||||
### Type Declarations
|
||||
- Always use explicit return type declarations for methods and functions.
|
||||
- Use appropriate PHP type hints for method parameters.
|
||||
|
||||
<code-snippet name="Explicit Return Types and Method Params" lang="php">
|
||||
protected function isAccessible(User $user, ?string $path = null): bool
|
||||
{
|
||||
...
|
||||
}
|
||||
</code-snippet>
|
||||
|
||||
## Comments
|
||||
- Prefer PHPDoc blocks over comments. Never use comments within the code itself unless there is something _very_ complex going on.
|
||||
|
||||
## PHPDoc Blocks
|
||||
- Add useful array shape type definitions for arrays when appropriate.
|
||||
|
||||
## Enums
|
||||
- Typically, keys in an Enum should be TitleCase. For example: `FavoritePerson`, `BestLake`, `Monthly`.
|
||||
|
||||
|
||||
=== laravel/core rules ===
|
||||
|
||||
## Do Things the Laravel Way
|
||||
|
||||
- Use `php artisan make:` commands to create new files (i.e. migrations, controllers, models, etc.). You can list available Artisan commands using the `list-artisan-commands` tool.
|
||||
- If you're creating a generic PHP class, use `artisan make:class`.
|
||||
- Pass `--no-interaction` to all Artisan commands to ensure they work without user input. You should also pass the correct `--options` to ensure correct behavior.
|
||||
|
||||
### Database
|
||||
- Always use proper Eloquent relationship methods with return type hints. Prefer relationship methods over raw queries or manual joins.
|
||||
- Use Eloquent models and relationships before suggesting raw database queries
|
||||
- Avoid `DB::`; prefer `Model::query()`. Generate code that leverages Laravel's ORM capabilities rather than bypassing them.
|
||||
- Generate code that prevents N+1 query problems by using eager loading.
|
||||
- Use Laravel's query builder for very complex database operations.
|
||||
|
||||
### Model Creation
|
||||
- When creating new models, create useful factories and seeders for them too. Ask the user if they need any other things, using `list-artisan-commands` to check the available options to `php artisan make:model`.
|
||||
|
||||
### APIs & Eloquent Resources
|
||||
- For APIs, default to using Eloquent API Resources and API versioning unless existing API routes do not, then you should follow existing application convention.
|
||||
|
||||
### Controllers & Validation
|
||||
- Always create Form Request classes for validation rather than inline validation in controllers. Include both validation rules and custom error messages.
|
||||
- Check sibling Form Requests to see if the application uses array or string based validation rules.
|
||||
|
||||
### Queues
|
||||
- Use queued jobs for time-consuming operations with the `ShouldQueue` interface.
|
||||
|
||||
### Authentication & Authorization
|
||||
- Use Laravel's built-in authentication and authorization features (gates, policies, Sanctum, etc.).
|
||||
|
||||
### URL Generation
|
||||
- When generating links to other pages, prefer named routes and the `route()` function.
|
||||
|
||||
### Configuration
|
||||
- Use environment variables only in configuration files - never use the `env()` function directly outside of config files. Always use `config('app.name')`, not `env('APP_NAME')`.
|
||||
|
||||
### Testing
|
||||
- When creating models for tests, use the factories for the models. Check if the factory has custom states that can be used before manually setting up the model.
|
||||
- Faker: Use methods such as `$this->faker->word()` or `fake()->randomDigit()`. Follow existing conventions whether to use `$this->faker` or `fake()`.
|
||||
- When creating tests, make use of `php artisan make:test [options] <name>` to create a feature test, and pass `--unit` to create a unit test. Most tests should be feature tests.
|
||||
|
||||
### Vite Error
|
||||
- If you receive an "Illuminate\Foundation\ViteException: Unable to locate file in Vite manifest" error, you can run `npm run build` or ask the user to run `npm run dev` or `composer run dev`.
|
||||
|
||||
|
||||
=== laravel/v11 rules ===
|
||||
|
||||
## Laravel 11
|
||||
|
||||
- Use the `search-docs` tool to get version specific documentation.
|
||||
- This project upgraded from Laravel 10 without migrating to the new streamlined Laravel 11 file structure.
|
||||
- This is **perfectly fine** and recommended by Laravel. Follow the existing structure from Laravel 10. We do not to need migrate to the Laravel 11 structure unless the user explicitly requests that.
|
||||
|
||||
### Laravel 10 Structure
|
||||
- Middleware typically live in `app/Http/Middleware/` and service providers in `app/Providers/`.
|
||||
- There is no `bootstrap/app.php` application configuration in a Laravel 10 structure:
|
||||
- Middleware registration is in `app/Http/Kernel.php`
|
||||
- Exception handling is in `app/Exceptions/Handler.php`
|
||||
- Console commands and schedule registration is in `app/Console/Kernel.php`
|
||||
- Rate limits likely exist in `RouteServiceProvider` or `app/Http/Kernel.php`
|
||||
|
||||
### Database
|
||||
- When modifying a column, the migration must include all of the attributes that were previously defined on the column. Otherwise, they will be dropped and lost.
|
||||
- Laravel 11 allows limiting eagerly loaded records natively, without external packages: `$query->latest()->limit(10);`.
|
||||
|
||||
### Models
|
||||
- Casts can and likely should be set in a `casts()` method on a model rather than the `$casts` property. Follow existing conventions from other models.
|
||||
|
||||
### New Artisan Commands
|
||||
- List Artisan commands using Boost's MCP tool, if available. New commands available in Laravel 11:
|
||||
- `php artisan make:enum`
|
||||
- `php artisan make:class`
|
||||
- `php artisan make:interface`
|
||||
|
||||
|
||||
=== pint/core rules ===
|
||||
|
||||
## Laravel Pint Code Formatter
|
||||
|
||||
- You must run `vendor/bin/pint --dirty` before finalizing changes to ensure your code matches the project's expected style.
|
||||
- Do not run `vendor/bin/pint --test`, simply run `vendor/bin/pint` to fix any formatting issues.
|
||||
|
||||
|
||||
=== pest/core rules ===
|
||||
|
||||
## Pest
|
||||
|
||||
### Testing
|
||||
- If you need to verify a feature is working, write or update a Unit / Feature test.
|
||||
|
||||
### Pest Tests
|
||||
- All tests must be written using Pest. Use `php artisan make:test --pest <name>`.
|
||||
- You must not remove any tests or test files from the tests directory without approval. These are not temporary or helper files - these are core to the application.
|
||||
- Tests should test all of the happy paths, failure paths, and weird paths.
|
||||
- Tests live in the `tests/Feature` and `tests/Unit` directories.
|
||||
- Pest tests look and behave like this:
|
||||
<code-snippet name="Basic Pest Test Example" lang="php">
|
||||
it('is true', function () {
|
||||
expect(true)->toBeTrue();
|
||||
});
|
||||
</code-snippet>
|
||||
|
||||
### Running Tests
|
||||
- Run the minimal number of tests using an appropriate filter before finalizing code edits.
|
||||
- To run all tests: `php artisan test`.
|
||||
- To run all tests in a file: `php artisan test tests/Feature/ExampleTest.php`.
|
||||
- To filter on a particular test name: `php artisan test --filter=testName` (recommended after making a change to a related file).
|
||||
- When the tests relating to your changes are passing, ask the user if they would like to run the entire test suite to ensure everything is still passing.
|
||||
|
||||
### Pest Assertions
|
||||
- When asserting status codes on a response, use the specific method like `assertForbidden` and `assertNotFound` instead of using `assertStatus(403)` or similar, e.g.:
|
||||
<code-snippet name="Pest Example Asserting postJson Response" lang="php">
|
||||
it('returns all', function () {
|
||||
$response = $this->postJson('/api/docs', []);
|
||||
|
||||
$response->assertSuccessful();
|
||||
});
|
||||
</code-snippet>
|
||||
|
||||
### Mocking
|
||||
- Mocking can be very helpful when appropriate.
|
||||
- When mocking, you can use the `Pest\Laravel\mock` Pest function, but always import it via `use function Pest\Laravel\mock;` before using it. Alternatively, you can use `$this->mock()` if existing tests do.
|
||||
- You can also create partial mocks using the same import or self method.
|
||||
|
||||
### Datasets
|
||||
- Use datasets in Pest to simplify tests which have a lot of duplicated data. This is often the case when testing validation rules, so consider going with this solution when writing tests for validation rules.
|
||||
|
||||
<code-snippet name="Pest Dataset Example" lang="php">
|
||||
it('has emails', function (string $email) {
|
||||
expect($email)->not->toBeEmpty();
|
||||
})->with([
|
||||
'james' => 'james@laravel.com',
|
||||
'taylor' => 'taylor@laravel.com',
|
||||
]);
|
||||
</code-snippet>
|
||||
</laravel-boost-guidelines>
|
||||
45
.devcontainer/devcontainer.json
Normal file
45
.devcontainer/devcontainer.json
Normal file
|
|
@ -0,0 +1,45 @@
|
|||
{
|
||||
"name": "Partner Grüne Seele (Dev Container)",
|
||||
"dockerComposeFile": [
|
||||
"../docker-compose.yml"
|
||||
],
|
||||
"service": "laravel.test",
|
||||
"workspaceFolder": "/var/www/html",
|
||||
"remoteUser": "sail",
|
||||
"features": {},
|
||||
"customizations": {
|
||||
"vscode": {
|
||||
"extensions": [
|
||||
"bmewburn.vscode-intelephense-client",
|
||||
"onecentlin.laravel-blade",
|
||||
"shufo.vscode-blade-formatter",
|
||||
"bradlc.vscode-tailwindcss",
|
||||
"Anthropic.claude-code",
|
||||
"onecentlin.laravel-extension-pack"
|
||||
]
|
||||
}
|
||||
},
|
||||
// WICHTIG: Nur noch den Haupt-Container starten!
|
||||
"runServices": [
|
||||
"laravel.test"
|
||||
],
|
||||
"containerEnv": {
|
||||
"WWWUSER": "501",
|
||||
"WWWGROUP": "20",
|
||||
"LARAVEL_SAIL": "1"
|
||||
},
|
||||
"mounts": [
|
||||
"source=${localWorkspaceFolder},target=/var/www/html,type=bind,consistency=cached",
|
||||
"source=/Users/pandora/Library/Mobile Documents/iCloud~md~obsidian/Documents/DEV-Vault/gruene-seele,target=/var/www/html/docs,type=bind",
|
||||
],
|
||||
// WICHTIG: Nur noch den Vite-Port weiterleiten
|
||||
"forwardPorts": [
|
||||
5179
|
||||
],
|
||||
"portsAttributes": {
|
||||
"5179": {
|
||||
"label": "Vite Dev Server",
|
||||
"onAutoForward": "notify"
|
||||
}
|
||||
}
|
||||
}
|
||||
68
.env
68
.env
|
|
@ -3,31 +3,39 @@ APP_ENV=local
|
|||
APP_KEY=base64:w0K6RjfleoAOpuICea14JnaZ28PNc6EMzIFMQZ3MVtU=
|
||||
APP_DEBUG=true
|
||||
APP_URL=https://partner.gruene-seele.test
|
||||
APP_API_DOMAIN=partner.gruene-seele.test
|
||||
APP_DOMAIN=partner.gruene-seele.test
|
||||
|
||||
APP_PROMO_URL=https://testemich.test
|
||||
APP_PROMO_DOMAIN=testemich.test
|
||||
|
||||
APP_CHECKOUT_MAIL=register@adametz.media
|
||||
APP_CHECKOUT_TEST_MAIL=register@adametz.media
|
||||
APP_INFO_MAIL=register@adametz.media
|
||||
APP_INFO_TEST_MAIL=register@adametz.media
|
||||
APP_SHOP_URL=https://grueneseele.test
|
||||
APP_SHOP_DOMAIN=grueneseele.test
|
||||
|
||||
APP_CHECKOUT_MAIL=kevin.adametz@me.com
|
||||
APP_CHECKOUT_TEST_MAIL=register@adametz.media
|
||||
APP_INFO_MAIL=kevin.adametz@me.com
|
||||
APP_INFO_TEST_MAIL=register@adametz.media
|
||||
EXCEPTION_MAIL=exception@adametz.media
|
||||
LOGISTIC_MAIL=kevin.adametz@me.com
|
||||
APP_MAIN_TAX = 1.19
|
||||
APP_MAIN_TAX_RATE = 19
|
||||
|
||||
APP_MAIN_USER_ID = 2
|
||||
|
||||
LOG_CHANNEL=stack
|
||||
LOG_LEVEL=debug
|
||||
|
||||
DB_CONNECTION=mysql
|
||||
DB_HOST=192.168.1.8
|
||||
DB_HOST=mysql
|
||||
DB_PORT=3306
|
||||
DB_DATABASE=grueneseele
|
||||
DB_USERNAME=kadmin
|
||||
DB_PASSWORD=KT32vQ7ix
|
||||
DB_DATABASE=partner_gruene_seele
|
||||
DB_USERNAME=root
|
||||
DB_PASSWORD=password
|
||||
|
||||
|
||||
#DB_CONNECTION=mysql
|
||||
#DB_HOST=localhost
|
||||
#DB_HOST=mysql
|
||||
#DB_PORT=3306
|
||||
#DB_DATABASE=web28_db4
|
||||
#DB_USERNAME=web28_4
|
||||
|
|
@ -43,16 +51,40 @@ MEMCACHED_HOST=127.0.0.1
|
|||
|
||||
REDIS_HOST=127.0.0.1
|
||||
REDIS_PASSWORD=null
|
||||
REDIS_PORT=6379
|
||||
REDIS_PORT=6384
|
||||
#REDIS_PORT=6379
|
||||
|
||||
MAIL_DRIVER=smtp
|
||||
MAIL_HOST=mailpit
|
||||
MAIL_PORT=1029
|
||||
|
||||
#MAIL_DRIVER=smtp
|
||||
#MAIL_HOST=w017e534.kasserver.com
|
||||
#MAIL_PORT=587
|
||||
#MAIL_USERNAME=m0496c96
|
||||
#MAIL_PASSWORD=mZtVp7WQcs6DC3hf
|
||||
#MAIL_ENCRYPTION=null
|
||||
#MAIL_FROM_ADDRESS=dev@adametz.media
|
||||
#MAIL_FROM_NAME="DEV Grüne Seele"
|
||||
|
||||
#MAIL_MAILER=smtp
|
||||
#MAIL_HOST=s182.goserver.host
|
||||
#MAIL_PORT=587
|
||||
#MAIL_USERNAME=web28p3
|
||||
#MAIL_PASSWORD=WeE2bmI9GjB7pDgi
|
||||
#MAIL_ENCRYPTION=""
|
||||
#MAIL_FROM_ADDRESS=partner@gruene-seele.bio
|
||||
#MAIL_FROM_NAME="GRÜNE SEELE Naturkosmetik"
|
||||
|
||||
RECAPTCHA_SITE_KEY="6LcGr_kqAAAAAOnz-L6IIBC_fTzJ7siTheZgFVMY"
|
||||
RECAPTCHA_SECRET_KEY="6LcGr_kqAAAAAKBZVoy37ski0Gl54jenWOlrbc9z"
|
||||
|
||||
PAYPAL_MODE=sandbox
|
||||
PAYPAL_SANDBOX_CLIENT_ID=AWMeW59cMOHaMWfv44kIMnzaR81Qo4yNVzEC5LyWl7x5RjkJZOJmvbvljqWPNEw7GihF3FLRL_tEJPHo
|
||||
PAYPAL_SANDBOX_CLIENT_SECRET=EFOuvQJpx3lM2HjLjPURgcxKuGLtKxNHKZqx65uQpQ8WNLDvijHhb79X5oE22LKIwW5V0GdX09jI24bF
|
||||
PAYPAL_LIVE_CLIENT_ID=ATBZUigDw1yuakQj9X7semskqBrBxSV3bOjp3AtHV5pCSc3tOIm1m2s3toUfGW9lcxQJ5_fSS37FVbki
|
||||
PAYPAL_LIVE_CLIENT_SECRET=ECCH1CPCiHLzEMbl3rMSo1PVSqn2iqu59t-ZUXSx4p1J_tTklpl9QGkBN77s9DfCA1dQ6u7VfBBfPApn
|
||||
|
||||
MAIL_MAILER=smtp
|
||||
MAIL_HOST=s182.goserver.host
|
||||
MAIL_PORT=587
|
||||
MAIL_USERNAME=web28p3
|
||||
MAIL_PASSWORD=WeE2bmI9GjB7pDgi
|
||||
MAIL_ENCRYPTION=""
|
||||
MAIL_FROM_ADDRESS=partner@gruene-seele.bio
|
||||
MAIL_FROM_NAME="Partner GRÜNE SEELE Naturkosmetik"
|
||||
|
||||
AWS_ACCESS_KEY_ID=
|
||||
AWS_SECRET_ACCESS_KEY=
|
||||
|
|
|
|||
27
.mcp.json
Normal file
27
.mcp.json
Normal file
|
|
@ -0,0 +1,27 @@
|
|||
{
|
||||
"mcpServers": {
|
||||
"laravel-boost": {
|
||||
"command": "php",
|
||||
"args": [
|
||||
"artisan",
|
||||
"boost:mcp"
|
||||
]
|
||||
},
|
||||
"context7": {
|
||||
"command": "npx",
|
||||
"args": [
|
||||
"-y",
|
||||
"@upstash/context7-mcp",
|
||||
"--api-key",
|
||||
"ctx7sk-119cd4ab-8983-4229-8702-e84c59c34fc9"
|
||||
]
|
||||
},
|
||||
"sequential-thinking": {
|
||||
"command": "npx",
|
||||
"args": [
|
||||
"-y",
|
||||
"@modelcontextprotocol/server-sequential-thinking"
|
||||
]
|
||||
}
|
||||
}
|
||||
}
|
||||
39
.php-cs-fixer.php
Normal file
39
.php-cs-fixer.php
Normal file
|
|
@ -0,0 +1,39 @@
|
|||
<?php
|
||||
|
||||
$finder = PhpCsFixer\Finder::create()
|
||||
->in([
|
||||
__DIR__ . '/app',
|
||||
__DIR__ . '/config',
|
||||
__DIR__ . '/database',
|
||||
__DIR__ . '/resources',
|
||||
__DIR__ . '/routes',
|
||||
__DIR__ . '/tests',
|
||||
])
|
||||
->name('*.php')
|
||||
->notName('*.blade.php')
|
||||
->ignoreDotFiles(true)
|
||||
->ignoreVCS(true);
|
||||
|
||||
return (new PhpCsFixer\Config())
|
||||
->setRules([
|
||||
'@PSR2' => true,
|
||||
'array_syntax' => ['syntax' => 'short'],
|
||||
'ordered_imports' => ['sort_algorithm' => 'alpha'],
|
||||
'no_unused_imports' => true,
|
||||
'not_operator_with_successor_space' => true,
|
||||
'trailing_comma_in_multiline' => true,
|
||||
'phpdoc_scalar' => true,
|
||||
'unary_operator_spaces' => true,
|
||||
'binary_operator_spaces' => true,
|
||||
'blank_line_before_statement' => [
|
||||
'statements' => ['break', 'continue', 'declare', 'return', 'throw', 'try'],
|
||||
],
|
||||
'phpdoc_single_line_var_spacing' => true,
|
||||
'phpdoc_var_without_name' => true,
|
||||
'method_argument_space' => [
|
||||
'on_multiline' => 'ensure_fully_multiline',
|
||||
'keep_multiple_spaces_after_comma' => true,
|
||||
],
|
||||
'single_trait_insert_per_statement' => true,
|
||||
])
|
||||
->setFinder($finder);
|
||||
4337
.phpstorm.meta.php
4337
.phpstorm.meta.php
File diff suppressed because it is too large
Load diff
85
CLAUDE.md
Normal file
85
CLAUDE.md
Normal file
|
|
@ -0,0 +1,85 @@
|
|||
# CLAUDE.md
|
||||
|
||||
This file provides guidance to Claude Code (claude.ai/code) when working with code in this repository.
|
||||
|
||||
## Project Overview
|
||||
|
||||
German-language MLM/direct-sales e-commerce platform for organic/natural products ("Gruene Seele" / Green Soul). Partners/distributors get personal whitelabel shops, earn commissions through a multi-level hierarchy, and manage orders, invoices, and promotions.
|
||||
|
||||
**Stack:** PHP 8.4, Laravel 11 (using Laravel 10 directory structure), Bootstrap 4, jQuery, Laravel Mix (webpack), MySQL, Laravel Passport (API auth).
|
||||
|
||||
## Common Commands
|
||||
|
||||
```bash
|
||||
# Tests (Pest v2, uses SQLite in-memory)
|
||||
php artisan test # run all tests
|
||||
php artisan test tests/Feature/ExampleTest.php # run single file
|
||||
php artisan test --filter=testName # filter by name
|
||||
|
||||
# Code formatting (Laravel Pint)
|
||||
vendor/bin/pint --dirty # format changed files only
|
||||
vendor/bin/pint # format all files
|
||||
composer format # alias for pint
|
||||
|
||||
# Frontend (Laravel Mix, NOT Vite)
|
||||
npm run dev # development build
|
||||
npm run prod # production build
|
||||
npm run watch # watch mode
|
||||
|
||||
# Artisan - always pass --no-interaction
|
||||
php artisan make:model Name --no-interaction
|
||||
php artisan make:test --pest Name --no-interaction
|
||||
```
|
||||
|
||||
## Architecture
|
||||
|
||||
### Multi-Domain Routing (`routes/web.php`)
|
||||
Three separate domain groups, each with distinct middleware:
|
||||
- **Main domain** (`config('app.domain')`) - admin panel + user dashboard
|
||||
- **Promo domain** (`config('app.promo_domain')`) - public promotion/microsite pages
|
||||
- **Shop domain** (`config('app.shop_domain')`) - public whitelabel shop
|
||||
|
||||
### Admin Access Levels (middleware in `app/Http/Middleware/`)
|
||||
- `CopyReader` - admin >= 1 (product/content management)
|
||||
- `Admin` - admin >= 7 (sales, customers, promotions)
|
||||
- `SuperAdmin` - admin >= 8 (users, shipping, settings)
|
||||
- `SysAdmin` - admin >= 9 (system tools, imports)
|
||||
|
||||
### Key Service Layer
|
||||
- **`app/Services/Yard.php`** + `app/Services/Yard/` - Custom shopping cart (extends forked Gloudemans Cart in `packages/digital-bird/shoppingcart/`). Handles shipping, tax, margins, commissions.
|
||||
- **`app/Services/Invoice.php`** - Invoice and cancellation invoice PDF generation (uses DomPDF)
|
||||
- **`app/Services/PaymentReminderService.php`** - Payment reminder logic with status progression
|
||||
- **`app/Services/Credit.php`** - User credit/balance management
|
||||
- **`app/Services/Stats/`** - Sales statistics
|
||||
|
||||
### Repository Pattern
|
||||
Business logic uses repositories in `app/Repositories/` (e.g., `CheckoutRepository`, `InvoiceRepository`, `CustomerRepository`). Controllers delegate to repositories and services.
|
||||
|
||||
### Local Packages
|
||||
`packages/digital-bird/shoppingcart/` - Forked `gloudemans/shoppingcart`, autoloaded via composer PSR-4 as `Gloudemans\Shoppingcart\`.
|
||||
|
||||
### Cron Jobs (`app/Console/Kernel.php`)
|
||||
- `payments:accounts` - Checks user account expiry, sends reminders (statuses 31/33/34/35), deactivates expired accounts
|
||||
- `payments:reminders` - Sends payment reminders for open invoices
|
||||
|
||||
### API (`routes/api.php`)
|
||||
No versioning. Passport-authenticated endpoints for WordPress integration (`/api/wp/*`) and auth (`/api/auth/*`).
|
||||
|
||||
### Global Helpers
|
||||
`app/helpers.php` (autoloaded) - URL helpers, formatting delegates to `App\Services\Util`.
|
||||
|
||||
### PDF Generation
|
||||
- `app/Libraries/InvoicePDF.php`, `ContractPDF.php` - FPDF/FPDI based
|
||||
- `app/Services/Invoice.php` - DomPDF based (Blade templates in `resources/views/pdf/`)
|
||||
|
||||
## Important Conventions
|
||||
|
||||
- This project uses **Laravel 10 directory structure** on Laravel 11. Do NOT migrate to Laravel 11 structure.
|
||||
- Middleware registration: `app/Http/Kernel.php`
|
||||
- Exception handling: `app/Exceptions/Handler.php`
|
||||
- Schedule: `app/Console/Kernel.php`
|
||||
- Default auth guard is `user` (not `web`), configured in `config/auth.php`
|
||||
- User model is `App\User` (not `App\Models\User`)
|
||||
- Views are Blade templates with Bootstrap 4 + jQuery DataTables
|
||||
- Always run `vendor/bin/pint --dirty` before finalizing changes
|
||||
- Countries supported: DE, FR, CH, NL (with reverse charge VAT handling)
|
||||
249
PAYMENT_REMINDER_CRON.md
Normal file
249
PAYMENT_REMINDER_CRON.md
Normal file
|
|
@ -0,0 +1,249 @@
|
|||
# Payment Reminder Cron-Job Einrichtung
|
||||
|
||||
## Übersicht
|
||||
|
||||
Der `PaymentsReminders` Command automatisiert das Senden von Zahlungserinnerungen basierend auf den konfigurierten Intervallen in der Datenbank.
|
||||
|
||||
## Command ausführen
|
||||
|
||||
```bash
|
||||
php artisan payments:reminders
|
||||
```
|
||||
|
||||
## Cron-Job Konfiguration
|
||||
|
||||
### 1. Crontab öffnen
|
||||
|
||||
```bash
|
||||
crontab -e
|
||||
```
|
||||
|
||||
### 2. Cron-Job hinzufügen
|
||||
|
||||
**Täglich um 9:00 Uhr:**
|
||||
|
||||
```bash
|
||||
0 9 * * * cd /path/to/your/project && php artisan payments:reminders >> /dev/null 2>&1
|
||||
```
|
||||
|
||||
**Stündlich:**
|
||||
|
||||
```bash
|
||||
0 * * * * cd /path/to/your/project && php artisan payments:reminders >> /dev/null 2>&1
|
||||
```
|
||||
|
||||
**Alle 6 Stunden:**
|
||||
|
||||
```bash
|
||||
0 */6 * * * cd /path/to/your/project && php artisan payments:reminders >> /dev/null 2>&1
|
||||
```
|
||||
|
||||
### 3. Cron-Job testen
|
||||
|
||||
```bash
|
||||
# Teste den Command manuell
|
||||
php artisan payments:reminders
|
||||
|
||||
# Prüfe die Logs
|
||||
tail -f storage/logs/laravel.log
|
||||
```
|
||||
|
||||
## Funktionsweise
|
||||
|
||||
### 1. Intervall-basierte Verarbeitung
|
||||
|
||||
- Der Command holt alle aktiven `PaymentReminder` aus der Datenbank
|
||||
- Gruppiert sie nach `clearingtype` (z.B. 'invoice', 'prepayment')
|
||||
- Verwendet das kleinste Intervall pro `clearingtype`
|
||||
|
||||
### 2. Zahlungsprüfung
|
||||
|
||||
- Sucht offene Zahlungen, die älter als das konfigurierte Intervall sind
|
||||
- Berücksichtigt nur die neueste Zahlung pro Bestellung
|
||||
- Prüft nur Live-Zahlungen (nicht Test)
|
||||
|
||||
### 3. Erinnerungslogik
|
||||
|
||||
- **Erste Erinnerung**: Nach X Tagen ab Bestelldatum
|
||||
- **Weitere Erinnerungen**: Nach Y Tagen ab letzter Erinnerung
|
||||
- Stoppt wenn alle konfigurierten Erinnerungen gesendet wurden
|
||||
|
||||
### 4. Automatische Aktionen
|
||||
|
||||
- E-Mail-Versand mit Platzhalter-Ersetzung
|
||||
- Optional: Bestellung auf "Storniert" setzen
|
||||
- Optional: Payment auf "non" Status setzen
|
||||
- Logging aller Aktivitäten
|
||||
|
||||
## Logging
|
||||
|
||||
### Command-Logs
|
||||
|
||||
```bash
|
||||
# Live-Logs während der Ausführung
|
||||
php artisan payments:reminders
|
||||
|
||||
# Beispiel-Output:
|
||||
RUN Command Payments Reminders: 15.12.2024 09:00
|
||||
=== STARTE PAYMENT REMINDERS ===
|
||||
Gefundene aktive PaymentReminder: 3
|
||||
Gefundene clearingtypes mit kleinsten Intervallen:
|
||||
- invoice: 7 Tage
|
||||
- prepayment: 3 Tage
|
||||
--- Verarbeite clearingtype: invoice mit Intervall: 7 Tage ---
|
||||
Suche Zahlungen vor: 08.12.2024 09:00:00
|
||||
Gefundene offene Zahlungen für invoice: 5
|
||||
Verarbeite Order ID: 12345, Created: 05.12.2024 10:30:00, Amount: 5000, Reminder: 0
|
||||
📧 Sende Erinnerung...
|
||||
✅ Erinnerung erfolgreich gesendet
|
||||
=== PAYMENT REMINDERS ABGESCHLOSSEN ===
|
||||
Ausführungszeit: 2.34 Sekunden
|
||||
Statistiken:
|
||||
- Gesamt verarbeitet: 5
|
||||
- Erinnerungen gesendet: 3
|
||||
- Fehler: 0
|
||||
- Übersprungen: 2
|
||||
```
|
||||
|
||||
### Laravel-Logs
|
||||
|
||||
```bash
|
||||
# Logs in storage/logs/laravel.log
|
||||
tail -f storage/logs/laravel.log | grep "Payment reminder"
|
||||
```
|
||||
|
||||
## Konfiguration
|
||||
|
||||
### PaymentReminder Einstellungen
|
||||
|
||||
```sql
|
||||
-- Beispiel-Konfiguration
|
||||
INSERT INTO payment_reminders (clearingtype, interval, subject, message, action, active) VALUES
|
||||
('invoice', 7, 'Zahlungserinnerung - Bestellung {order_number}', 'Sehr geehrte/r {billing_first_name}...', NULL, 1),
|
||||
('invoice', 14, '2. Zahlungserinnerung - Bestellung {order_number}', 'Sehr geehrte/r {billing_first_name}...', NULL, 1),
|
||||
('invoice', 21, 'Letzte Zahlungserinnerung - Bestellung {order_number}', 'Sehr geehrte/r {billing_first_name}...', 'set_order_status_cancelled', 1);
|
||||
```
|
||||
|
||||
### Platzhalter
|
||||
|
||||
- `{billing_first_name}` - Vorname
|
||||
- `{billing_last_name}` - Nachname
|
||||
- `{order_number}` - Bestellnummer
|
||||
- `{order_date}` - Bestelldatum
|
||||
- `{order_total}` - Bestellsumme
|
||||
|
||||
## Monitoring
|
||||
|
||||
### 1. Log-Statistiken
|
||||
|
||||
- Admin-Bereich: `/admin/payments/reminder/logs`
|
||||
- Zeigt Statistiken der letzten 7, 30 und 90 Tage
|
||||
- Filter nach Order ID, Aktion und Datum
|
||||
|
||||
### 2. Erfolgsrate
|
||||
|
||||
- E-Mails gesendet vs. Fehler
|
||||
- Aktionen ausgeführt
|
||||
- Übersprungene Erinnerungen
|
||||
|
||||
### 3. Performance
|
||||
|
||||
- Ausführungszeit pro Lauf
|
||||
- Anzahl verarbeiteter Zahlungen
|
||||
- Speicherverbrauch
|
||||
|
||||
## Troubleshooting
|
||||
|
||||
### Häufige Probleme
|
||||
|
||||
**1. Command läuft nicht**
|
||||
|
||||
```bash
|
||||
# Prüfe PHP-Pfad
|
||||
which php
|
||||
|
||||
# Prüfe Projekt-Pfad
|
||||
pwd
|
||||
|
||||
# Teste Command manuell
|
||||
php artisan payments:reminders
|
||||
```
|
||||
|
||||
**2. Keine E-Mails werden gesendet**
|
||||
|
||||
```bash
|
||||
# Prüfe Mail-Konfiguration
|
||||
php artisan config:cache
|
||||
|
||||
# Prüfe Logs
|
||||
tail -f storage/logs/laravel.log
|
||||
```
|
||||
|
||||
**3. Falsche Intervalle**
|
||||
|
||||
```bash
|
||||
# Prüfe PaymentReminder-Konfiguration
|
||||
php artisan tinker
|
||||
>>> App\Models\PaymentReminder::where('active', true)->get()
|
||||
```
|
||||
|
||||
**4. Cron-Job läuft nicht**
|
||||
|
||||
```bash
|
||||
# Prüfe Crontab
|
||||
crontab -l
|
||||
|
||||
# Prüfe Cron-Logs
|
||||
sudo tail -f /var/log/cron
|
||||
|
||||
# Teste mit absoluten Pfaden
|
||||
0 9 * * * /usr/bin/php /path/to/project/artisan payments:reminders
|
||||
```
|
||||
|
||||
## Sicherheit
|
||||
|
||||
### 1. Berechtigungen
|
||||
|
||||
```bash
|
||||
# Stelle sicher, dass der Webserver-Benutzer Schreibrechte hat
|
||||
chown -R www-data:www-data storage/logs
|
||||
chmod -R 755 storage/logs
|
||||
```
|
||||
|
||||
### 2. Log-Rotation
|
||||
|
||||
```bash
|
||||
# Konfiguriere Log-Rotation in /etc/logrotate.d/laravel
|
||||
/path/to/project/storage/logs/*.log {
|
||||
daily
|
||||
missingok
|
||||
rotate 52
|
||||
compress
|
||||
notifempty
|
||||
create 644 www-data www-data
|
||||
}
|
||||
```
|
||||
|
||||
### 3. Backup
|
||||
|
||||
```bash
|
||||
# Backup der PaymentReminder-Konfiguration
|
||||
mysqldump -u username -p database payment_reminders > payment_reminders_backup.sql
|
||||
```
|
||||
|
||||
## Performance-Optimierung
|
||||
|
||||
### 1. Batch-Verarbeitung
|
||||
|
||||
- Der Command verarbeitet Zahlungen in Batches
|
||||
- Verwendet Datenbank-Indizes für bessere Performance
|
||||
|
||||
### 2. Memory-Management
|
||||
|
||||
- Garbage Collection nach jeder Zahlung
|
||||
- Begrenzte Anzahl von Logs
|
||||
|
||||
### 3. Timeout-Handling
|
||||
|
||||
- Lange Ausführungen werden abgebrochen
|
||||
- Fehler werden geloggt und übersprungen
|
||||
36109
_ide_helper.php
36109
_ide_helper.php
File diff suppressed because it is too large
Load diff
2267
_ide_helper_models.php
Normal file
2267
_ide_helper_models.php
Normal file
File diff suppressed because it is too large
Load diff
203
app/Console/Commands/PaymentsAccounts.php
Normal file
203
app/Console/Commands/PaymentsAccounts.php
Normal file
|
|
@ -0,0 +1,203 @@
|
|||
<?php
|
||||
|
||||
namespace App\Console\Commands;
|
||||
|
||||
use App\User;
|
||||
use Carbon\Carbon;
|
||||
use Illuminate\Console\Command;
|
||||
use App\Cron\UserCheckPaymentsAccounts;
|
||||
|
||||
class PaymentsAccounts extends Command
|
||||
{
|
||||
/**
|
||||
* ln -sfv /usr/bin/php73 /usr/bin/php
|
||||
* php artisan payments:accounts
|
||||
* The name and signature of the console command.
|
||||
*
|
||||
* @var string
|
||||
*/
|
||||
protected $signature = 'payments:accounts';
|
||||
protected $description = 'Check Payments Accounts';
|
||||
|
||||
private $timeStart;
|
||||
|
||||
private $dev = false;
|
||||
|
||||
public function __construct()
|
||||
{
|
||||
parent::__construct();
|
||||
}
|
||||
|
||||
/**
|
||||
* Execute the console command.
|
||||
*
|
||||
* @return int
|
||||
*/
|
||||
public function handle()
|
||||
{
|
||||
\Log::info('Starting PaymentsAccounts Command', ['timestamp' => now()]);
|
||||
$this->info('RUN Command Payments Account: '.date('d.m.Y H:i'));
|
||||
$this->timeStart = microtime(true);
|
||||
|
||||
try {
|
||||
$this->updateUserNextLevel();
|
||||
$this->updatePaymentsAccountsFree();
|
||||
$this->deactivateUserAccounts();
|
||||
$this->reminderPaymentsAccounts();
|
||||
|
||||
\Log::info('PaymentsAccounts Command completed successfully');
|
||||
return 0;
|
||||
} catch (\Exception $e) {
|
||||
\Log::error('PaymentsAccounts Command failed', [
|
||||
'error' => $e->getMessage(),
|
||||
'trace' => $e->getTraceAsString()
|
||||
]);
|
||||
return 1;
|
||||
}
|
||||
}
|
||||
|
||||
private function updateUserNextLevel(){
|
||||
try {
|
||||
// now date - renewal_days
|
||||
$count = 0;
|
||||
$renewalDate = Carbon::now()->modify('+'.(config('main.renewal_days')).' days');
|
||||
$users = User::where('payment_account', '!=', NULL)
|
||||
->where('active', '=', 1)
|
||||
->where('blocked', '!=', 1)
|
||||
->where('payment_account', '<', $renewalDate)
|
||||
->whereColumn('m_level', '!=', 'next_m_level')
|
||||
->where('deleted_at', NULL)
|
||||
->get();
|
||||
|
||||
foreach($users as $user){
|
||||
$user->m_level = $user->next_m_level;
|
||||
$user->save();
|
||||
$count ++;
|
||||
}
|
||||
|
||||
$diff = microtime(true) - $this->timeStart;
|
||||
$sec = intval($diff);
|
||||
$micro = $diff - $sec;
|
||||
$this->info('END Command updateUserNextLevel: '.$count.' | Time: '.$sec. 'sec :' . round($micro * 1000, 4) . " ms");
|
||||
|
||||
\Log::info('updateUserNextLevel completed', [
|
||||
'users_updated' => $count,
|
||||
'execution_time' => $sec . 'sec :' . round($micro * 1000, 4) . "ms"
|
||||
]);
|
||||
} catch (\Exception $e) {
|
||||
\Log::error('updateUserNextLevel failed', [
|
||||
'error' => $e->getMessage()
|
||||
]);
|
||||
throw $e;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
private function updatePaymentsAccountsFree(){
|
||||
try {
|
||||
// now date - renewal_days -1 / user_levels.payment_year false is no payment
|
||||
$count = 0;
|
||||
$renewalDate = Carbon::now()->modify('+'.(config('main.renewal_days')-1).' days');
|
||||
$users = User::join('user_levels', 'm_level', '=', 'user_levels.id')->select('users.*')
|
||||
->where('users.payment_account', '!=', NULL)
|
||||
->where('users.active', '=', 1)
|
||||
->where('users.blocked', '!=', 1)
|
||||
->where('users.payment_account', '<', $renewalDate)
|
||||
->where('user_levels.payment_year', '=', 0)//user_levels.payment_year false is no payment
|
||||
->where('users.deleted_at', NULL)
|
||||
->get();
|
||||
|
||||
foreach($users as $user){
|
||||
$user->payment_account = Carbon::parse($user->payment_account)->modify('1 year');
|
||||
$user->save();
|
||||
$count ++;
|
||||
}
|
||||
|
||||
$diff = microtime(true) - $this->timeStart;
|
||||
$sec = intval($diff);
|
||||
$micro = $diff - $sec;
|
||||
$this->info('END Command updatePaymentsAccountsFree: '.$count.' | Time: '.$sec. 'sec :' . round($micro * 1000, 4) . " ms");
|
||||
|
||||
\Log::info('updatePaymentsAccountsFree completed', [
|
||||
'users_updated' => $count,
|
||||
'execution_time' => $sec . 'sec :' . round($micro * 1000, 4) . "ms"
|
||||
]);
|
||||
} catch (\Exception $e) {
|
||||
\Log::error('updatePaymentsAccountsFree failed', [
|
||||
'error' => $e->getMessage()
|
||||
]);
|
||||
throw $e;
|
||||
}
|
||||
}
|
||||
|
||||
private function deactivateUserAccounts(){
|
||||
try {
|
||||
$count = 0;
|
||||
$sevenDaysAfterExpiry = Carbon::now()->subDays(7);
|
||||
$users = User::where('payment_account', '!=', NULL)
|
||||
->where('active', '=', 1)
|
||||
->where('blocked', '!=', 1)
|
||||
->where('payment_account', '<', $sevenDaysAfterExpiry)
|
||||
->where('deleted_at', NULL)
|
||||
->get();
|
||||
|
||||
foreach($users as $user){
|
||||
$user->active = 0;
|
||||
$user->save();
|
||||
$this->info('deactivateUserAccount | User: '.$user->id.' '.$user->email.' | Date :' . $user->getPaymentAccountDateFormat() . "");
|
||||
|
||||
$count ++;
|
||||
}
|
||||
|
||||
$diff = microtime(true) - $this->timeStart;
|
||||
$sec = intval($diff);
|
||||
$micro = $diff - $sec;
|
||||
$this->info('END Command deactivateUserAccounts: '.$count.' | Time: '.$sec. 'sec :' . round($micro * 1000, 4) . " ms");
|
||||
|
||||
\Log::info('deactivateUserAccounts completed', [
|
||||
'users_updated' => $count,
|
||||
'execution_time' => $sec . 'sec :' . round($micro * 1000, 4) . "ms"
|
||||
]);
|
||||
} catch (\Exception $e) {
|
||||
\Log::error('deactivateUserAccounts failed', [
|
||||
'error' => $e->getMessage()
|
||||
]);
|
||||
throw $e;
|
||||
}
|
||||
}
|
||||
|
||||
private function reminderPaymentsAccounts()
|
||||
{
|
||||
try {
|
||||
$count = 0;
|
||||
$max_reminder_date = Carbon::now()->modify('+'.(config('main.remind_first_days')).' days');
|
||||
$users = User::where('payment_account', '!=', NULL)
|
||||
->where('active', '=', 1)
|
||||
->where('blocked', '!=', 1)
|
||||
->where('payment_account', '<', $max_reminder_date)
|
||||
->where('deleted_at', NULL)
|
||||
->get();
|
||||
|
||||
foreach ($users as $user){
|
||||
$status = UserCheckPaymentsAccounts::userReminderPayments($user, $this->dev);
|
||||
$this->info('reminderPaymentsAccounts Status: '.$status.' | User: '.$user->id.' '.$user->email.' | Date :' . $user->getPaymentAccountDateFormat() . "");
|
||||
$count ++;
|
||||
}
|
||||
|
||||
$diff = microtime(true) - $this->timeStart;
|
||||
$sec = intval($diff);
|
||||
$micro = $diff - $sec;
|
||||
$this->info('END Command reminderPaymentsAccounts: '.$count.' | Time: '.$sec. 'sec :' . round($micro * 1000, 4) . " ms");
|
||||
|
||||
\Log::info('reminderPaymentsAccounts completed', [
|
||||
'users_processed' => $count,
|
||||
'execution_time' => $sec . 'sec :' . round($micro * 1000, 4) . "ms"
|
||||
]);
|
||||
} catch (\Exception $e) {
|
||||
\Log::error('reminderPaymentsAccounts failed', [
|
||||
'error' => $e->getMessage()
|
||||
]);
|
||||
throw $e;
|
||||
}
|
||||
}
|
||||
}
|
||||
279
app/Console/Commands/PaymentsReminders.php
Normal file
279
app/Console/Commands/PaymentsReminders.php
Normal file
|
|
@ -0,0 +1,279 @@
|
|||
<?php
|
||||
|
||||
namespace App\Console\Commands;
|
||||
|
||||
use App\Models\PaymentReminder;
|
||||
use App\Models\ShoppingPayment;
|
||||
use App\Services\PaymentReminderService;
|
||||
use Carbon\Carbon;
|
||||
use Illuminate\Console\Command;
|
||||
|
||||
/**
|
||||
* Command für automatische Zahlungserinnerungen
|
||||
*
|
||||
* Dieser Command wird als Cron-Job ausgeführt und sendet automatisch
|
||||
* Zahlungserinnerungen basierend auf den konfigurierten Intervallen.
|
||||
*
|
||||
* Verwendung:
|
||||
* php artisan payments:reminders
|
||||
*
|
||||
* Cron-Job Konfiguration (täglich um 9:00 Uhr):
|
||||
* 0 9 * * * cd /path/to/project && php artisan payments:reminders >> /dev/null 2>&1
|
||||
*
|
||||
* Oder für stündliche Ausführung:
|
||||
* 0 * * * * cd /path/to/project && php artisan payments:reminders >> /dev/null 2>&1
|
||||
*
|
||||
* Logs werden automatisch in storage/logs/laravel.log geschrieben
|
||||
*/
|
||||
class PaymentsReminders extends Command
|
||||
{
|
||||
/**
|
||||
* The name and signature of the console command.
|
||||
*
|
||||
* @var string
|
||||
*/
|
||||
protected $signature = 'payments:reminders';
|
||||
|
||||
protected $description = 'Run Payments Reminders';
|
||||
|
||||
private $timeStart;
|
||||
|
||||
private $dev = false;
|
||||
|
||||
private $paymentReminderService;
|
||||
|
||||
private $stats = [
|
||||
'total_processed' => 0,
|
||||
'reminders_sent' => 0,
|
||||
'errors' => 0,
|
||||
'skipped' => 0,
|
||||
];
|
||||
|
||||
public function __construct(PaymentReminderService $paymentReminderService)
|
||||
{
|
||||
parent::__construct();
|
||||
$this->paymentReminderService = $paymentReminderService;
|
||||
}
|
||||
|
||||
/**
|
||||
* Execute the console command.
|
||||
*
|
||||
* @return int
|
||||
*/
|
||||
public function handle()
|
||||
{
|
||||
\Log::info('Starting PaymentsReminders Command', ['timestamp' => now()]);
|
||||
$this->info('RUN Command Payments Reminders: '.date('d.m.Y H:i'));
|
||||
$this->timeStart = microtime(true);
|
||||
|
||||
try {
|
||||
$this->functionReminder();
|
||||
|
||||
$executionTime = round(microtime(true) - $this->timeStart, 2);
|
||||
$this->info("\n=== PAYMENT REMINDERS ABGESCHLOSSEN ===");
|
||||
$this->info("Ausführungszeit: {$executionTime} Sekunden");
|
||||
$this->info('Statistiken:');
|
||||
$this->info(" - Gesamt verarbeitet: {$this->stats['total_processed']}");
|
||||
$this->info(" - Erinnerungen gesendet: {$this->stats['reminders_sent']}");
|
||||
$this->info(" - Fehler: {$this->stats['errors']}");
|
||||
$this->info(" - Übersprungen: {$this->stats['skipped']}");
|
||||
|
||||
\Log::info('PaymentsReminders Command completed successfully', [
|
||||
'execution_time' => $executionTime,
|
||||
'stats' => $this->stats,
|
||||
]);
|
||||
|
||||
return 0;
|
||||
} catch (\Exception $e) {
|
||||
\Log::error('PaymentsReminders Command failed', [
|
||||
'error' => $e->getMessage(),
|
||||
'trace' => $e->getTraceAsString(),
|
||||
]);
|
||||
$this->error('Command failed: '.$e->getMessage());
|
||||
|
||||
return 1;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Hauptfunktion für die Verarbeitung der Zahlungserinnerungen
|
||||
*/
|
||||
private function functionReminder()
|
||||
{
|
||||
$this->info('=== STARTE PAYMENT REMINDERS ===');
|
||||
|
||||
// Hole alle aktiven PaymentReminder und gruppiere sie nach clearingtype
|
||||
$payment_reminders = PaymentReminder::where('active', true)->get();
|
||||
$this->info('Gefundene aktive PaymentReminder: '.$payment_reminders->count());
|
||||
|
||||
if ($payment_reminders->isEmpty()) {
|
||||
$this->warn('Keine aktiven PaymentReminder gefunden!');
|
||||
|
||||
return;
|
||||
}
|
||||
|
||||
// Finde für jeden clearingtype das kleinste Intervall (in Tagen)
|
||||
$intervals = $this->paymentReminderService->getActiveIntervals();
|
||||
|
||||
$this->info('Gefundene clearingtypes mit kleinsten Intervallen:');
|
||||
foreach ($intervals as $clearingtype => $interval) {
|
||||
$this->line(" - {$clearingtype}: {$interval} Tage");
|
||||
}
|
||||
|
||||
// Verarbeite jeden clearingtype mit seinem kleinsten Intervall
|
||||
foreach ($intervals as $clearingtype => $interval) {
|
||||
$this->info("\n--- Verarbeite clearingtype: {$clearingtype} mit Intervall: {$interval} Tage ---");
|
||||
|
||||
$date = Carbon::now()->subDays($interval);
|
||||
$this->line('Suche Zahlungen vor: '.$date->format('d.m.Y H:i:s'));
|
||||
|
||||
// Hole nur die neueste ShoppingPayment pro shopping_order_id
|
||||
$shopping_payments = $this->paymentReminderService->getOpenPaymentsForClearingType($clearingtype, $interval);
|
||||
|
||||
$this->info("Gefundene offene Zahlungen für {$clearingtype}: ".$shopping_payments->count());
|
||||
|
||||
if ($shopping_payments->isEmpty()) {
|
||||
$this->line("Keine Zahlungen für {$clearingtype} gefunden.");
|
||||
|
||||
continue;
|
||||
}
|
||||
|
||||
// Verarbeite jede Zahlung
|
||||
$this->line('--- START processPayment VERARBEITUNG');
|
||||
|
||||
foreach ($shopping_payments as $shopping_payment) {
|
||||
$this->processPayment($shopping_payment, $clearingtype);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Verarbeitet eine einzelne Zahlung und sendet ggf. eine Erinnerung
|
||||
*/
|
||||
private function processPayment($shopping_payment, $clearingtype)
|
||||
{
|
||||
$this->stats['total_processed']++;
|
||||
|
||||
try {
|
||||
$this->line("Verarbeite Order ID: {$shopping_payment->shopping_order_id}, Created: {$shopping_payment->created_at->format('d.m.Y H:i:s')}, Amount: {$shopping_payment->amount}, Reminder: {$shopping_payment->reminder}");
|
||||
|
||||
// Prüfe ob eine Erinnerung gesendet werden soll
|
||||
if ($this->shouldSendReminder($shopping_payment, $clearingtype)) {
|
||||
$this->sendReminderForPayment($shopping_payment);
|
||||
} else {
|
||||
$this->line('Übersprungen - Keine Erinnerung fällig');
|
||||
$this->stats['skipped']++;
|
||||
}
|
||||
} catch (\Exception $e) {
|
||||
$this->error("Fehler bei Order ID {$shopping_payment->shopping_order_id}: ".$e->getMessage());
|
||||
$this->stats['errors']++;
|
||||
|
||||
\Log::error('Error processing payment reminder', [
|
||||
'order_id' => $shopping_payment->shopping_order_id,
|
||||
'payment_id' => $shopping_payment->id,
|
||||
'error' => $e->getMessage(),
|
||||
]);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Prüft ob eine Erinnerung für diese Zahlung gesendet werden soll
|
||||
*
|
||||
* Logik:
|
||||
* - Erste Erinnerung: Nach X Tagen ab Bestelldatum
|
||||
* - Weitere Erinnerungen: Nach Y Tagen ab letzter Erinnerung
|
||||
*/
|
||||
private function shouldSendReminder($shopping_payment, $clearingtype)
|
||||
{
|
||||
// Hole alle aktiven Erinnerungen für diesen Clearingtype
|
||||
$payment_reminders = PaymentReminder::where('active', true)
|
||||
->where('clearingtype', $clearingtype)
|
||||
->orderBy('interval', 'asc') // von kein nach gross
|
||||
->get();
|
||||
|
||||
if ($payment_reminders->isEmpty()) {
|
||||
$this->line('shouldSendReminder - keine PaymentReminders');
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
// Wenn alle Erinnerungen bereits gesendet wurden
|
||||
if ($shopping_payment->reminder >= $payment_reminders->count()) {
|
||||
$this->line('shouldSendReminder - alle Erinnerungen wurden bereits gesendet');
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
$next_reminder = isset($payment_reminders[$shopping_payment->reminder]) ? $payment_reminders[$shopping_payment->reminder] : null;
|
||||
if ($next_reminder == null) {
|
||||
$next_reminder = isset($payment_reminders[0]) ? $payment_reminders[0] : null;
|
||||
if ($next_reminder == null) {
|
||||
$this->line('shouldSendReminder - keine Erinnerung gefunden');
|
||||
|
||||
return false;
|
||||
}
|
||||
}
|
||||
$this->line("shouldSendReminder - nächste Erinnerung: {$next_reminder->interval} Tage");
|
||||
|
||||
// Wenn noch keine Erinnerung gesendet wurde, prüfe das erste Intervall
|
||||
if ($shopping_payment->reminder == null || $shopping_payment->reminder == 0) {
|
||||
$daysSinceOrder = $shopping_payment->created_at->diffInDays(now());
|
||||
$this->line("shouldSendReminder - no reminder send first intervall - Tage seit Bestellung: {$daysSinceOrder} : Next intervall: {$next_reminder->interval}");
|
||||
|
||||
return $daysSinceOrder >= $next_reminder->interval;
|
||||
}
|
||||
|
||||
// Hole die nächste Erinnerung
|
||||
|
||||
// Wenn bereits Erinnerungen gesendet wurden, prüfe das nächste Intervall
|
||||
if ($shopping_payment->reminder_date) {
|
||||
$current_reminder = $payment_reminders[$shopping_payment->reminder - 1];
|
||||
$this->line("shouldSendReminder - letzte Erinnerung: {$current_reminder->interval} Tage");
|
||||
$interval_difference = $next_reminder->interval - $current_reminder->interval;
|
||||
|
||||
$next_reminder_date = Carbon::parse($shopping_payment->reminder_date)->addDays($interval_difference);
|
||||
$this->line("shouldSendReminder - next reminder date: {$next_reminder_date->format('d.m.Y H:i:s')}");
|
||||
|
||||
return now()->gte($next_reminder_date);
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
/**
|
||||
* Sendet eine Erinnerung für eine spezifische Zahlung
|
||||
*/
|
||||
private function sendReminderForPayment($shopping_payment)
|
||||
{
|
||||
try {
|
||||
$this->line('Sende Erinnerung...');
|
||||
|
||||
$result = $this->paymentReminderService->sendReminder($shopping_payment);
|
||||
|
||||
if ($result) {
|
||||
$this->line('Erinnerung erfolgreich gesendet');
|
||||
$this->stats['reminders_sent']++;
|
||||
|
||||
// Log für Cron-Job
|
||||
\Log::info('Payment reminder sent via cron', [
|
||||
'order_id' => $shopping_payment->shopping_order_id,
|
||||
'payment_id' => $shopping_payment->id,
|
||||
'reminder_count' => $shopping_payment->reminder + 1,
|
||||
'email' => $shopping_payment->shopping_order->shopping_user->billing_email ?? 'N/A',
|
||||
]);
|
||||
} else {
|
||||
$this->line('Keine Erinnerung gesendet (keine weitere Erinnerung verfügbar)');
|
||||
$this->stats['skipped']++;
|
||||
}
|
||||
} catch (\Exception $e) {
|
||||
$this->error('Fehler beim Senden der Erinnerung: '.$e->getMessage());
|
||||
$this->stats['errors']++;
|
||||
|
||||
\Log::error('Error sending payment reminder', [
|
||||
'order_id' => $shopping_payment->shopping_order_id,
|
||||
'payment_id' => $shopping_payment->id,
|
||||
'error' => $e->getMessage(),
|
||||
]);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
@ -19,13 +19,27 @@ class Kernel extends ConsoleKernel
|
|||
/**
|
||||
* Define the application's command schedule.
|
||||
*
|
||||
* @param \Illuminate\Console\Scheduling\Schedule $schedule
|
||||
* @return void
|
||||
*/
|
||||
protected function schedule(Schedule $schedule)
|
||||
{
|
||||
// $schedule->command('inspire')
|
||||
// ->hourly();
|
||||
if (config('app.debug') == false) {
|
||||
$schedule->command('payments:accounts')
|
||||
->sendOutputTo(storage_path('logs/cron.log'))
|
||||
->appendOutputTo(storage_path('logs/cron-history.log'))
|
||||
->emailOutputOnFailure(config('app.exception_mail'))
|
||||
->onFailure(function () {
|
||||
\Log::error('Payments:accounts command failed');
|
||||
});
|
||||
}
|
||||
|
||||
$schedule->command('payments:reminders')
|
||||
->sendOutputTo(storage_path('logs/cron.log'))
|
||||
->appendOutputTo(storage_path('logs/cron-reminders.log'))
|
||||
->emailOutputOnFailure(config('app.exception_mail'))
|
||||
->onFailure(function () {
|
||||
\Log::error('Payments:reminders command failed');
|
||||
});
|
||||
}
|
||||
|
||||
/**
|
||||
|
|
|
|||
158
app/Cron/UserCheckPaymentsAccounts.php
Normal file
158
app/Cron/UserCheckPaymentsAccounts.php
Normal file
|
|
@ -0,0 +1,158 @@
|
|||
<?php
|
||||
|
||||
namespace App\Cron;
|
||||
|
||||
use App\Mail\MailCustomMessage;
|
||||
use App\Mail\MailVerifyAccount;
|
||||
use App\Models\UserHistory;
|
||||
use App\Models\UserMessage;
|
||||
use App\User;
|
||||
use Carbon;
|
||||
use Illuminate\Support\Facades\Mail;
|
||||
|
||||
class UserCheckPaymentsAccounts
|
||||
{
|
||||
/*RULES
|
||||
reminders
|
||||
> 29 renewal_days > set next_m_level to m_level
|
||||
> 29 renewal_days $user->user_level->payment_year = 0 / false + 1 year
|
||||
|
||||
> 21 remind_first_days = reminder_first //status 31
|
||||
> 14 remind_sec_days = reminder_sec //status 33
|
||||
> 2 remind_last_days = reminder_last //status 34
|
||||
> 0 deaktiv = reminder_deaktiv //status 35
|
||||
*/
|
||||
|
||||
public static function userReminderPayments(User $user, $dev)
|
||||
{
|
||||
// 35 reminder_deaktiv
|
||||
if (! $user->isActiveAccount()) { // payment_account gt now
|
||||
return self::checkIsReminderSend($user, 35, $dev);
|
||||
}
|
||||
// 34 reminder_last
|
||||
if ($user->daysActiveAccount() <= config('main.remind_last_days')) {
|
||||
return self::checkIsReminderSend($user, 34, $dev);
|
||||
}
|
||||
// 33 reminder_sec
|
||||
if ($user->daysActiveAccount() <= config('main.remind_sec_days')) {
|
||||
return self::checkIsReminderSend($user, 33, $dev);
|
||||
}
|
||||
// 31 reminder_first
|
||||
if ($user->daysActiveAccount() > config('main.remind_sec_days')) {
|
||||
return self::checkIsReminderSend($user, 31, $dev);
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
private static function checkIsReminderSend(User $user, $status, $dev)
|
||||
{
|
||||
|
||||
$isSend = UserHistory::whereUserId($user->id)
|
||||
->whereAction('reminder_payments')
|
||||
->whereIdentifier($user->payment_account)
|
||||
->whereStatus($status)
|
||||
->get()->last();
|
||||
|
||||
if ($isSend) {
|
||||
return 0;
|
||||
}
|
||||
if ($dev) {
|
||||
$referenz = 0;
|
||||
} else {
|
||||
$referenz = self::sendReminderMail($user, $status);
|
||||
}
|
||||
UserHistory::create(['user_id' => $user->id, 'action' => 'reminder_payments', 'referenz' => $referenz, 'identifier' => $user->payment_account, 'status' => $status]);
|
||||
|
||||
return $status;
|
||||
}
|
||||
|
||||
private static function sendReminderMail(User $user, $status)
|
||||
{
|
||||
|
||||
$days = $user->daysActiveAccount();
|
||||
if ($days < 0) {
|
||||
$days = $days * -1;
|
||||
}
|
||||
$datetime = $user->getPaymentAccountDateFormat();
|
||||
|
||||
$pay_date = 0;
|
||||
$price = 0;
|
||||
/*$pay_date = Carbon::parse($user->payment_account)->modify('- '.config('main.abo_booking_days').' days')->format('d.m.Y');
|
||||
$price = "";
|
||||
if($user->payment_order_id && isset($user->payment_order_product->price)){
|
||||
$price = 'von '.$user->payment_order_product->getFormattedPrice().' EUR';
|
||||
}*/
|
||||
|
||||
$message = __('reminder.copy_first_'.$status, ['days' => $days, 'datetime' => $datetime, 'price' => $price, 'pay_date' => $pay_date]);
|
||||
$message_last = __('reminder.copy_last_'.$status, ['days' => $days, 'datetime' => $datetime, 'price' => $price, 'pay_date' => $pay_date]);
|
||||
$button = __('reminder.button_'.$status);
|
||||
|
||||
$message = preg_replace("/[\n\r]/", '', $message);
|
||||
$message_last = preg_replace("/[\n\r]/", '', $message_last);
|
||||
|
||||
$data = [
|
||||
'subject' => __('reminder.subject').' | ID: '.$status,
|
||||
'message' => $message,
|
||||
'message_last' => $message_last,
|
||||
'url' => route('user_membership'),
|
||||
'button' => $button,
|
||||
];
|
||||
// dump($data);
|
||||
$sender = User::find(1);
|
||||
$customer_mail = UserMessage::create([
|
||||
'user_id' => $user->id,
|
||||
'send_user_id' => $sender->id,
|
||||
'email' => $user->email,
|
||||
'subject' => $data['subject'],
|
||||
'message' => $data['message'].' '.$data['message_last'],
|
||||
]);
|
||||
try {
|
||||
if ($status >= 34) {
|
||||
// Mail::to($user->email)->bcc(config('app.info_mail'))->send(new MailCustomMessage($user, $data, $sender, false));
|
||||
} else {
|
||||
// Mail::to($user->email)->send(new MailCustomMessage($user, $data, $sender, false));
|
||||
}
|
||||
} catch (\Exception $e) {
|
||||
\Log::channel('cron')->error('Mail Error: '.$e->getMessage());
|
||||
// Never reached
|
||||
$customer_mail->fail = true;
|
||||
$customer_mail->error = $e->getMessage();
|
||||
$customer_mail->save();
|
||||
|
||||
return 0;
|
||||
}
|
||||
$customer_mail->send = true;
|
||||
$customer_mail->sent_at = now();
|
||||
$customer_mail->save();
|
||||
|
||||
return 1;
|
||||
}
|
||||
}
|
||||
|
||||
/*public function checkConfirmation()
|
||||
{
|
||||
User Register sind in der DB UserRegister, erst bei bestätigung wird es in die User DB übertragen
|
||||
|
||||
$now = date('Y-m-d H:i:s');
|
||||
$next = date('Y-m-d H:i:s', strtotime('+3 week'));
|
||||
|
||||
$users = User::where('confirmed', '=', 0)->where('confirmation_code_to', '<', $now)->get();
|
||||
|
||||
foreach ($users as $user) {
|
||||
|
||||
//delete user
|
||||
if ($user->confirmation_code_remider == 1) {
|
||||
$this->userRepo->deleteUser($user);
|
||||
|
||||
}
|
||||
//send new remider
|
||||
if ($user->confirmation_code_remider == 0) {
|
||||
Mail::to($user->email)->bcc(config('app.info_mail'))->send(new MailVerifyAccount($user->confirmation_code, $user));
|
||||
$user->confirmation_code_to = $next;
|
||||
$user->confirmation_code_remider = 1;
|
||||
$user->save();
|
||||
}
|
||||
}
|
||||
return "TOSK";
|
||||
}*/
|
||||
|
|
@ -4,6 +4,9 @@ namespace App\Exceptions;
|
|||
|
||||
use Illuminate\Foundation\Exceptions\Handler as ExceptionHandler;
|
||||
use Throwable;
|
||||
use Illuminate\Support\Facades\Mail;
|
||||
use Symfony\Component\ErrorHandler\Exception\FlattenException;
|
||||
use Symfony\Component\ErrorHandler\ErrorRenderer\HtmlErrorRenderer;
|
||||
|
||||
class Handler extends ExceptionHandler
|
||||
{
|
||||
|
|
@ -36,6 +39,9 @@ class Handler extends ExceptionHandler
|
|||
*/
|
||||
public function report(Throwable $exception)
|
||||
{
|
||||
if ($this->shouldReport($exception)) {
|
||||
$this->sendEmail($exception);
|
||||
}
|
||||
parent::report($exception);
|
||||
}
|
||||
|
||||
|
|
@ -52,4 +58,35 @@ class Handler extends ExceptionHandler
|
|||
{
|
||||
return parent::render($request, $exception);
|
||||
}
|
||||
|
||||
public function sendEmail(Throwable $exception)
|
||||
{
|
||||
try {
|
||||
$e = FlattenException::create($exception);
|
||||
$handler = new HtmlErrorRenderer(true); // boolean, true raises debug flag...
|
||||
|
||||
$css = $handler->getStylesheet();
|
||||
$content = $handler->getBody($e);
|
||||
//Mail::to(config('app.exception_mail'))->send(new MailContact($contact));
|
||||
// Verwende normale Mail-Klasse statt Facade, um Probleme bei der Initialisierung zu vermeiden
|
||||
$to = config('app.exception_mail');
|
||||
$subject = 'gruene-seele Exception: ' . \Request::fullUrl();
|
||||
|
||||
if ($to) {
|
||||
\Mail::send('emails.exception', compact('css', 'content'), function ($message) use ($to, $subject) {
|
||||
$message
|
||||
->to($to)
|
||||
->subject($subject)
|
||||
;
|
||||
});
|
||||
}
|
||||
} catch (Throwable $ex) {
|
||||
// Einfache Fehlerprotokollierung ohne Facade
|
||||
file_put_contents(
|
||||
storage_path('logs/laravel-' . date('Y-m-d') . '.log'),
|
||||
'[' . date('Y-m-d H:i:s') . '] exception-handler-error: ' . $ex->getMessage() . "\n",
|
||||
FILE_APPEND
|
||||
);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
|||
33
app/Exports/ExcelExport.php
Normal file
33
app/Exports/ExcelExport.php
Normal file
|
|
@ -0,0 +1,33 @@
|
|||
<?php
|
||||
namespace App\Exports;
|
||||
|
||||
use Maatwebsite\Excel\Excel;
|
||||
use Maatwebsite\Excel\Concerns\FromCollection;
|
||||
use Maatwebsite\Excel\Concerns\Exportable;
|
||||
use Maatwebsite\Excel\Concerns\WithHeadings;
|
||||
|
||||
class ExcelExport implements FromCollection, WithHeadings
|
||||
{
|
||||
protected $collection;
|
||||
protected $headings;
|
||||
|
||||
use Exportable;
|
||||
|
||||
|
||||
public function __construct($data,$header)
|
||||
{
|
||||
$this->collection = $data;
|
||||
$this->headings = $header;
|
||||
}
|
||||
|
||||
public function collection()
|
||||
{
|
||||
return collect($this->collection);
|
||||
}
|
||||
|
||||
public function headings(): array
|
||||
{
|
||||
return [$this->headings];
|
||||
}
|
||||
|
||||
}
|
||||
59
app/Http/Controllers/Admin/Inventory/LocationController.php
Normal file
59
app/Http/Controllers/Admin/Inventory/LocationController.php
Normal file
|
|
@ -0,0 +1,59 @@
|
|||
<?php
|
||||
|
||||
namespace App\Http\Controllers\Admin\Inventory;
|
||||
|
||||
use App\Http\Controllers\Controller;
|
||||
use App\Http\Requests\Inventory\StoreLocationRequest;
|
||||
use App\Http\Requests\Inventory\UpdateLocationRequest;
|
||||
use App\Models\Location;
|
||||
|
||||
class LocationController extends Controller
|
||||
{
|
||||
public function index()
|
||||
{
|
||||
return view('admin.inventory.locations.index', [
|
||||
'values' => Location::query()->orderBy('name')->get(),
|
||||
]);
|
||||
}
|
||||
|
||||
public function create()
|
||||
{
|
||||
return view('admin.inventory.locations.form', [
|
||||
'model' => new Location(['active' => true]),
|
||||
]);
|
||||
}
|
||||
|
||||
public function store(StoreLocationRequest $request)
|
||||
{
|
||||
Location::create($request->validated());
|
||||
|
||||
\Session::flash('alert-save', '1');
|
||||
|
||||
return redirect()->route('admin.inventory.locations.index');
|
||||
}
|
||||
|
||||
public function edit(Location $location)
|
||||
{
|
||||
return view('admin.inventory.locations.form', [
|
||||
'model' => $location,
|
||||
]);
|
||||
}
|
||||
|
||||
public function update(UpdateLocationRequest $request, Location $location)
|
||||
{
|
||||
$location->update($request->validated());
|
||||
|
||||
\Session::flash('alert-save', '1');
|
||||
|
||||
return redirect()->route('admin.inventory.locations.index');
|
||||
}
|
||||
|
||||
public function destroy(Location $location)
|
||||
{
|
||||
$location->delete();
|
||||
|
||||
\Session::flash('alert-success', __('Eintrag gelöscht'));
|
||||
|
||||
return redirect()->route('admin.inventory.locations.index');
|
||||
}
|
||||
}
|
||||
|
|
@ -0,0 +1,59 @@
|
|||
<?php
|
||||
|
||||
namespace App\Http\Controllers\Admin\Inventory;
|
||||
|
||||
use App\Http\Controllers\Controller;
|
||||
use App\Http\Requests\Inventory\StoreMaterialQualityRequest;
|
||||
use App\Http\Requests\Inventory\UpdateMaterialQualityRequest;
|
||||
use App\Models\MaterialQuality;
|
||||
|
||||
class MaterialQualityController extends Controller
|
||||
{
|
||||
public function index()
|
||||
{
|
||||
return view('admin.inventory.material-qualities.index', [
|
||||
'values' => MaterialQuality::query()->orderBy('pos')->orderBy('name')->get(),
|
||||
]);
|
||||
}
|
||||
|
||||
public function create()
|
||||
{
|
||||
return view('admin.inventory.material-qualities.form', [
|
||||
'model' => new MaterialQuality(['pos' => 0]),
|
||||
]);
|
||||
}
|
||||
|
||||
public function store(StoreMaterialQualityRequest $request)
|
||||
{
|
||||
MaterialQuality::create($request->validated());
|
||||
|
||||
\Session::flash('alert-save', '1');
|
||||
|
||||
return redirect()->route('admin.inventory.material-qualities.index');
|
||||
}
|
||||
|
||||
public function edit(MaterialQuality $materialQuality)
|
||||
{
|
||||
return view('admin.inventory.material-qualities.form', [
|
||||
'model' => $materialQuality,
|
||||
]);
|
||||
}
|
||||
|
||||
public function update(UpdateMaterialQualityRequest $request, MaterialQuality $materialQuality)
|
||||
{
|
||||
$materialQuality->update($request->validated());
|
||||
|
||||
\Session::flash('alert-save', '1');
|
||||
|
||||
return redirect()->route('admin.inventory.material-qualities.index');
|
||||
}
|
||||
|
||||
public function destroy(MaterialQuality $materialQuality)
|
||||
{
|
||||
$materialQuality->delete();
|
||||
|
||||
\Session::flash('alert-success', __('Eintrag gelöscht'));
|
||||
|
||||
return redirect()->route('admin.inventory.material-qualities.index');
|
||||
}
|
||||
}
|
||||
119
app/Http/Controllers/Admin/Inventory/PackagingItemController.php
Normal file
119
app/Http/Controllers/Admin/Inventory/PackagingItemController.php
Normal file
|
|
@ -0,0 +1,119 @@
|
|||
<?php
|
||||
|
||||
namespace App\Http\Controllers\Admin\Inventory;
|
||||
|
||||
use App\Http\Controllers\Controller;
|
||||
use App\Http\Requests\Inventory\StorePackagingItemRequest;
|
||||
use App\Http\Requests\Inventory\UpdatePackagingItemRequest;
|
||||
use App\Models\PackagingItem;
|
||||
use App\Models\PackagingMaterial;
|
||||
use App\Models\Supplier;
|
||||
use App\Repositories\PackagingItemRepository;
|
||||
use Illuminate\Http\Request;
|
||||
|
||||
class PackagingItemController extends Controller
|
||||
{
|
||||
public function __construct(
|
||||
protected PackagingItemRepository $packagingItemRepository
|
||||
) {}
|
||||
|
||||
public function index(Request $request)
|
||||
{
|
||||
$category = $request->get('category', 'packaging');
|
||||
$isShipping = $category === 'shipping';
|
||||
|
||||
$query = PackagingItem::query()
|
||||
->with(['packagingMaterial', 'supplier'])
|
||||
->orderBy('name');
|
||||
|
||||
if ($isShipping) {
|
||||
$query->where('category', 'shipping');
|
||||
} else {
|
||||
$query->where('category', 'packaging');
|
||||
}
|
||||
|
||||
return view('admin.inventory.packaging-items.index', [
|
||||
'values' => $query->get(),
|
||||
'category' => $category,
|
||||
'pageTitle' => $isShipping ? __('Versandverpackung') : __('Produktverpackung'),
|
||||
]);
|
||||
}
|
||||
|
||||
public function create(Request $request)
|
||||
{
|
||||
$category = $request->query('category', 'packaging');
|
||||
if (! in_array($category, ['packaging', 'shipping'], true)) {
|
||||
$category = 'packaging';
|
||||
}
|
||||
|
||||
return view('admin.inventory.packaging-items.form', [
|
||||
'model' => new PackagingItem(['active' => true, 'category' => $category === 'shipping' ? 'shipping' : 'packaging', 'weight_grams' => 0]),
|
||||
'packagingMaterials' => PackagingMaterial::query()->orderBy('pos')->orderBy('name')->get(),
|
||||
'suppliers' => Supplier::query()->orderBy('name')->get(),
|
||||
'category' => $category,
|
||||
]);
|
||||
}
|
||||
|
||||
public function store(StorePackagingItemRequest $request)
|
||||
{
|
||||
$validated = $request->validated();
|
||||
|
||||
\Log::debug('PackagingItem STORE – raw input', [
|
||||
'category_raw' => $request->input('category'),
|
||||
'category_hex' => bin2hex((string) $request->input('category')),
|
||||
'all_input' => $request->all(),
|
||||
]);
|
||||
\Log::debug('PackagingItem STORE – validated', $validated);
|
||||
|
||||
$item = $this->packagingItemRepository->create($validated);
|
||||
|
||||
\Session::flash('alert-save', '1');
|
||||
|
||||
$category = $item->category === 'shipping' ? 'shipping' : 'packaging';
|
||||
|
||||
return redirect()->route('admin.inventory.packaging-items.index', ['category' => $category]);
|
||||
}
|
||||
|
||||
public function edit(PackagingItem $packagingItem)
|
||||
{
|
||||
$category = $packagingItem->category === 'shipping' ? 'shipping' : 'packaging';
|
||||
|
||||
return view('admin.inventory.packaging-items.form', [
|
||||
'model' => $packagingItem,
|
||||
'packagingMaterials' => PackagingMaterial::query()->orderBy('pos')->orderBy('name')->get(),
|
||||
'suppliers' => Supplier::query()->orderBy('name')->get(),
|
||||
'category' => $category,
|
||||
]);
|
||||
}
|
||||
|
||||
public function update(UpdatePackagingItemRequest $request, PackagingItem $packagingItem)
|
||||
{
|
||||
$validated = $request->validated();
|
||||
|
||||
\Log::debug('PackagingItem UPDATE – raw input', [
|
||||
'category_raw' => $request->input('category'),
|
||||
'category_hex' => bin2hex((string) $request->input('category')),
|
||||
'all_input' => $request->all(),
|
||||
]);
|
||||
\Log::debug('PackagingItem UPDATE – validated', $validated);
|
||||
|
||||
$this->packagingItemRepository->update($packagingItem, $validated);
|
||||
|
||||
\Session::flash('alert-save', '1');
|
||||
|
||||
$category = $packagingItem->category === 'shipping' ? 'shipping' : 'packaging';
|
||||
|
||||
return redirect()->route('admin.inventory.packaging-items.index', ['category' => $category]);
|
||||
}
|
||||
|
||||
public function destroy(PackagingItem $packagingItem)
|
||||
{
|
||||
$category = $packagingItem->category === 'shipping' ? 'shipping' : 'packaging';
|
||||
|
||||
$packagingItem->delete();
|
||||
|
||||
\Session::flash('alert-success', __('Eintrag gelöscht'));
|
||||
|
||||
return redirect()->route('admin.inventory.packaging-items.index', ['category' => $category]);
|
||||
}
|
||||
}
|
||||
|
|
@ -0,0 +1,59 @@
|
|||
<?php
|
||||
|
||||
namespace App\Http\Controllers\Admin\Inventory;
|
||||
|
||||
use App\Http\Controllers\Controller;
|
||||
use App\Http\Requests\Inventory\StorePackagingMaterialRequest;
|
||||
use App\Http\Requests\Inventory\UpdatePackagingMaterialRequest;
|
||||
use App\Models\PackagingMaterial;
|
||||
|
||||
class PackagingMaterialController extends Controller
|
||||
{
|
||||
public function index()
|
||||
{
|
||||
return view('admin.inventory.packaging-materials.index', [
|
||||
'values' => PackagingMaterial::query()->orderBy('pos')->orderBy('name')->get(),
|
||||
]);
|
||||
}
|
||||
|
||||
public function create()
|
||||
{
|
||||
return view('admin.inventory.packaging-materials.form', [
|
||||
'model' => new PackagingMaterial(['pos' => 0]),
|
||||
]);
|
||||
}
|
||||
|
||||
public function store(StorePackagingMaterialRequest $request)
|
||||
{
|
||||
PackagingMaterial::create($request->validated());
|
||||
|
||||
\Session::flash('alert-save', '1');
|
||||
|
||||
return redirect()->route('admin.inventory.packaging-materials.index');
|
||||
}
|
||||
|
||||
public function edit(PackagingMaterial $packagingMaterial)
|
||||
{
|
||||
return view('admin.inventory.packaging-materials.form', [
|
||||
'model' => $packagingMaterial,
|
||||
]);
|
||||
}
|
||||
|
||||
public function update(UpdatePackagingMaterialRequest $request, PackagingMaterial $packagingMaterial)
|
||||
{
|
||||
$packagingMaterial->update($request->validated());
|
||||
|
||||
\Session::flash('alert-save', '1');
|
||||
|
||||
return redirect()->route('admin.inventory.packaging-materials.index');
|
||||
}
|
||||
|
||||
public function destroy(PackagingMaterial $packagingMaterial)
|
||||
{
|
||||
$packagingMaterial->delete();
|
||||
|
||||
\Session::flash('alert-success', __('Eintrag gelöscht'));
|
||||
|
||||
return redirect()->route('admin.inventory.packaging-materials.index');
|
||||
}
|
||||
}
|
||||
169
app/Http/Controllers/Admin/Inventory/ProductionController.php
Normal file
169
app/Http/Controllers/Admin/Inventory/ProductionController.php
Normal file
|
|
@ -0,0 +1,169 @@
|
|||
<?php
|
||||
|
||||
namespace App\Http\Controllers\Admin\Inventory;
|
||||
|
||||
use App\Http\Controllers\Controller;
|
||||
use App\Http\Requests\Inventory\StoreProductionRequest;
|
||||
use App\Models\Location;
|
||||
use App\Models\Product;
|
||||
use App\Models\Production;
|
||||
use App\Repositories\ProductionRepository;
|
||||
use App\Services\ProductionService;
|
||||
use Illuminate\Http\JsonResponse;
|
||||
use Illuminate\Http\RedirectResponse;
|
||||
use Illuminate\Http\Request;
|
||||
use Illuminate\Validation\ValidationException;
|
||||
use Illuminate\View\View;
|
||||
|
||||
class ProductionController extends Controller
|
||||
{
|
||||
public function __construct(
|
||||
protected ProductionRepository $productionRepository,
|
||||
protected ProductionService $productionService
|
||||
) {}
|
||||
|
||||
public function index(): View
|
||||
{
|
||||
return view('admin.inventory.productions.index', [
|
||||
'values' => $this->productionRepository->listForIndex(),
|
||||
]);
|
||||
}
|
||||
|
||||
public function create(): View
|
||||
{
|
||||
$defaultLocationId = Location::query()->where('name', 'like', '%öln%')->value('id')
|
||||
?? Location::query()->where('active', true)->first()?->id;
|
||||
|
||||
return view('admin.inventory.productions.create', [
|
||||
'products' => Product::query()->where('active', 1)->orderBy('name')->get(['id', 'name']),
|
||||
'locations' => Location::query()->where('active', true)->orderBy('name')->get(),
|
||||
'defaultLocationId' => $defaultLocationId,
|
||||
'model' => null,
|
||||
]);
|
||||
}
|
||||
|
||||
public function store(StoreProductionRequest $request): RedirectResponse
|
||||
{
|
||||
$payload = $request->validatedPayload();
|
||||
|
||||
try {
|
||||
$production = $this->productionService->store(
|
||||
[
|
||||
'product_id' => $payload['product_id'],
|
||||
'location_id' => $payload['location_id'],
|
||||
'produced_at' => $payload['produced_at'],
|
||||
'quantity' => $payload['quantity'],
|
||||
'notes' => $payload['notes'],
|
||||
],
|
||||
$payload['ingredient_lines'],
|
||||
(int) $request->user()->id
|
||||
);
|
||||
} catch (ValidationException $e) {
|
||||
return redirect()->back()->withInput()->withErrors($e->errors());
|
||||
}
|
||||
|
||||
if ($production->mhd_warning) {
|
||||
\Session::flash('alert-warning', __('Hinweis: Mindestens eine Rohstoff-Charge hat ein kürzeres MHD als das geplante Produkt-MHD.'));
|
||||
}
|
||||
\Session::flash('alert-save', '1');
|
||||
|
||||
return redirect()->route('admin.inventory.productions.show', $production);
|
||||
}
|
||||
|
||||
public function show(Production $production): View
|
||||
{
|
||||
$production->load([
|
||||
'product',
|
||||
'location',
|
||||
'producedByUser.account',
|
||||
'productionIngredients.ingredient',
|
||||
'productionIngredients.stockEntry',
|
||||
'productionPackagings.packagingItem.packagingMaterial',
|
||||
]);
|
||||
|
||||
return view('admin.inventory.productions.show', [
|
||||
'model' => $production,
|
||||
]);
|
||||
}
|
||||
|
||||
public function edit(Production $production): View
|
||||
{
|
||||
$production->load([
|
||||
'product',
|
||||
'location',
|
||||
'productionIngredients.ingredient',
|
||||
'productionIngredients.stockEntry',
|
||||
]);
|
||||
|
||||
$defaultLocationId = $production->location_id;
|
||||
|
||||
return view('admin.inventory.productions.edit', [
|
||||
'model' => $production,
|
||||
'products' => Product::query()->where('active', 1)
|
||||
->orWhere('id', $production->product_id)
|
||||
->orderBy('name')->get(['id', 'name']),
|
||||
'locations' => Location::query()->where('active', true)->orderBy('name')->get(),
|
||||
'defaultLocationId' => $defaultLocationId,
|
||||
]);
|
||||
}
|
||||
|
||||
public function update(StoreProductionRequest $request, Production $production): RedirectResponse
|
||||
{
|
||||
$payload = $request->validatedPayload();
|
||||
|
||||
try {
|
||||
$production = $this->productionService->updateProduction(
|
||||
$production,
|
||||
[
|
||||
'product_id' => $payload['product_id'],
|
||||
'location_id' => $payload['location_id'],
|
||||
'produced_at' => $payload['produced_at'],
|
||||
'quantity' => $payload['quantity'],
|
||||
'notes' => $payload['notes'],
|
||||
],
|
||||
$payload['ingredient_lines'],
|
||||
(int) $request->user()->id
|
||||
);
|
||||
} catch (ValidationException $e) {
|
||||
return redirect()->back()->withInput()->withErrors($e->errors());
|
||||
}
|
||||
|
||||
if ($production->mhd_warning) {
|
||||
\Session::flash('alert-warning', __('Hinweis: Mindestens eine Rohstoff-Charge hat ein kürzeres MHD als das geplante Produkt-MHD.'));
|
||||
}
|
||||
\Session::flash('alert-save', '1');
|
||||
|
||||
return redirect()->route('admin.inventory.productions.show', $production);
|
||||
}
|
||||
|
||||
public function copy(Production $production): View
|
||||
{
|
||||
$production->load([
|
||||
'product',
|
||||
'productionIngredients.ingredient',
|
||||
'productionIngredients.stockEntry',
|
||||
]);
|
||||
|
||||
$defaultLocationId = $production->location_id;
|
||||
|
||||
return view('admin.inventory.productions.create', [
|
||||
'model' => $production,
|
||||
'products' => Product::query()->where('active', 1)->orderBy('name')->get(['id', 'name']),
|
||||
'locations' => Location::query()->where('active', true)->orderBy('name')->get(),
|
||||
'defaultLocationId' => $defaultLocationId,
|
||||
]);
|
||||
}
|
||||
|
||||
public function recipeJson(Request $request, Product $product): JsonResponse
|
||||
{
|
||||
$locationId = (int) $request->query('location_id', 0);
|
||||
$quantity = (int) $request->query('quantity', 1);
|
||||
if ($locationId < 1) {
|
||||
return response()->json(['message' => __('location_id erforderlich')], 422);
|
||||
}
|
||||
|
||||
return response()->json(
|
||||
$this->productionService->buildRecipePayload($product, $locationId, max(1, $quantity))
|
||||
);
|
||||
}
|
||||
}
|
||||
233
app/Http/Controllers/Admin/Inventory/StockEntryController.php
Normal file
233
app/Http/Controllers/Admin/Inventory/StockEntryController.php
Normal file
|
|
@ -0,0 +1,233 @@
|
|||
<?php
|
||||
|
||||
namespace App\Http\Controllers\Admin\Inventory;
|
||||
|
||||
use App\Http\Controllers\Controller;
|
||||
use App\Http\Requests\Inventory\ReceiveStockEntryRequest;
|
||||
use App\Http\Requests\Inventory\StoreStockEntryRequest;
|
||||
use App\Http\Requests\Inventory\UpdateStockEntryRequest;
|
||||
use App\Models\Ingredient;
|
||||
use App\Models\Location;
|
||||
use App\Models\MaterialQuality;
|
||||
use App\Models\PackagingItem;
|
||||
use App\Models\StockEntry;
|
||||
use App\Models\Supplier;
|
||||
use App\Repositories\StockEntryRepository;
|
||||
use Illuminate\Http\JsonResponse;
|
||||
use Illuminate\Http\RedirectResponse;
|
||||
use Illuminate\Http\Request;
|
||||
use Illuminate\View\View;
|
||||
|
||||
class StockEntryController extends Controller
|
||||
{
|
||||
public function __construct(
|
||||
protected StockEntryRepository $stockEntryRepository
|
||||
) {}
|
||||
|
||||
public function index(): View
|
||||
{
|
||||
return view('admin.inventory.stock-entries.index', array_merge($this->formSharedData(), [
|
||||
'values' => $this->stockEntryRepository->listForIndex(),
|
||||
]));
|
||||
}
|
||||
|
||||
public function create(): View|RedirectResponse
|
||||
{
|
||||
if (! auth()->user()->isAdmin()) {
|
||||
return redirect()->route('home');
|
||||
}
|
||||
|
||||
return view('admin.inventory.stock-entries.create', array_merge($this->formSharedData(), [
|
||||
'model' => new StockEntry([
|
||||
'ordered_at' => now()->toDateString(),
|
||||
'entry_type' => 'ingredient',
|
||||
]),
|
||||
]));
|
||||
}
|
||||
|
||||
public function store(StoreStockEntryRequest $request): RedirectResponse
|
||||
{
|
||||
if (! $request->user()->isAdmin()) {
|
||||
return redirect()->route('home');
|
||||
}
|
||||
|
||||
$data = $request->validatedPayload();
|
||||
$data['ordered_by'] = (int) auth()->id();
|
||||
|
||||
$this->stockEntryRepository->create($data);
|
||||
|
||||
\Session::flash('alert-save', '1');
|
||||
|
||||
return redirect()->route('admin.inventory.stock-entries.index');
|
||||
}
|
||||
|
||||
public function show(StockEntry $stockEntry): View
|
||||
{
|
||||
$stockEntry->load([
|
||||
'ingredient',
|
||||
'packagingItem.packagingMaterial',
|
||||
'supplier',
|
||||
'location',
|
||||
'quality',
|
||||
'orderedByUser.account',
|
||||
'receivedByUser.account',
|
||||
]);
|
||||
|
||||
return view('admin.inventory.stock-entries.show', array_merge($this->formSharedData(), [
|
||||
'model' => $stockEntry,
|
||||
'materialQualities' => MaterialQuality::query()->orderBy('pos')->orderBy('name')->get(),
|
||||
]));
|
||||
}
|
||||
|
||||
public function edit(StockEntry $stockEntry): View|RedirectResponse
|
||||
{
|
||||
if (! auth()->user()->isAdmin()) {
|
||||
return redirect()->route('home');
|
||||
}
|
||||
if (! $stockEntry->isPending()) {
|
||||
\Session::flash('alert-error', __('Nur offene Bestellungen können bearbeitet werden.'));
|
||||
|
||||
return redirect()->route('admin.inventory.stock-entries.show', $stockEntry);
|
||||
}
|
||||
|
||||
$stockEntry->load(['ingredient', 'packagingItem']);
|
||||
|
||||
return view('admin.inventory.stock-entries.edit', array_merge($this->formSharedData(), [
|
||||
'model' => $stockEntry,
|
||||
]));
|
||||
}
|
||||
|
||||
public function update(UpdateStockEntryRequest $request, StockEntry $stockEntry): RedirectResponse
|
||||
{
|
||||
if (! $request->user()->isAdmin()) {
|
||||
return redirect()->route('home');
|
||||
}
|
||||
if (! $stockEntry->isPending()) {
|
||||
\Session::flash('alert-error', __('Nur offene Bestellungen können bearbeitet werden.'));
|
||||
|
||||
return redirect()->route('admin.inventory.stock-entries.show', $stockEntry);
|
||||
}
|
||||
|
||||
$this->stockEntryRepository->update($stockEntry, $request->validatedPayload());
|
||||
|
||||
\Session::flash('alert-save', '1');
|
||||
|
||||
return redirect()->route('admin.inventory.stock-entries.index');
|
||||
}
|
||||
|
||||
public function destroy(StockEntry $stockEntry): RedirectResponse
|
||||
{
|
||||
if (! auth()->user()->isAdmin()) {
|
||||
return redirect()->route('home');
|
||||
}
|
||||
if (! $stockEntry->isPending()) {
|
||||
\Session::flash('alert-error', __('Nur offene Bestellungen können gelöscht werden.'));
|
||||
|
||||
return redirect()->route('admin.inventory.stock-entries.index');
|
||||
}
|
||||
|
||||
$stockEntry->delete();
|
||||
|
||||
\Session::flash('alert-success', __('Eintrag gelöscht'));
|
||||
|
||||
return redirect()->route('admin.inventory.stock-entries.index');
|
||||
}
|
||||
|
||||
public function receive(ReceiveStockEntryRequest $request, StockEntry $stockEntry): RedirectResponse
|
||||
{
|
||||
if (! $stockEntry->isPending()) {
|
||||
\Session::flash('alert-error', __('Eintrag nicht mehr offen.'));
|
||||
|
||||
return redirect()->route('admin.inventory.stock-entries.show', $stockEntry);
|
||||
}
|
||||
|
||||
$data = $request->validated();
|
||||
if ($stockEntry->entry_type !== 'ingredient') {
|
||||
$data['quality_id'] = null;
|
||||
$data['best_before'] = null;
|
||||
}
|
||||
|
||||
$this->stockEntryRepository->receive($stockEntry, $data);
|
||||
|
||||
\Session::flash('alert-save', '1');
|
||||
|
||||
return redirect()->route('admin.inventory.stock-entries.show', $stockEntry->fresh());
|
||||
}
|
||||
|
||||
public function searchIngredients(Request $request): JsonResponse
|
||||
{
|
||||
$term = trim((string) $request->query('q', ''));
|
||||
if (mb_strlen($term) < 1) {
|
||||
return response()->json(['results' => []]);
|
||||
}
|
||||
|
||||
$rows = Ingredient::query()
|
||||
->where('active', true)
|
||||
->where(function ($query) use ($term) {
|
||||
$query->where('name', 'like', '%'.$term.'%')
|
||||
->orWhere('inci', 'like', '%'.$term.'%');
|
||||
})
|
||||
->orderBy('name')
|
||||
->limit(30)
|
||||
->get(['id', 'name', 'inci']);
|
||||
|
||||
$results = $rows->map(function (Ingredient $i) {
|
||||
$text = $i->name;
|
||||
if ($i->inci) {
|
||||
$text .= ' ('.$i->inci.')';
|
||||
}
|
||||
|
||||
return ['id' => $i->id, 'text' => $text];
|
||||
})->values()->all();
|
||||
|
||||
return response()->json(['results' => $results]);
|
||||
}
|
||||
|
||||
public function searchPackagingItems(Request $request): JsonResponse
|
||||
{
|
||||
$term = trim((string) $request->query('q', ''));
|
||||
$entryType = $request->query('entry_type');
|
||||
|
||||
$categoryMap = [
|
||||
'packaging' => 'packaging',
|
||||
'shipping' => 'shipping',
|
||||
];
|
||||
|
||||
$query = PackagingItem::query()
|
||||
->where('active', true);
|
||||
|
||||
if ($entryType && isset($categoryMap[$entryType])) {
|
||||
$query->where('category', $categoryMap[$entryType]);
|
||||
}
|
||||
|
||||
if (mb_strlen($term) >= 1) {
|
||||
$query->where('name', 'like', '%'.$term.'%');
|
||||
}
|
||||
|
||||
$rows = $query->orderBy('name')->limit(30)->get(['id', 'name']);
|
||||
|
||||
$results = $rows->map(fn (PackagingItem $p) => [
|
||||
'id' => $p->id,
|
||||
'text' => $p->name,
|
||||
])->values()->all();
|
||||
|
||||
return response()->json(['results' => $results]);
|
||||
}
|
||||
|
||||
/**
|
||||
* @return array<string, mixed>
|
||||
*/
|
||||
protected function formSharedData(): array
|
||||
{
|
||||
return [
|
||||
'suppliers' => Supplier::query()->where('active', true)->orderBy('name')->get(),
|
||||
'locations' => Location::query()->where('active', true)->orderBy('name')->get(),
|
||||
'materialQualities' => MaterialQuality::query()->orderBy('pos')->orderBy('name')->get(),
|
||||
'entryTypeLabels' => [
|
||||
'ingredient' => __('Rohstoff'),
|
||||
'packaging' => __('Produktverpackung'),
|
||||
'shipping' => __('Versandverpackung'),
|
||||
],
|
||||
];
|
||||
}
|
||||
}
|
||||
|
|
@ -0,0 +1,59 @@
|
|||
<?php
|
||||
|
||||
namespace App\Http\Controllers\Admin\Inventory;
|
||||
|
||||
use App\Http\Controllers\Controller;
|
||||
use App\Http\Requests\Inventory\StoreSupplierCategoryRequest;
|
||||
use App\Http\Requests\Inventory\UpdateSupplierCategoryRequest;
|
||||
use App\Models\SupplierCategory;
|
||||
|
||||
class SupplierCategoryController extends Controller
|
||||
{
|
||||
public function index()
|
||||
{
|
||||
return view('admin.inventory.supplier-categories.index', [
|
||||
'values' => SupplierCategory::query()->orderBy('pos')->orderBy('name')->get(),
|
||||
]);
|
||||
}
|
||||
|
||||
public function create()
|
||||
{
|
||||
return view('admin.inventory.supplier-categories.form', [
|
||||
'model' => new SupplierCategory(['pos' => 0]),
|
||||
]);
|
||||
}
|
||||
|
||||
public function store(StoreSupplierCategoryRequest $request)
|
||||
{
|
||||
SupplierCategory::create($request->validated());
|
||||
|
||||
\Session::flash('alert-save', '1');
|
||||
|
||||
return redirect()->route('admin.inventory.supplier-categories.index');
|
||||
}
|
||||
|
||||
public function edit(SupplierCategory $supplierCategory)
|
||||
{
|
||||
return view('admin.inventory.supplier-categories.form', [
|
||||
'model' => $supplierCategory,
|
||||
]);
|
||||
}
|
||||
|
||||
public function update(UpdateSupplierCategoryRequest $request, SupplierCategory $supplierCategory)
|
||||
{
|
||||
$supplierCategory->update($request->validated());
|
||||
|
||||
\Session::flash('alert-save', '1');
|
||||
|
||||
return redirect()->route('admin.inventory.supplier-categories.index');
|
||||
}
|
||||
|
||||
public function destroy(SupplierCategory $supplierCategory)
|
||||
{
|
||||
$supplierCategory->delete();
|
||||
|
||||
\Session::flash('alert-success', __('Eintrag gelöscht'));
|
||||
|
||||
return redirect()->route('admin.inventory.supplier-categories.index');
|
||||
}
|
||||
}
|
||||
74
app/Http/Controllers/Admin/Inventory/SupplierController.php
Normal file
74
app/Http/Controllers/Admin/Inventory/SupplierController.php
Normal file
|
|
@ -0,0 +1,74 @@
|
|||
<?php
|
||||
|
||||
namespace App\Http\Controllers\Admin\Inventory;
|
||||
|
||||
use App\Http\Controllers\Controller;
|
||||
use App\Http\Requests\Inventory\StoreSupplierRequest;
|
||||
use App\Http\Requests\Inventory\UpdateSupplierRequest;
|
||||
use App\Models\Country;
|
||||
use App\Models\Supplier;
|
||||
use App\Models\SupplierCategory;
|
||||
use App\Repositories\SupplierRepository;
|
||||
|
||||
class SupplierController extends Controller
|
||||
{
|
||||
public function __construct(
|
||||
protected SupplierRepository $supplierRepository
|
||||
) {}
|
||||
|
||||
public function index()
|
||||
{
|
||||
return view('admin.inventory.suppliers.index', [
|
||||
'values' => Supplier::query()->with(['country', 'supplierCategories'])->orderBy('name')->get(),
|
||||
]);
|
||||
}
|
||||
|
||||
public function create()
|
||||
{
|
||||
$defaultCountryId = Country::where('code', 'DE')->value('id');
|
||||
|
||||
return view('admin.inventory.suppliers.form', [
|
||||
'model' => new Supplier(['active' => true, 'country_id' => $defaultCountryId]),
|
||||
'countries' => Country::query()->orderBy('de')->get(),
|
||||
'supplierCategories' => SupplierCategory::query()->orderBy('pos')->orderBy('name')->get(),
|
||||
]);
|
||||
}
|
||||
|
||||
public function store(StoreSupplierRequest $request)
|
||||
{
|
||||
$this->supplierRepository->create($request->validated());
|
||||
|
||||
\Session::flash('alert-save', '1');
|
||||
|
||||
return redirect()->route('admin.inventory.suppliers.index');
|
||||
}
|
||||
|
||||
public function edit(Supplier $supplier)
|
||||
{
|
||||
$supplier->load('supplierCategories');
|
||||
|
||||
return view('admin.inventory.suppliers.form', [
|
||||
'model' => $supplier,
|
||||
'countries' => Country::query()->orderBy('de')->get(),
|
||||
'supplierCategories' => SupplierCategory::query()->orderBy('pos')->orderBy('name')->get(),
|
||||
]);
|
||||
}
|
||||
|
||||
public function update(UpdateSupplierRequest $request, Supplier $supplier)
|
||||
{
|
||||
$this->supplierRepository->update($supplier, $request->validated());
|
||||
|
||||
\Session::flash('alert-save', '1');
|
||||
|
||||
return redirect()->route('admin.inventory.suppliers.index');
|
||||
}
|
||||
|
||||
public function destroy(Supplier $supplier)
|
||||
{
|
||||
$supplier->delete();
|
||||
|
||||
\Session::flash('alert-success', __('Eintrag gelöscht'));
|
||||
|
||||
return redirect()->route('admin.inventory.suppliers.index');
|
||||
}
|
||||
}
|
||||
41
app/Http/Controllers/Admin/PaymentReminderController.php
Normal file
41
app/Http/Controllers/Admin/PaymentReminderController.php
Normal file
|
|
@ -0,0 +1,41 @@
|
|||
<?php
|
||||
|
||||
namespace App\Http\Controllers\Admin;
|
||||
|
||||
use App\Http\Controllers\Controller;
|
||||
use App\Services\PaymentReminderService;
|
||||
use Illuminate\Http\Request;
|
||||
|
||||
class PaymentReminderController extends Controller
|
||||
{
|
||||
|
||||
/* not used at the moment */
|
||||
private $paymentReminderService;
|
||||
|
||||
public function __construct(PaymentReminderService $paymentReminderService)
|
||||
{
|
||||
$this->paymentReminderService = $paymentReminderService;
|
||||
}
|
||||
|
||||
/**
|
||||
* Zeige die Payment Reminders Übersicht
|
||||
*/
|
||||
public function index()
|
||||
{
|
||||
$detailedData = $this->paymentReminderService->getDetailedPaymentsData();
|
||||
$summaryData = $this->paymentReminderService->getAllOpenPayments();
|
||||
|
||||
// Statistiken für die Übersicht
|
||||
$totalPayments = collect($detailedData)->count();
|
||||
$totalAmount = collect($detailedData)->sum('amount');
|
||||
$clearingTypes = collect($detailedData)->groupBy('clearingtype')->map->count();
|
||||
|
||||
return view('admin.payment.reminder.index', compact(
|
||||
'detailedData',
|
||||
'summaryData',
|
||||
'totalPayments',
|
||||
'totalAmount',
|
||||
'clearingTypes'
|
||||
));
|
||||
}
|
||||
}
|
||||
|
|
@ -20,6 +20,11 @@ class AuthController extends Controller
|
|||
|
||||
public $successStatus = 200;
|
||||
|
||||
public function test(Request $request)
|
||||
{
|
||||
var_dump("testing");
|
||||
die("test");
|
||||
}
|
||||
|
||||
public function login(Request $request)
|
||||
{
|
||||
|
|
|
|||
|
|
@ -265,7 +265,7 @@ class ShoppingUserController extends Controller
|
|||
$shopping_user = ShoppingUser::create($data);
|
||||
|
||||
//Kundenhoheit prüfen
|
||||
$priority = CustomerPriority::checkOne($shopping_user, true, false);
|
||||
$priority = CustomerPriority::checkOne($shopping_user, true, false, true);
|
||||
\App\Services\Shop::newUserOrder($shopping_user->number);
|
||||
//exists //like //update
|
||||
$user = $this->prepareForShow($shopping_user);
|
||||
|
|
@ -595,7 +595,9 @@ class ShoppingUserController extends Controller
|
|||
if ($order->price != ($product->price * 100)) {
|
||||
$error[] = "different price: " . ($product->price * 100);
|
||||
}
|
||||
Yard::instance('shopping')->add($product->id, $product->name, (int) $order->qty, $product->price, ['image' => [], 'slug' => $product->slug, 'weight' => $product->weight]);
|
||||
|
||||
|
||||
Yard::instance('shopping')->add($product->id, $product->name, (int) $order->qty, $product->price, $product->tax, ['image' => [], 'slug' => $product->slug, 'weight' => $product->weight]);
|
||||
}
|
||||
}
|
||||
$order->message = $error;
|
||||
|
|
@ -604,7 +606,7 @@ class ShoppingUserController extends Controller
|
|||
|
||||
$ShippingCountry = ShippingCountry::whereCountryId($shopping_user->shipping_country_id)->first();
|
||||
if($ShippingCountry){
|
||||
Yard::instance('shopping')->setShippingCountryWithPrice($ShippingCountry->id);
|
||||
Yard::instance('shopping')->setShippingCountryWithPrice($ShippingCountry->id, 'ot');
|
||||
}
|
||||
$shopping_order = $this->makeShoppingOrder($shopping_user, $wp_invoice_path, $wp_notice);
|
||||
$this->orderStatusSendMail($shopping_order);
|
||||
|
|
|
|||
|
|
@ -3,9 +3,10 @@
|
|||
namespace App\Http\Controllers;
|
||||
|
||||
|
||||
use App\Models\Attribute;
|
||||
use App\Models\ProductAttribute;
|
||||
use Request;
|
||||
use App\Models\Attribute;
|
||||
use App\Models\AttributeType;
|
||||
use App\Models\ProductAttribute;
|
||||
|
||||
|
||||
class AttributeController extends Controller
|
||||
|
|
@ -13,40 +14,71 @@ class AttributeController extends Controller
|
|||
|
||||
public function __construct()
|
||||
{
|
||||
$this->middleware('admin');
|
||||
$this->middleware('copyreader');
|
||||
}
|
||||
|
||||
public function index()
|
||||
{
|
||||
|
||||
$data = [
|
||||
'values' => Attribute::all(),
|
||||
'attribute_types' => AttributeType::all(),
|
||||
'attributes' => Attribute::all(),
|
||||
'trans' => array_keys(config('localization.supportedLocales')),
|
||||
];
|
||||
return view('admin.attribute.index', $data);
|
||||
}
|
||||
|
||||
|
||||
|
||||
public function store()
|
||||
{
|
||||
|
||||
$data = Request::all();
|
||||
if($data['id'] == "new"){
|
||||
$model = Attribute::create([
|
||||
'parent_id' => null,
|
||||
'name' => $data['name'],
|
||||
'pos' => $data['pos'],
|
||||
'active' => isset($data['active']) ? true : false,
|
||||
]);
|
||||
}else{
|
||||
$model = Attribute::find($data['id']);
|
||||
$model->parent_id = null;
|
||||
$model->name = $data['name'];
|
||||
$model->pos = $data['pos'];
|
||||
$model->active = isset($data['active']) ? true : false;
|
||||
$model->save();
|
||||
}
|
||||
if(isset($data['action'])){
|
||||
|
||||
if(!empty($data['trans'])){
|
||||
if( $data['action'] === "attribute-type"){
|
||||
if($data['id'] == "new"){
|
||||
$model = AttributeType::create([
|
||||
'parent_id' => null,
|
||||
'name' => $data['name'],
|
||||
'description' => $data['description'],
|
||||
'pos' => $data['pos'],
|
||||
'active' => isset($data['active']) ? true : false,
|
||||
]);
|
||||
}else{
|
||||
$model = AttributeType::find($data['id']);
|
||||
$model->parent_id = null;
|
||||
$model->name = $data['name'];
|
||||
$model->description = $data['description'];
|
||||
$model->pos = $data['pos'];
|
||||
$model->active = isset($data['active']) ? true : false;
|
||||
$model->save();
|
||||
}
|
||||
}
|
||||
if($data['action'] === "attribute"){
|
||||
if($data['id'] == "new"){
|
||||
$model = Attribute::create([
|
||||
'parent_id' => null,
|
||||
'attribute_type_id' => $data['attribute_type_id'],
|
||||
'name' => $data['name'],
|
||||
'value' => $data['value'],
|
||||
'pos' => $data['pos'],
|
||||
'active' => isset($data['active']) ? true : false,
|
||||
]);
|
||||
}else{
|
||||
$model = Attribute::find($data['id']);
|
||||
$model->parent_id = null;
|
||||
$model->name = $data['name'];
|
||||
$model->value = $data['value'];
|
||||
$model->attribute_type_id = $data['attribute_type_id'];
|
||||
$model->pos = $data['pos'];
|
||||
$model->active = isset($data['active']) ? true : false;
|
||||
$model->save();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/*if(!empty($data['trans'])){
|
||||
$trans = [];
|
||||
foreach ($data['trans'] as $lang => $value){
|
||||
if($value && $value != null){
|
||||
|
|
@ -57,7 +89,7 @@ class AttributeController extends Controller
|
|||
$model->trans_name = $trans;
|
||||
$model->save();
|
||||
}
|
||||
}
|
||||
}*/
|
||||
|
||||
\Session()->flash('alert-save', '1');
|
||||
return redirect(route('admin_product_attributes'));
|
||||
|
|
@ -66,21 +98,41 @@ class AttributeController extends Controller
|
|||
}
|
||||
|
||||
|
||||
public function delete($id){
|
||||
public function delete($attr, $id){
|
||||
|
||||
if(ProductAttribute::where('attribute_id', $id)->count()){
|
||||
\Session()->flash('alert-error', 'Eintrag wird als Produktattribute verwendet');
|
||||
if($attr === 'type'){
|
||||
if(Attribute::where('attribute_type_id', $id)->count()){
|
||||
\Session()->flash('alert-error', 'Attribute Type wird bei den Attributen verwendet');
|
||||
return redirect(route('admin_product_attributes'));
|
||||
}
|
||||
/* if(AttributeType::where('parent_id', $id)->count()){
|
||||
\Session()->flash('alert-error', 'Eintrag wird als Main Attribute verwendet');
|
||||
return redirect(route('admin_product_attributes'));
|
||||
}
|
||||
*/
|
||||
$model = AttributeType::findOrFail($id);
|
||||
$model->delete();
|
||||
\Session()->flash('alert-success', 'Attribute Type gelöscht');
|
||||
return redirect(route('admin_product_attributes'));
|
||||
}
|
||||
/* if(Attribute::where('parent_id', $id)->count()){
|
||||
\Session()->flash('alert-error', 'Eintrag wird als Main Attribute verwendet');
|
||||
return redirect(route('admin_industry_sectors'));
|
||||
|
||||
if($attr === 'attr'){
|
||||
if(ProductAttribute::where('attribute_id', $id)->count()){
|
||||
\Session()->flash('alert-error', 'Attribute wird bei den Produkten verwendet');
|
||||
return redirect(route('admin_product_attributes'));
|
||||
}
|
||||
/* if(Attribute::where('parent_id', $id)->count()){
|
||||
\Session()->flash('alert-error', 'Eintrag wird als Main Attribute verwendet');
|
||||
return redirect(route('admin_product_attributes'));
|
||||
}
|
||||
*/
|
||||
$model = Attribute::findOrFail($id);
|
||||
$model->delete();
|
||||
\Session()->flash('alert-success', 'Eintrag gelöscht');
|
||||
return redirect(route('admin_product_attributes'));
|
||||
}
|
||||
*/
|
||||
$model = Attribute::findOrFail($id);
|
||||
$model->delete();
|
||||
\Session()->flash('alert-success', 'Eintrag gelöscht');
|
||||
return redirect(route('admin_product_attributes'));
|
||||
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
|
|
@ -5,7 +5,7 @@ namespace App\Http\Controllers;
|
|||
use App\Models\Category;
|
||||
use App\Models\IqImage;
|
||||
use App\Models\ProductCategory;
|
||||
use\Request;
|
||||
use Request;
|
||||
|
||||
|
||||
class CategoryController extends Controller
|
||||
|
|
@ -14,14 +14,14 @@ class CategoryController extends Controller
|
|||
|
||||
public function __construct()
|
||||
{
|
||||
$this->middleware('admin');
|
||||
$this->middleware('copyreader');
|
||||
}
|
||||
|
||||
public function index()
|
||||
{
|
||||
|
||||
$data = [
|
||||
'values' => Category::all(),
|
||||
'values' => Category::orderBy('pos', 'ASC')->get(),
|
||||
];
|
||||
return view('admin.category.index', $data);
|
||||
}
|
||||
|
|
@ -46,42 +46,66 @@ class CategoryController extends Controller
|
|||
{
|
||||
|
||||
$data = Request::all();
|
||||
$data['active'] = isset($data['active']) ? true : false;
|
||||
$data['parent_id'] = isset($data['parent_id']) ? $data['parent_id'] : null;
|
||||
if($data['id'] == "new"){
|
||||
$model = Category::create($data);
|
||||
}else{
|
||||
$model = Category::find($data['id']);
|
||||
$model->fill($data)->save();
|
||||
if($data['action'] === 'save-product_category'){
|
||||
|
||||
if($data['id'] === 'new'){
|
||||
$ProductCategory = ProductCategory::create([
|
||||
'pos' => $data['pos'],
|
||||
'product_id' => $data['product_id'],
|
||||
'category_id' => $data['category_id'],
|
||||
]);
|
||||
\Session()->flash('alert-save', '1');
|
||||
return redirect(route('admin_product_category_edit', [$ProductCategory->category_id]));
|
||||
}else{
|
||||
$ProductCategory = ProductCategory::findOrFail($data['id']);
|
||||
if($ProductCategory->category_id != $data['category_id']){
|
||||
abort(404);
|
||||
}
|
||||
$ProductCategory->pos = $data['pos'];
|
||||
$ProductCategory->product_id = $data['product_id'];
|
||||
$ProductCategory->save();
|
||||
\Session()->flash('alert-save', '1');
|
||||
return redirect(route('admin_product_category_edit', [$ProductCategory->category_id]));
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
$trans = [];
|
||||
if(!empty($data['trans_name'])){
|
||||
|
||||
foreach ($data['trans_name'] as $lang => $value){
|
||||
if($value && $value != null){
|
||||
$trans[$lang] = $value;
|
||||
if($data['action'] === 'save-form'){
|
||||
$data['active'] = isset($data['active']) ? true : false;
|
||||
$data['parent_id'] = isset($data['parent_id']) ? $data['parent_id'] : null;
|
||||
if($data['id'] == "new"){
|
||||
$model = Category::create($data);
|
||||
}else{
|
||||
$model = Category::find($data['id']);
|
||||
$model->fill($data)->save();
|
||||
}
|
||||
|
||||
$trans = [];
|
||||
if(!empty($data['trans_name'])){
|
||||
|
||||
foreach ($data['trans_name'] as $lang => $value){
|
||||
if($value && $value != null){
|
||||
$trans[$lang] = $value;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
$model->trans_name = $trans;
|
||||
$model->save();
|
||||
|
||||
$trans = [];
|
||||
if(!empty($data['trans_headline'])){
|
||||
foreach ($data['trans_headline'] as $lang => $value){
|
||||
if($value && $value != null){
|
||||
$trans[$lang] = $value;
|
||||
$model->trans_name = $trans;
|
||||
$model->save();
|
||||
|
||||
$trans = [];
|
||||
if(!empty($data['trans_headline'])){
|
||||
foreach ($data['trans_headline'] as $lang => $value){
|
||||
if($value && $value != null){
|
||||
$trans[$lang] = $value;
|
||||
}
|
||||
}
|
||||
}
|
||||
$model->trans_headline = $trans;
|
||||
$model->save();
|
||||
|
||||
\Session()->flash('alert-save', '1');
|
||||
return redirect(route('admin_product_categories'));
|
||||
}
|
||||
$model->trans_headline = $trans;
|
||||
$model->save();
|
||||
|
||||
\Session()->flash('alert-save', '1');
|
||||
return redirect(route('admin_product_categories'));
|
||||
|
||||
|
||||
}
|
||||
|
||||
|
||||
|
|
@ -157,7 +181,7 @@ class CategoryController extends Controller
|
|||
return redirect(route('admin_product_category_edit', [$category->id]));
|
||||
|
||||
}
|
||||
catch (Exception $e) {
|
||||
catch (\Exception $e) {
|
||||
\Session()->flash('alert-danger', "Fehler".$e);
|
||||
return redirect(route('admin_product_category_edit', [$category->id]));
|
||||
}
|
||||
|
|
|
|||
|
|
@ -52,6 +52,8 @@ class CountryController extends Controller
|
|||
|
||||
$data['active'] = isset($data['active']) ? true : false;
|
||||
$data['switch'] = isset($data['switch']) ? true : false;
|
||||
$data['translate'] = isset($data['translate']) ? true : false;
|
||||
$data['eu_country'] = isset($data['eu_country']) ? true : false;
|
||||
$data['own_eur'] = isset($data['own_eur']) ? true : false;
|
||||
$data['currency'] = isset($data['currency']) ? true : false;
|
||||
$data['currency_faktor'] = $data['currency_faktor'] == "" ? null : reFormatNumber($data['currency_faktor']);
|
||||
|
|
|
|||
|
|
@ -43,6 +43,7 @@ class CronController extends Controller
|
|||
if($key !== 'key'){
|
||||
abort(404);
|
||||
}
|
||||
die('not in use');
|
||||
if($action === 'check_payments_account'){
|
||||
$this->checkPaymentsAccounts();
|
||||
}
|
||||
|
|
@ -54,6 +55,8 @@ class CronController extends Controller
|
|||
*/
|
||||
public function checkConfirmation()
|
||||
{
|
||||
/*
|
||||
User Register sind in der DB UserRegister, erst bei bestätigung wird es in die User DB übertragen
|
||||
$now = date('Y-m-d H:i:s');
|
||||
$next = date('Y-m-d H:i:s', strtotime('+3 week'));
|
||||
|
||||
|
|
@ -68,12 +71,12 @@ class CronController extends Controller
|
|||
}
|
||||
//send new remider
|
||||
if ($user->confirmation_code_remider == 0) {
|
||||
Mail::to($user->email)->send(new MailVerifyAccount($user->confirmation_code, $user));
|
||||
Mail::to($user->email)->bcc(config('app.info_mail'))->send(new MailVerifyAccount($user->confirmation_code, $user));
|
||||
$user->confirmation_code_to = $next;
|
||||
$user->confirmation_code_remider = 1;
|
||||
$user->save();
|
||||
}
|
||||
}
|
||||
}*/
|
||||
return "TOSK";
|
||||
}
|
||||
|
||||
|
|
@ -218,7 +221,7 @@ class CronController extends Controller
|
|||
]);
|
||||
try{
|
||||
if($status >= 34){
|
||||
Mail::to($user->email)->bcc(config('app.default_mail'))->send(new MailCustomMessage($user, $data, $sender, false));
|
||||
Mail::to($user->email)->bcc(config('app.info_mail'))->send(new MailCustomMessage($user, $data, $sender, false));
|
||||
}else{
|
||||
Mail::to($user->email)->send(new MailCustomMessage($user, $data, $sender, false));
|
||||
}
|
||||
|
|
|
|||
|
|
@ -15,7 +15,7 @@ class DataTableController extends Controller
|
|||
|
||||
public function getUsers()
|
||||
{
|
||||
$query = User::with('account')->select('users.*')->where('users.deleted_at', '=', null)->where('users.admin', "<", 4);
|
||||
$query = User::with('account')->select('users.*')->where('users.deleted_at', '=', null)->where('users.admin', "<", 10);
|
||||
|
||||
return \DataTables::eloquent($query)
|
||||
->addColumn('first_name', function (User $user) {
|
||||
|
|
@ -30,6 +30,9 @@ class DataTableController extends Controller
|
|||
->addColumn('admin', function (User $user) {
|
||||
return '<a href="#" data-toggle="modal" data-target="#modals-admin" data-id="'.$user->id.'" data-email="'.$user->email.'" data-admin="'.$user->admin.'">'.HTMLHelper::getRoleLabel($user->admin).'</a>';
|
||||
})
|
||||
->addColumn('role', function (User $user) {
|
||||
return $user->user_level ? $user->user_level->name : '';
|
||||
})
|
||||
->addColumn('confirmed', function (User $user) {
|
||||
$date = $user->getConfirmationDateFormat();
|
||||
$link = '<a href="#" data-toggle="modal" data-target="#modals-confirmed" data-id="'.$user->id.'" data-email="'.$user->email.'" data-confirmed="'.$user->confirmed.'" data-confirmation_date="'.$date.'">';
|
||||
|
|
@ -71,6 +74,9 @@ class DataTableController extends Controller
|
|||
}
|
||||
return "-";
|
||||
})*/
|
||||
->addColumn('country', function (User $user) {
|
||||
return ($user->account && $user->account->country) ? $user->account->country->de : '';
|
||||
})
|
||||
->addColumn('my_payment_methods', function (User $user) {
|
||||
$payment_methods = json_encode($user->payment_methods);
|
||||
$link = '<a href="#" data-toggle="modal" data-target="#modals-payment_methods" data-id="'.$user->id.'" data-email="'.$user->email.'" data-payment_methods="'.htmlspecialchars($payment_methods).'">';
|
||||
|
|
|
|||
|
|
@ -2,11 +2,15 @@
|
|||
|
||||
namespace App\Http\Controllers;
|
||||
|
||||
use Storage;
|
||||
use Response;
|
||||
use App\Models\File;
|
||||
use App\Models\ShoppingOrder;
|
||||
use App\Models\UserCredit;
|
||||
use App\Services\Credit;
|
||||
use App\Services\Invoice;
|
||||
use App\Services\PDFMerger;
|
||||
use Auth;
|
||||
use Response;
|
||||
use Storage;
|
||||
|
||||
class FileController extends Controller
|
||||
{
|
||||
|
|
@ -15,93 +19,126 @@ class FileController extends Controller
|
|||
*
|
||||
* @return void
|
||||
*/
|
||||
public function __construct()
|
||||
public function __construct() {}
|
||||
|
||||
private function isPermission($user_id)
|
||||
{
|
||||
}
|
||||
|
||||
private function isPermission($user_id){
|
||||
|
||||
if(Auth::user()->isAdmin() || $user_id == Auth::user()->id){
|
||||
if (Auth::user()->isAdmin() || $user_id == Auth::user()->id) {
|
||||
return true;
|
||||
}
|
||||
abort(404);
|
||||
abort(404);
|
||||
|
||||
}
|
||||
|
||||
public function show($id = null, $disk = null, $do='file')
|
||||
public function show($id = null, $disk = null, $do = 'file')
|
||||
{
|
||||
$path = "";
|
||||
$filename = "";
|
||||
$path = '';
|
||||
$filename = '';
|
||||
|
||||
if($disk === 'user'){
|
||||
$file = \App\Models\File::findOrFail($id);
|
||||
if ($disk === 'user') {
|
||||
$file = File::findOrFail($id);
|
||||
$this->isPermission($file->user_id);
|
||||
$path = Storage::disk($disk)->path($file->dir.$file->filename);
|
||||
if (file_exists($path)) {
|
||||
return Response::file($path);
|
||||
}
|
||||
}
|
||||
|
||||
if ($disk === 'invoice'){
|
||||
$shopping_order = \App\Models\ShoppingOrder::findOrFail($id);
|
||||
$this->isPermission($shopping_order->auth_user_id);
|
||||
$filename = Invoice::getFilename($shopping_order);
|
||||
$path = Invoice::getDownloadPath($shopping_order);
|
||||
if (!Storage::disk('public')->exists($path)) {
|
||||
return Response::make('File no found.', 404);
|
||||
}
|
||||
$file = Storage::disk('public')->get($path);
|
||||
$type = Storage::disk('public')->mimeType($path);
|
||||
|
||||
if($do === 'download'){
|
||||
return Response::make($file, 200)
|
||||
->header("Content-Type", $type)
|
||||
->header('Content-disposition', 'attachment; filename="'.$filename.'"');
|
||||
/* $full_path = Invoice::getDownloadPath($shopping_order, true);
|
||||
$he
|
||||
if (file_exists($full_path)) {
|
||||
return Response::download($full_path, $filename);
|
||||
}*/
|
||||
}
|
||||
if($do === 'stream'){
|
||||
return Response::make($file, 200)
|
||||
->header("Content-Type", $type)
|
||||
->header('Content-disposition','filename="'.$filename.'"');
|
||||
}
|
||||
|
||||
if ($disk === 'invoice') {
|
||||
$shopping_order = ShoppingOrder::findOrFail($id);
|
||||
$this->isPermission($shopping_order->auth_user_id);
|
||||
$filename = Invoice::getFilename($shopping_order);
|
||||
$path = Invoice::getDownloadPath($shopping_order);
|
||||
}
|
||||
|
||||
if ($disk === 'credit'){
|
||||
$UserCredit = \App\Models\UserCredit::findOrFail($id);
|
||||
if ($disk === 'delivery') {
|
||||
$shopping_order = ShoppingOrder::findOrFail($id);
|
||||
$this->isPermission($shopping_order->auth_user_id);
|
||||
$filename = Invoice::getDeliveryFilename($shopping_order);
|
||||
$path = Invoice::getDownloadPathDelivery($shopping_order);
|
||||
}
|
||||
|
||||
if ($disk === 'cancellation') {
|
||||
$shopping_order = ShoppingOrder::findOrFail($id);
|
||||
$this->isPermission($shopping_order->auth_user_id);
|
||||
$filename = Invoice::getCancellationFilename($shopping_order);
|
||||
$path = Invoice::getCancellationDownloadPath($shopping_order);
|
||||
}
|
||||
|
||||
if ($disk === 'invoice_delivery') {
|
||||
$shopping_order = ShoppingOrder::findOrFail($id);
|
||||
$this->isPermission($shopping_order->auth_user_id);
|
||||
|
||||
$ifilename = Invoice::getFilename($shopping_order);
|
||||
$ipath = Invoice::getDownloadPath($shopping_order, true);
|
||||
$dfilename = Invoice::getDeliveryFilename($shopping_order);
|
||||
$dpath = Invoice::getDownloadPathDelivery($shopping_order, true);
|
||||
|
||||
$oMerger = new PDFMerger;
|
||||
$oMerger->init();
|
||||
|
||||
$oMerger->addPDF($ipath);
|
||||
$oMerger->addPDF($dpath);
|
||||
$filename = str_replace('Rechnung-', 'Rechnung-Lieferschein-', $ifilename);
|
||||
$oMerger->setFileName($filename);
|
||||
$oMerger->merge();
|
||||
$file = $oMerger->output();
|
||||
|
||||
return Response::make($file, 200)
|
||||
->header('Content-Type', 'application/pdf')
|
||||
->header('Content-disposition', 'attachment; filename="'.$filename.'"');
|
||||
}
|
||||
|
||||
if ($disk === 'credit') {
|
||||
$UserCredit = UserCredit::findOrFail($id);
|
||||
$this->isPermission($UserCredit->auth_user_id);
|
||||
|
||||
$filename = Credit::getFilename($UserCredit);
|
||||
$filename = Credit::getFilename($UserCredit);
|
||||
$path = Credit::getDownloadPath($UserCredit);
|
||||
}
|
||||
|
||||
if (!Storage::disk('public')->exists($path)) {
|
||||
return Response::make('File no found.', 404);
|
||||
}
|
||||
$file = Storage::disk('public')->get($path);
|
||||
$type = Storage::disk('public')->mimeType($path);
|
||||
if (! Storage::disk('public')->exists($path)) {
|
||||
return Response::make('File no found.', 404);
|
||||
}
|
||||
|
||||
if($do === 'download'){
|
||||
return Response::make($file, 200)
|
||||
->header("Content-Type", $type)
|
||||
->header('Content-disposition', 'attachment; filename="'.$filename.'"');
|
||||
/* $full_path = Invoice::getDownloadPath($shopping_order, true);
|
||||
$he
|
||||
if (file_exists($full_path)) {
|
||||
return Response::download($full_path, $filename);
|
||||
}*/
|
||||
}
|
||||
if($do === 'stream'){
|
||||
return Response::make($file, 200)
|
||||
->header("Content-Type", $type)
|
||||
->header('Content-disposition','filename="'.$filename.'"');
|
||||
}
|
||||
|
||||
$file = Storage::disk('public')->get($path);
|
||||
$mime = Storage::disk('public')->mimeType($path);
|
||||
|
||||
if ($do === 'download') {
|
||||
return Response::make($file, 200)
|
||||
->header('Content-Type', $mime)
|
||||
->header('Content-disposition', 'attachment; filename="'.$filename.'"');
|
||||
/* $full_path = Invoice::getDownloadPath($shopping_order, true);
|
||||
$he
|
||||
if (file_exists($full_path)) {
|
||||
return Response::download($full_path, $filename);
|
||||
}*/
|
||||
}
|
||||
if ($do === 'stream') {
|
||||
return Response::make($file, 200)
|
||||
->header('Content-Type', $mime)
|
||||
->header('Content-disposition', 'filename="'.$filename.'"');
|
||||
}
|
||||
|
||||
if ($do === 'file') {
|
||||
return Response::make($file, 200)
|
||||
->header('Content-Type', $mime)
|
||||
->header('Content-disposition', 'filename="'.$filename.'"');
|
||||
}
|
||||
if ($do === 'image') {
|
||||
return Response::make($file, 200)
|
||||
->header('Content-Type', $mime);
|
||||
}
|
||||
if ($do === 'pdf') {
|
||||
$path = storage_path().'/app/public/'.$path;
|
||||
$headers = [
|
||||
'Content-Type:'.$mime,
|
||||
// 'Content-Length: ' . $file->size
|
||||
// 'Content-Disposition: ' . $stream . '; filename=' . $file->original_name
|
||||
];
|
||||
|
||||
return Response::download($path, $filename, $headers);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -90,34 +90,7 @@ class HomeController extends Controller
|
|||
}
|
||||
|
||||
|
||||
public function verify($confirmation_code){
|
||||
if( ! $confirmation_code)
|
||||
{
|
||||
return redirect('/status/error');
|
||||
}
|
||||
|
||||
$user = User::whereConfirmationCode($confirmation_code)->first();
|
||||
|
||||
if ( ! $user)
|
||||
{
|
||||
return redirect('/status/not/found');
|
||||
}
|
||||
if($user->confirmed === 0){
|
||||
$user->confirmed = 1;
|
||||
//kill after wizzard!
|
||||
// $user->confirmation_code = null;
|
||||
// $user->confirmation_code_to = null;
|
||||
// $user->confirmation_code_remider = 0;
|
||||
$user->confirmation_date = now();
|
||||
}
|
||||
|
||||
$user->save();
|
||||
|
||||
//Login!
|
||||
Auth::login($user);
|
||||
|
||||
return redirect('/home');
|
||||
}
|
||||
|
||||
|
||||
public function statusRegister(){
|
||||
return view('status.status_register');
|
||||
|
|
|
|||
|
|
@ -84,6 +84,7 @@ class ImportProductController extends Controller
|
|||
|
||||
ProductImage::create([
|
||||
'product_id' => $product->id,
|
||||
'type' => 'product', // 'product',
|
||||
'filename' => $name,
|
||||
'original_name' => $original_name,
|
||||
'ext' => $ext,
|
||||
|
|
|
|||
|
|
@ -2,21 +2,15 @@
|
|||
|
||||
namespace App\Http\Controllers;
|
||||
|
||||
use App\Models\Category;
|
||||
use App\Models\Ingredient;
|
||||
use App\Models\IqImage;
|
||||
use App\Models\ProductCategory;
|
||||
use App\Models\ProductIngredient;
|
||||
use Request;
|
||||
|
||||
|
||||
class IngredientController extends Controller
|
||||
{
|
||||
|
||||
|
||||
public function __construct()
|
||||
{
|
||||
$this->middleware('admin');
|
||||
$this->middleware('copyreader');
|
||||
}
|
||||
|
||||
public function index()
|
||||
|
|
@ -25,22 +19,24 @@ class IngredientController extends Controller
|
|||
$data = [
|
||||
'values' => Ingredient::all(),
|
||||
];
|
||||
|
||||
return view('admin.ingredient.index', $data);
|
||||
}
|
||||
|
||||
public function edit($id)
|
||||
{
|
||||
if($id === "new"){
|
||||
$model = new Ingredient();
|
||||
if ($id === 'new') {
|
||||
$model = new Ingredient;
|
||||
$model->active = true;
|
||||
}else{
|
||||
} else {
|
||||
$model = Ingredient::findOrFail($id);
|
||||
}
|
||||
$data = [
|
||||
'model' => $model,
|
||||
//'trans' => array_keys(config('localization.supportedLocales')),
|
||||
// 'trans' => array_keys(config('localization.supportedLocales')),
|
||||
|
||||
];
|
||||
|
||||
return view('admin.ingredient.edit', $data);
|
||||
}
|
||||
|
||||
|
|
@ -49,30 +45,42 @@ class IngredientController extends Controller
|
|||
|
||||
$data = Request::all();
|
||||
$data['active'] = isset($data['active']) ? true : false;
|
||||
if($data['id'] === "new"){
|
||||
if (isset($data['default_factor']) && $data['default_factor'] !== '') {
|
||||
$data['default_factor'] = reFormatNumber($data['default_factor']) ?: 1.10;
|
||||
}
|
||||
if (isset($data['min_stock_alert']) && $data['min_stock_alert'] === '') {
|
||||
$data['min_stock_alert'] = null;
|
||||
} elseif (isset($data['min_stock_alert']) && $data['min_stock_alert'] !== null) {
|
||||
$data['min_stock_alert'] = reFormatNumber($data['min_stock_alert']);
|
||||
}
|
||||
if (empty($data['material_quality_id'])) {
|
||||
$data['material_quality_id'] = null;
|
||||
}
|
||||
if ($data['id'] === 'new') {
|
||||
$model = Ingredient::create($data);
|
||||
}else{
|
||||
} else {
|
||||
$model = Ingredient::find($data['id']);
|
||||
$model->fill($data)->save();
|
||||
}
|
||||
|
||||
\Session()->flash('alert-save', '1');
|
||||
return redirect(route('admin_product_ingredients'));
|
||||
|
||||
return redirect(route('admin_product_ingredients'));
|
||||
|
||||
}
|
||||
|
||||
public function delete($id){
|
||||
public function delete($id)
|
||||
{
|
||||
|
||||
if(ProductIngredient::where('ingredient_id', $id)->count()) {
|
||||
if (ProductIngredient::where('ingredient_id', $id)->count()) {
|
||||
\Session()->flash('alert-error', 'Eintrag wird als Produkt-Inhaltsstoff verwendet');
|
||||
|
||||
return redirect(route('admin_product_ingredients'));
|
||||
}
|
||||
$model = Ingredient::findOrFail($id);
|
||||
$model->delete();
|
||||
\Session()->flash('alert-success', 'Eintrag gelöscht');
|
||||
|
||||
return redirect(route('admin_product_ingredients'));
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -2,20 +2,23 @@
|
|||
|
||||
namespace App\Http\Controllers;
|
||||
|
||||
use App\Exports\ExcelExport;
|
||||
use Request;
|
||||
use App\User;
|
||||
use Validator;
|
||||
use App\Services\SysLog;
|
||||
use App\Models\UserAccount;
|
||||
use App\Models\UserHistory;
|
||||
use Maatwebsite\Excel\Facades\Excel;
|
||||
use App\Services\UserService;
|
||||
use App\Mail\MailAccountActive;
|
||||
use App\Mail\MailCustomMessage;
|
||||
use App\Mail\MailVerifyAccount;
|
||||
use App\Mail\MailVerifyContact;
|
||||
use App\Mail\MailAccountActive;
|
||||
use App\Models\UserAccount;
|
||||
use App\Models\UserHistory;
|
||||
use App\Repositories\ContractPDFRepository;
|
||||
use App\Models\UserWhitelabelProduct;
|
||||
use App\Repositories\UserRepository;
|
||||
use App\Services\SysLog;
|
||||
use App\Services\UserService;
|
||||
use App\User;
|
||||
use Illuminate\Support\Facades\Mail;
|
||||
use Request;
|
||||
use Validator;
|
||||
use App\Repositories\ContractPDFRepository;
|
||||
|
||||
class LeadController extends Controller
|
||||
{
|
||||
|
|
@ -33,13 +36,14 @@ class LeadController extends Controller
|
|||
*/
|
||||
public function index()
|
||||
{
|
||||
$this->setFilterVars();
|
||||
$data = [
|
||||
'values' => User::where('admin', '=', 0)->where('confirmation_code_remider', '!=', 2)->get(),
|
||||
|
||||
];
|
||||
return view('admin.lead.index', $data);
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* @param $id
|
||||
* @return \Illuminate\Contracts\View\Factory|\Illuminate\View\View
|
||||
|
|
@ -122,7 +126,17 @@ class LeadController extends Controller
|
|||
|
||||
$data = Request::all();
|
||||
$show = Request::get('show');
|
||||
dd($data);
|
||||
|
||||
if(isset($data['action']) && $data['action'] == "reverse_charge_validate" && isset($data['user_id'])){
|
||||
$user = User::findOrFail($data['user_id']);
|
||||
return $this->userRepo->reverse_charge_validate($data, $user, route('admin_lead_edit', [$user->id]));
|
||||
}
|
||||
|
||||
if(isset($data['action']) && $data['action'] == "reverse_charge_delete" && isset($data['user_id'])){
|
||||
$user = User::findOrFail($data['user_id']);
|
||||
return $this->userRepo->reverse_charge_delete($data, $user, route('admin_lead_edit', [$user->id]));
|
||||
}
|
||||
|
||||
if ($data['user_id'] === "new" || $data['user_id'] == 0) {
|
||||
$rules = array(
|
||||
'salutation' => 'required',
|
||||
|
|
@ -188,6 +202,7 @@ class LeadController extends Controller
|
|||
if(isset($data['m_data_edit']) && $data['m_data_edit'] === "TSOK"){
|
||||
$user = $this->userRepo->getModel();
|
||||
$user->m_level = isset($data['m_level']) ? $data['m_level'] : NULL;
|
||||
$user->lead_type_id = isset($data['lead_type_id']) ? $data['lead_type_id'] : NULL;
|
||||
$user->m_sponsor = isset($data['m_sponsor']) ? $data['m_sponsor'] : NULL;
|
||||
$user->save();
|
||||
}
|
||||
|
|
@ -203,7 +218,7 @@ class LeadController extends Controller
|
|||
//10 == start wizard form create Lead
|
||||
$user->wizard = 10;
|
||||
$user->save();
|
||||
Mail::to($user->email)->send(new MailVerifyContact($confirmation_code, $user));
|
||||
Mail::to($user->email)->bcc(config('app.info_mail'))->send(new MailVerifyContact($confirmation_code, $user));
|
||||
|
||||
\Session()->flash('alert-save', true);
|
||||
return redirect(route('admin_leads'));
|
||||
|
|
@ -216,146 +231,142 @@ class LeadController extends Controller
|
|||
|
||||
|
||||
}
|
||||
//user released when register is complete
|
||||
public function released($action, $id){
|
||||
|
||||
$user = User::findOrFail($id);
|
||||
if($action === 'completed'){
|
||||
$validator = Validator::make(Request::all(), []);
|
||||
/*if(!$user->m_sponsor){
|
||||
$validator->errors()->add('m_sponsor', __('Vertriebspartner hat keinen Sponsor.'));
|
||||
}*/
|
||||
if(!$user->account->m_first_name){
|
||||
$validator->errors()->add('m_first_name', __('Vertriebspartner hat keinen Vornamen.'));
|
||||
}
|
||||
if(!$user->account->m_last_name){
|
||||
$validator->errors()->add('m_last_name', __('Vertriebspartner hat keinen Nachnamen.'));
|
||||
}
|
||||
|
||||
if ($validator->errors()->count()) {
|
||||
return back()->withErrors($validator)->withRequest(Request::all());
|
||||
}
|
||||
|
||||
if(!$user->account->m_account){
|
||||
$user->account->m_account = UserAccount::withTrashed()->max('m_account') +1;
|
||||
$user->account->save();
|
||||
}
|
||||
|
||||
//create PDF
|
||||
$pdf = new ContractPDFRepository($user);
|
||||
$pdf->_set('disk', 'user');
|
||||
$pdf->_set('dir', '/'.$user->id.'/documents/');
|
||||
$pdf->_set('user_id', $user->id);
|
||||
$pdf->_set('identifier', 'contract');
|
||||
$pdf->createContractPDF();
|
||||
|
||||
//set wizard tp payments
|
||||
$user->wizard = 20;
|
||||
$user->active = 1;
|
||||
$user->active_date = now();
|
||||
$user->confirmation_code = null;
|
||||
$user->confirmation_code_to = null;
|
||||
$user->confirmation_code_remider = 0;
|
||||
$user->save();
|
||||
|
||||
//mail with code to user?
|
||||
try {
|
||||
Mail::to($user->email)->send(new MailAccountActive($user));
|
||||
}
|
||||
catch(\Exception $e){
|
||||
SysLog::action('released', 'admin_lead', 5)
|
||||
->setUserId($user->id)
|
||||
->setModel($user->id, User::class)
|
||||
->setMessage('Error send released E-Mail: '.$e->getMessage())
|
||||
->save();
|
||||
}
|
||||
|
||||
UserHistory::create(['user_id' => $user->id, 'action'=>'released_completed', 'status'=>0]);
|
||||
\Session()->flash('alert-success', "Vertriebspartner freigeschaltet!");
|
||||
public function update()
|
||||
{
|
||||
$data = Request::all();
|
||||
$show = Request::get('show');
|
||||
if(!isset($data['user_id']) || $data['user_id'] === "new" || $data['user_id'] == 0){
|
||||
abort(404, 'User not found');
|
||||
}
|
||||
$user = User::findOrFail($data['user_id']);
|
||||
|
||||
if($action === 'incomplete'){
|
||||
if(isset($data['action'])){
|
||||
|
||||
|
||||
//reset release
|
||||
$confirmation_code = UserService::createConfirmationCode();
|
||||
$user->confirmation_code = $confirmation_code;
|
||||
$user->confirmation_code_to = date('Y-m-d H:i:s', strtotime('+1 week'));
|
||||
$user->confirmation_code_remider = 0;
|
||||
$user->wizard = 1;
|
||||
$user->release_account = null;
|
||||
$user->save();
|
||||
|
||||
$input = Request::all();
|
||||
$data = [
|
||||
'subject' => $input['account_incomplete_subject'],
|
||||
'message' => $input['account_incomplete_message'],
|
||||
'confirmation_code' => $confirmation_code,
|
||||
];
|
||||
try {
|
||||
Mail::to($user->email)->send(new MailCustomMessage($user, $data, \Auth::user(), true));
|
||||
//add whitelabel products
|
||||
if($data['action'] === 'add_whitelabel_products'){
|
||||
if(isset($data['whitelabel_products']) && is_array($data['whitelabel_products'])){
|
||||
foreach ($data['whitelabel_products'] as $product_id){
|
||||
$user->whitelabel_products()->create(['product_id' => $product_id]);
|
||||
}
|
||||
}
|
||||
\Session()->flash('alert-save', true);
|
||||
}
|
||||
catch(\Exception $e){
|
||||
SysLog::action('released_incomplete', 'admin_lead', 5)
|
||||
->setUserId($user->id)
|
||||
->setModel($user->id, User::class)
|
||||
->setMessage('Error send released_incomplete E-Mail: '.$e->getMessage())
|
||||
->save();
|
||||
//remove whitelabel products
|
||||
if($data['action'] === 'remove_whitelabel_products'){
|
||||
if(isset($data['whitelabel_products']) && is_array($data['whitelabel_products'])){
|
||||
$user->whitelabel_products()->whereIn('product_id', $data['whitelabel_products'])->delete();
|
||||
}
|
||||
\Session()->flash('alert-success', "Produkt gelöscht");
|
||||
}
|
||||
if($data['action'] === 'upload_white_label_image'){
|
||||
//id == user_whitelabel_product_id
|
||||
$whitelabel_product = UserWhitelabelProduct::findOrFail($data['id']);
|
||||
if($whitelabel_product && $user->id == $whitelabel_product->user_id){
|
||||
return \App\Services\ProductImage::imageUpload('user_wl_product', $whitelabel_product, Request::get('upload_type'));
|
||||
}
|
||||
}
|
||||
//update whitelabel products
|
||||
if($data['action'] === 'update_whitelabel_products'){
|
||||
if(isset($data['image_wl_attributes']) && is_array($data['image_wl_attributes'])){
|
||||
foreach ( $user->whitelabel_products as $wl_product){
|
||||
foreach ($wl_product->whitelabel_images as $wl_image) {
|
||||
$wl_image->update([
|
||||
'attributes' => isset($data['image_wl_attributes'][$wl_image->id]) ? $data['image_wl_attributes'][$wl_image->id] : NULL,
|
||||
]);
|
||||
}
|
||||
}
|
||||
}
|
||||
\Session()->flash('alert-save', true);
|
||||
}
|
||||
UserHistory::create(['user_id' => $user->id, 'action'=>'released_incomplete', 'status'=>0]);
|
||||
\Session()->flash('alert-success', "E-Mail an Vertriebspartner gesendet.");
|
||||
|
||||
}
|
||||
return redirect(route('admin_lead_edit', [$user->id]));
|
||||
return redirect(route('admin_lead_edit', [$user->id])."?show=".$show);
|
||||
}
|
||||
|
||||
public function remove($action, $user_id, $id, $mid=null){
|
||||
$show = Request::get('show');
|
||||
$user = User::findOrFail($user_id);
|
||||
|
||||
//send new verfified mail to user
|
||||
public function newMailVerified($id){
|
||||
|
||||
$user = User::findOrFail($id);
|
||||
|
||||
$confirmation_code = UserService::createConfirmationCode();
|
||||
$user->confirmation_code = $confirmation_code;
|
||||
$user->confirmation_code_to = date('Y-m-d H:i:s', strtotime('+1 week'));
|
||||
$user->confirmation_code_remider = 0;
|
||||
$user->save();
|
||||
|
||||
try {
|
||||
Mail::to($user->email)->send(new MailVerifyAccount($confirmation_code, $user));
|
||||
if($action === 'remove_whitelabel_label'){
|
||||
$model = $user->whitelabel_products()->where('id', $id)->first();
|
||||
return \App\Services\ProductImage::imageDelete('user_wl_image', $model, $mid);
|
||||
}
|
||||
catch(\Exception $e){
|
||||
SysLog::action('new_mail_verified', 'admin_lead', 5)
|
||||
->setUserId($user->id)
|
||||
->setModel($user->id, User::class)
|
||||
->setMessage('Error send new_mail_verified E-Mail: '.$e->getMessage())
|
||||
->save();
|
||||
|
||||
if($action === 'remove_whitelabel_product'){
|
||||
|
||||
$model = $user->whitelabel_products()->where('id', $id)->first();
|
||||
//remove images
|
||||
foreach ($model->whitelabel_images as $image){
|
||||
\App\Services\ProductImage::imageDelete('user_wl_image', $model, $image->id);
|
||||
|
||||
}
|
||||
$model->delete();
|
||||
\Session()->flash('alert-success', "White Label Produkt entfernt");
|
||||
return redirect(route('admin_lead_edit', [$user->id])."?show=$show");
|
||||
}
|
||||
UserHistory::create(['user_id' => $user->id, 'action'=>'new_mail_verified', 'status'=>0]);
|
||||
|
||||
\Session()->flash('alert-success', "E-Mail erneut gesendet");
|
||||
return redirect(route('admin_lead_edit', [$user->id]));
|
||||
|
||||
}
|
||||
|
||||
public function download(){
|
||||
|
||||
if(Request::get('action') === "export"){
|
||||
$query = $this->initSearch();
|
||||
$columns = [];
|
||||
$filename = "GS-VP-export-".date("d-m-Y");
|
||||
$headers = array(
|
||||
'ID',
|
||||
'Email',
|
||||
'Firma',
|
||||
'Anrede',
|
||||
'Vorname',
|
||||
'Nachname',
|
||||
'Mitglied',
|
||||
'Bis',
|
||||
'Art',
|
||||
|
||||
);
|
||||
$objects = $query->get();
|
||||
if($objects){
|
||||
foreach ($objects as $obj){
|
||||
$columns[] = array(
|
||||
'ID' => $obj->id,
|
||||
'Email' => $obj->email,
|
||||
'Firma' => $obj->account ? $obj->account->company : '',
|
||||
'Anrede' => $obj->account ? ($obj->account->salutation == 'mr' ? 'Herr' : 'Frau') : '-',
|
||||
'Vorname' => $obj->account ? $obj->account->first_name : '',
|
||||
'Nachname' => $obj->account ? $obj->account->last_name : '',
|
||||
'Mitglied' => $obj->payment_account ? ($obj->isActiveAccount() ? 'JA' : 'Abgelaufen') : "Nein",
|
||||
'Bis' => $obj->payment_account ? $obj->getPaymentAccountDateFormat(false) : '-',
|
||||
'Art' => $obj->lead_type ? $obj->lead_type->name : '-',
|
||||
);
|
||||
}
|
||||
}
|
||||
return Excel::download(new ExcelExport($columns, $headers), $filename.'.xls');
|
||||
}
|
||||
}
|
||||
|
||||
public function deleteFile($user_id, $file_id, $relation){
|
||||
|
||||
if($relation === 'upload'){
|
||||
$user = User::findOrFail($user_id);
|
||||
$file = $user->files()->findOrFail($file_id);
|
||||
//remove file
|
||||
\Storage::disk('user')->delete($file->dir.$file->filename);
|
||||
$file->delete();
|
||||
\Session()->flash('alert-success', "Datei gelöscht");
|
||||
private function setFilterVars(){
|
||||
if(!session('filter_lead_type_id')){
|
||||
session(['filter_lead_type_id' => 'all']);
|
||||
}
|
||||
if(Request::get('filter_lead_type_id')){
|
||||
session(['filter_lead_type_id' => Request::get('filter_lead_type_id')]);
|
||||
}
|
||||
return back();
|
||||
}
|
||||
|
||||
private function initSearch(){
|
||||
$this->setFilterVars();
|
||||
$query = User::with('account')->select('users.*')->where('users.deleted_at', '=', null)->where('users.admin', "<", 4);
|
||||
if(session('filter_lead_type_id') && session('filter_lead_type_id') !== null && session('filter_lead_type_id') !== "all"){
|
||||
$query->where('lead_type_id', session('filter_lead_type_id'));
|
||||
}
|
||||
return $query;
|
||||
}
|
||||
|
||||
public function getLeads()
|
||||
{
|
||||
|
||||
$query = User::with('account')->select('users.*')->where('users.deleted_at', '=', null)->where('users.admin', "<", 4);
|
||||
$query = $this->initSearch();
|
||||
|
||||
return \DataTables::eloquent($query)
|
||||
->addColumn('first_name', function (User $user) {
|
||||
|
|
@ -370,6 +381,9 @@ class LeadController extends Controller
|
|||
->addColumn('user_level', function (User $user) {
|
||||
return $user->user_level ? $user->user_level->name : '';
|
||||
})
|
||||
->addColumn('lead_type', function (User $user) {
|
||||
return $user->lead_type ? $user->lead_type->name : '';
|
||||
})
|
||||
->addColumn('id', function (User $user) {
|
||||
return '<a href="' . route('admin_lead_edit', [$user->id]) . '" class="btn icon-btn btn-sm btn-primary"><span class="far fa-edit"></span></a>';
|
||||
})
|
||||
|
|
@ -404,10 +418,217 @@ class LeadController extends Controller
|
|||
->orderColumn('id', 'id $1')
|
||||
->orderColumn('confirmed', 'confirmed $1')
|
||||
->orderColumn('active', 'active $1')
|
||||
->orderColumn('lead_type', 'lead_type_id $1')
|
||||
->orderColumn('agreement', 'agreement $1')
|
||||
->orderColumn('payment_account', 'payment_account $1')
|
||||
//->orderColumn('payment_shop', 'payment_shop $1')
|
||||
->rawColumns(['id', 'confirmed', 'active', 'agreement', 'payment_account'])
|
||||
->make(true);
|
||||
}
|
||||
|
||||
private function activeAccountPayment($user){
|
||||
|
||||
if($user->user_level){
|
||||
if($user->user_level->payment_year){
|
||||
//if true = payments
|
||||
$user->wizard = 20;
|
||||
$user->active = 1;
|
||||
$user->active_date = now();
|
||||
$user->confirmation_code = null;
|
||||
$user->confirmation_code_to = null;
|
||||
$user->confirmation_code_remider = 0;
|
||||
$user->save();
|
||||
}else{
|
||||
//if false = no payments for 1 year
|
||||
$user->wizard = 100;
|
||||
$user->payment_account = \Carbon::now()->modify('1 year');
|
||||
$user->active = 1;
|
||||
$user->active_date = now();
|
||||
$user->confirmation_code = null;
|
||||
$user->confirmation_code_to = null;
|
||||
$user->confirmation_code_remider = 0;
|
||||
$user->save();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
//user released when register is complete
|
||||
public function released($action, $id){
|
||||
|
||||
$user = User::findOrFail($id);
|
||||
if($action === 'completed'){
|
||||
$validator = Validator::make(Request::all(), []);
|
||||
/*if(!$user->m_sponsor){
|
||||
$validator->errors()->add('m_sponsor', __('Vertriebspartner hat keinen Sponsor.'));
|
||||
}*/
|
||||
if(!$user->account->m_first_name){
|
||||
$validator->errors()->add('m_first_name', __('Vertriebspartner hat keinen Vornamen.'));
|
||||
}
|
||||
if(!$user->account->m_last_name){
|
||||
$validator->errors()->add('m_last_name', __('Vertriebspartner hat keinen Nachnamen.'));
|
||||
}
|
||||
if(!$user->m_level){
|
||||
$validator->errors()->add('m_level', __('Vertriebspartner hat keine Rolle'));
|
||||
}
|
||||
if ($validator->errors()->count()) {
|
||||
return back()->withErrors($validator)->withRequest(Request::all());
|
||||
}
|
||||
|
||||
if(!$user->account->m_account){
|
||||
$user->account->m_account = UserAccount::withTrashed()->max('m_account') +1;
|
||||
$user->account->save();
|
||||
}
|
||||
|
||||
//create PDF
|
||||
$pdf = new ContractPDFRepository($user);
|
||||
$pdf->_set('disk', 'user');
|
||||
$pdf->_set('dir', '/'.$user->id.'/documents/');
|
||||
$pdf->_set('user_id', $user->id);
|
||||
$pdf->_set('identifier', 'contract');
|
||||
$pdf->createContractPDF();
|
||||
|
||||
//set wizard to payments / activate
|
||||
$this->activeAccountPayment($user);
|
||||
|
||||
//mail with code to user?
|
||||
try {
|
||||
Mail::to($user->email)->bcc(config('app.info_mail'))->send(new MailAccountActive($user));
|
||||
}
|
||||
catch(\Exception $e){
|
||||
SysLog::action('released', 'admin_lead', 5)
|
||||
->setUserId($user->id)
|
||||
->setModel($user->id, User::class)
|
||||
->setMessage('Error send released E-Mail: '.$e->getMessage())
|
||||
->save();
|
||||
}
|
||||
|
||||
UserHistory::create(['user_id' => $user->id, 'action'=>'released_completed', 'status'=>0]);
|
||||
\Session()->flash('alert-success', "Vertriebspartner freigeschaltet!");
|
||||
}
|
||||
|
||||
if($action === 'incomplete'){
|
||||
//reset release
|
||||
$confirmation_code = UserService::createConfirmationCode();
|
||||
$user->confirmation_code = $confirmation_code;
|
||||
$user->confirmation_code_to = date('Y-m-d H:i:s', strtotime('+1 week'));
|
||||
$user->confirmation_code_remider = 0;
|
||||
$user->wizard = 1;
|
||||
$user->release_account = null;
|
||||
$user->save();
|
||||
|
||||
$input = Request::all();
|
||||
$data = [
|
||||
'subject' => $input['account_incomplete_subject'],
|
||||
'message' => $input['account_incomplete_message'],
|
||||
'confirmation_code' => $confirmation_code,
|
||||
];
|
||||
try {
|
||||
Mail::to($user->email)->bcc(config('app.info_mail'))->send(new MailCustomMessage($user, $data, \Auth::user(), true));
|
||||
}
|
||||
catch(\Exception $e){
|
||||
SysLog::action('released_incomplete', 'admin_lead', 5)
|
||||
->setUserId($user->id)
|
||||
->setModel($user->id, User::class)
|
||||
->setMessage('Error send released_incomplete E-Mail: '.$e->getMessage())
|
||||
->save();
|
||||
}
|
||||
UserHistory::create(['user_id' => $user->id, 'action'=>'released_incomplete', 'status'=>0]);
|
||||
\Session()->flash('alert-success', "E-Mail an Vertriebspartner gesendet.");
|
||||
}
|
||||
if($action === 'reset_switch'){
|
||||
$user->wizard = 3;
|
||||
$user->save();
|
||||
UserHistory::create(['user_id' => $user->id, 'action'=>'reset_switch', 'status'=>0]);
|
||||
\Session()->flash('alert-success', "Vertriebspartner zurückgesetzt!");
|
||||
}
|
||||
if($action === 'unlock'){
|
||||
$validator = Validator::make(Request::all(), []);
|
||||
/*if(!$user->m_sponsor){
|
||||
$validator->errors()->add('m_sponsor', __('Vertriebspartner hat keinen Sponsor.'));
|
||||
}*/
|
||||
if(!$user->account->m_first_name){
|
||||
$validator->errors()->add('m_first_name', __('Vertriebspartner hat keinen Vornamen.'));
|
||||
}
|
||||
if(!$user->account->m_last_name){
|
||||
$validator->errors()->add('m_last_name', __('Vertriebspartner hat keinen Nachnamen.'));
|
||||
}
|
||||
if(!$user->m_level){
|
||||
$validator->errors()->add('m_level', __('Vertriebspartner hat keine Rolle'));
|
||||
}
|
||||
|
||||
if ($validator->errors()->count()) {
|
||||
return back()->withErrors($validator)->withRequest(Request::all());
|
||||
}
|
||||
|
||||
if(!$user->account->m_account){
|
||||
$user->account->m_account = UserAccount::withTrashed()->max('m_account') +1;
|
||||
$user->account->save();
|
||||
}
|
||||
|
||||
//set wizard to payments / activate
|
||||
$this->activeAccountPayment($user);
|
||||
|
||||
//mail with code to user?
|
||||
try {
|
||||
Mail::to($user->email)->bcc(config('app.info_mail'))->send(new MailAccountActive($user));
|
||||
}
|
||||
catch(\Exception $e){
|
||||
SysLog::action('unlock', 'admin_lead', 5)
|
||||
->setUserId($user->id)
|
||||
->setModel($user->id, User::class)
|
||||
->setMessage('Error send released E-Mail: '.$e->getMessage())
|
||||
->save();
|
||||
}
|
||||
|
||||
UserHistory::create(['user_id' => $user->id, 'action'=>'unlock_completed', 'status'=>0]);
|
||||
\Session()->flash('alert-success', "Vertriebspartner erneut freigeschaltet!");
|
||||
}
|
||||
return redirect(route('admin_lead_edit', [$user->id]));
|
||||
|
||||
|
||||
}
|
||||
|
||||
|
||||
//send new verfified mail to user
|
||||
/* public function newMailVerified($id){
|
||||
|
||||
User Register sind in der DB UserRegister, erst bei bestätigung wird es in die User DB übertragen
|
||||
|
||||
$user = User::findOrFail($id);
|
||||
|
||||
$confirmation_code = UserService::createConfirmationCode();
|
||||
$user->confirmation_code = $confirmation_code;
|
||||
$user->confirmation_code_to = date('Y-m-d H:i:s', strtotime('+1 week'));
|
||||
$user->confirmation_code_remider = 0;
|
||||
$user->save();
|
||||
|
||||
try {
|
||||
Mail::to($user->email)->bcc(config('app.info_mail'))->send(new MailVerifyAccount($confirmation_code, $user));
|
||||
}
|
||||
catch(\Exception $e){
|
||||
SysLog::action('new_mail_verified', 'admin_lead', 5)
|
||||
->setUserId($user->id)
|
||||
->setModel($user->id, User::class)
|
||||
->setMessage('Error send new_mail_verified E-Mail: '.$e->getMessage())
|
||||
->save();
|
||||
}
|
||||
UserHistory::create(['user_id' => $user->id, 'action'=>'new_mail_verified', 'status'=>0]);
|
||||
|
||||
\Session()->flash('alert-success', "E-Mail erneut gesendet");
|
||||
return redirect(route('admin_lead_edit', [$user->id]));
|
||||
|
||||
}*/
|
||||
|
||||
public function deleteFile($user_id, $file_id, $relation){
|
||||
|
||||
if($relation === 'upload'){
|
||||
$user = User::findOrFail($user_id);
|
||||
$file = $user->files()->findOrFail($file_id);
|
||||
//remove file
|
||||
\Storage::disk('user')->delete($file->dir.$file->filename);
|
||||
$file->delete();
|
||||
\Session()->flash('alert-success', "Datei gelöscht");
|
||||
}
|
||||
return back();
|
||||
}
|
||||
}
|
||||
47
app/Http/Controllers/LeadTypeController.php
Normal file
47
app/Http/Controllers/LeadTypeController.php
Normal file
|
|
@ -0,0 +1,47 @@
|
|||
<?php
|
||||
|
||||
namespace App\Http\Controllers;
|
||||
|
||||
|
||||
use App\Models\LeadType;
|
||||
use Request;
|
||||
|
||||
|
||||
class LeadTypeController extends Controller
|
||||
{
|
||||
|
||||
public function __construct()
|
||||
{
|
||||
$this->middleware('admin');
|
||||
}
|
||||
|
||||
public function index()
|
||||
{
|
||||
|
||||
$data = [
|
||||
'values' => LeadType::all(),
|
||||
];
|
||||
return view('admin.lead.types', $data);
|
||||
}
|
||||
|
||||
public function store()
|
||||
{
|
||||
|
||||
$data = Request::all();
|
||||
if($data['id'] === "new"){
|
||||
$model = LeadType::create([
|
||||
'name' => $data['name'],
|
||||
'active' => isset($data['active']) ? true : false,
|
||||
]);
|
||||
}else{
|
||||
$model = LeadType::find($data['id']);
|
||||
$model->name = $data['name'];
|
||||
$model->active = isset($data['active']) ? true : false;
|
||||
$model->save();
|
||||
}
|
||||
\Session()->flash('alert-save', '1');
|
||||
return redirect(route('admin_lead_types'));
|
||||
|
||||
|
||||
}
|
||||
}
|
||||
|
|
@ -51,7 +51,7 @@ class MembershipController extends Controller
|
|||
'userHistoryPaymentOrder' => $userHistoryPaymentOrder,
|
||||
'userHistoryUpgradeOrder' => $userHistoryUpgradeOrder,
|
||||
'userHistoryDeleteMembership' => $userHistoryDeleteMembership,
|
||||
'user_levels' => UserLevel::where('active', true)->get(),
|
||||
'user_levels' => UserLevel::where('active', true)->orderBy('pos')->get(),
|
||||
|
||||
];
|
||||
return view('user.membership.index', $data);
|
||||
|
|
@ -99,6 +99,17 @@ class MembershipController extends Controller
|
|||
$image = $product->images->first()->slug;
|
||||
}
|
||||
$qty = Request::get('qty') ? Request::get('qty') : 1;
|
||||
|
||||
/* //need setGlobalTaxRate
|
||||
|
||||
$cartItem = Yard::instance('shopping')->add($product->id, $product->getLang('name'), $qty, $product->getPriceWith(\App\Services\UserService::getTaxFree(), false, \App\Services\UserService::$user_country), false, false, ['image' => $image, 'slug' => $product->slug, 'weight' => $product->weight, 'points' => $product->points, 'no_commission' => $product->no_commission]);
|
||||
if(\App\Services\UserService::getTaxFree()){
|
||||
Yard::setTax($cartItem->rowId, 0);
|
||||
}else{
|
||||
Yard::setTax($cartItem->rowId, $product->getTaxWith(\App\Services\UserService::$user_country));
|
||||
}
|
||||
*/
|
||||
//Keine steuer
|
||||
Yard::instance('shopping')->add($product->id, $product->getLang('name'), $qty, $product->price, $product->tax, ['image' => $image, 'slug' => $product->slug, 'weight' => $product->weight]);
|
||||
Yard::instance('shopping')->setGlobalTaxRate(0);
|
||||
/*
|
||||
|
|
@ -161,6 +172,8 @@ class MembershipController extends Controller
|
|||
if($action === "change_level"){
|
||||
if(Request::get('switchers-package-level')){
|
||||
$user = User::find(Auth::user()->id);
|
||||
//hier wird die nächste Mitgliedschaftsstufe gesetzt
|
||||
//wird im Cronjob UserCheckPaymentsAccounts.php verwendet und gesetzt
|
||||
$user->next_m_level = Request::get('switchers-package-level');
|
||||
$user->save();
|
||||
UserHistory::create(['user_id' => $user->id, 'action'=>$action, 'status'=>10, 'referenz'=>Request::get('switchers-package-level')]);
|
||||
|
|
|
|||
|
|
@ -27,7 +27,7 @@ class ModalController extends Controller
|
|||
if(Request::ajax()){
|
||||
if($data['action'] === 'shopping-order-change-member'){
|
||||
$value = ShoppingOrder::find($data['id']);
|
||||
$route = route('admin_sales_customers_detail', [$value->id]);
|
||||
$route = route('admin_sales_detail', [$value->id]);
|
||||
$ret = view("admin.modal.member", compact('value', 'data', 'route'))->render();
|
||||
}
|
||||
if($data['action'] === 'shopping-user-change-member'){
|
||||
|
|
|
|||
|
|
@ -59,6 +59,8 @@ class PayController extends Controller
|
|||
|
||||
private $reference;
|
||||
|
||||
private $payment_method;
|
||||
|
||||
public function __construct() {
|
||||
|
||||
}
|
||||
|
|
@ -77,6 +79,7 @@ class PayController extends Controller
|
|||
public function setPrePayment($payment_method, $amount, $currency, $ret = []){
|
||||
|
||||
$this->reference = $this->shopping_order->created_at->format('Ym').$this->shopping_order->id;//substr(uniqid('m', false), 0, 16);
|
||||
$this->payment_method = $payment_method;
|
||||
$this->setMethod($payment_method, $ret);
|
||||
|
||||
$this->prepayment = [
|
||||
|
|
@ -86,7 +89,6 @@ class PayController extends Controller
|
|||
"param" => $this->shopping_order->id,
|
||||
|
||||
];
|
||||
|
||||
$this->shopping_payment = ShoppingPayment::create([
|
||||
'shopping_order_id' => $this->shopping_order->id,
|
||||
'clearingtype' => $this->method["clearingtype"],
|
||||
|
|
@ -119,6 +121,15 @@ class PayController extends Controller
|
|||
private function setMethod($payment_method, $ret = []){
|
||||
|
||||
//vorkasse
|
||||
if($payment_method === 'non'){
|
||||
$this->method = [
|
||||
"clearingtype" => "non",
|
||||
"wallettype" => "",
|
||||
'onlinebanktransfertype' => "",
|
||||
"request" => "authorization",
|
||||
];
|
||||
}
|
||||
|
||||
if($payment_method === 'vor'){
|
||||
$this->method = [
|
||||
"clearingtype" => "vor",
|
||||
|
|
@ -138,12 +149,21 @@ class PayController extends Controller
|
|||
];
|
||||
}
|
||||
|
||||
//Rechnungskauf
|
||||
if($payment_method === 'pp'){
|
||||
$this->method = [
|
||||
"clearingtype" => "pp",
|
||||
"wallettype" => "",
|
||||
'onlinebanktransfertype' => "",
|
||||
"request" => "CAPTURE",
|
||||
];
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
public function ResponseData($identifier){
|
||||
public function ResponseData($identifier, $payment_for = false){
|
||||
|
||||
$request = array_merge($this->default, $this->personalData, $this->deliveryData, $this->method, $this->prepayment, $this->urls);
|
||||
//RECHNUNG MIV
|
||||
|
||||
$payt = PaymentTransaction::create([
|
||||
'shopping_payment_id' => $this->shopping_payment->id,
|
||||
|
|
@ -155,10 +175,36 @@ class PayController extends Controller
|
|||
'txaction' => 'prev',
|
||||
'mode' => $this->shopping_payment->mode,
|
||||
]);
|
||||
|
||||
//paypal
|
||||
if($this->payment_method === 'pp'){
|
||||
switch ($payment_for) {
|
||||
case 7: //promotion
|
||||
$paypal = new PayPalController;
|
||||
$redirect = $paypal->payment($this->shopping_payment, $payt, $identifier, $payment_for, $this->shopping_order->promotion_user_id);
|
||||
Util::setUserHistoryValue(['status'=>4], $identifier);
|
||||
return $redirect;
|
||||
case 8: //shop
|
||||
$paypal = new PayPalController;
|
||||
$redirect = $paypal->payment($this->shopping_payment, $payt, $identifier, $payment_for, $this->shopping_order->user_shop_id);
|
||||
Util::setUserHistoryValue(['status'=>4], $identifier);
|
||||
return $redirect;
|
||||
}
|
||||
}
|
||||
|
||||
Util::setUserHistoryValue(['status'=>5], $identifier);
|
||||
return redirect(route('user_checkout_final', [$payt->id, $this->reference, $identifier]));
|
||||
switch ($payment_for) {
|
||||
case 7: //promotion
|
||||
return redirect(route('web_promotion_goto', ['thanksorder', $this->shopping_order->promotion_user_id, $payt->id, $this->reference, $identifier]));
|
||||
break;
|
||||
case 8: //shop
|
||||
return redirect(route('web_shop_goto', ['thanksorder', $this->shopping_order->user_shop_id, $payt->id, $this->reference, $identifier]));
|
||||
break;
|
||||
|
||||
default:
|
||||
return redirect(route('user_checkout_final', [$payt->id, $this->reference, $identifier]));
|
||||
break;
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
}
|
||||
|
|
|
|||
113
app/Http/Controllers/Pay/PayPalController.php
Normal file
113
app/Http/Controllers/Pay/PayPalController.php
Normal file
|
|
@ -0,0 +1,113 @@
|
|||
<?php
|
||||
|
||||
|
||||
namespace App\Http\Controllers\Pay;
|
||||
use Request;
|
||||
use App\Models\UserShop;
|
||||
use App\Models\PromotionUser;
|
||||
use App\Models\PaymentTransaction;
|
||||
use App\Http\Controllers\Controller;
|
||||
use Srmklive\PayPal\Services\PayPal as PayPalClient;
|
||||
|
||||
|
||||
class PayPalController extends Controller
|
||||
{
|
||||
|
||||
public function payment($shopping_payment, $payt, $identifier, $payment_for, $payment_for_user_id)
|
||||
{
|
||||
$provider = new PayPalClient;
|
||||
// Through facade. No need to import namespaces
|
||||
|
||||
$provider = \PayPal::setProvider();
|
||||
$provider->setApiCredentials(config('paypal'));
|
||||
$provider->setAccessToken($provider->getAccessToken());
|
||||
$provider->setCurrency('EUR');
|
||||
|
||||
$order = $provider->createOrder([
|
||||
"intent"=> "CAPTURE",
|
||||
"purchase_units"=> [
|
||||
[
|
||||
"reference_id" => $shopping_payment->reference,
|
||||
"shopping_order_id" => $shopping_payment->shopping_order_id,
|
||||
"amount"=> [
|
||||
"currency_code"=> "EUR",
|
||||
"value"=> ($shopping_payment->amount / 100)
|
||||
],
|
||||
'description' => 'test'
|
||||
]
|
||||
],
|
||||
'application_context' => [
|
||||
'cancel_url' => route('cancel.paypal_payment', [$payment_for, $payment_for_user_id, $payt->id, $shopping_payment->reference, $identifier]),
|
||||
'return_url' => route('success.paypal_payment', [$payment_for, $payment_for_user_id, $payt->id, $shopping_payment->reference, $identifier])
|
||||
]
|
||||
|
||||
]);
|
||||
$payt->key = $order['id'];
|
||||
$payt->save();
|
||||
return redirect($order['links'][1]['href'])->send();
|
||||
|
||||
}
|
||||
|
||||
public function paymentSuccess($payment_for, $id, $transactionId=false, $reference=false, $identifier=false)
|
||||
{
|
||||
$payt = PaymentTransaction::findOrFail($transactionId);
|
||||
if($payt->shopping_payment->reference != $reference){
|
||||
abort(404);
|
||||
}
|
||||
// Init PayPal
|
||||
$provider = \PayPal::setProvider();
|
||||
$provider->setApiCredentials(config('paypal'));
|
||||
$provider->setAccessToken($provider->getAccessToken());
|
||||
|
||||
// Get PaymentOrder using our transaction ID
|
||||
$order = $provider->capturePaymentOrder($payt->key);
|
||||
if(isset($order['type'])){
|
||||
abort(403, 'PayPal Type: '.$order['type']);
|
||||
}
|
||||
|
||||
if(!isset($order['status']) || $order['status'] !== "COMPLETED"){
|
||||
abort(403, 'Error: Order Status ');
|
||||
}
|
||||
|
||||
if(Request::get('token') !== $payt->key){
|
||||
abort(403, 'Error: PayPal token');
|
||||
}
|
||||
$payt->request = $order['status'];
|
||||
$payt->save();
|
||||
|
||||
switch ($payment_for) {
|
||||
case 7: //promotion
|
||||
$PromotionUser = PromotionUser::findOrFail($id);
|
||||
return redirect(route('web_promotion_goto', ['thanksorder', $id, $payt->id, $reference, $identifier]));
|
||||
case 8: //shop
|
||||
$userShop = UserShop::findOrFail($id);
|
||||
return redirect(route('web_shop_goto', ['thanksorder', $id, $payt->id, $reference, $identifier]));
|
||||
dd('Your payment has been declend. The payment cancelation page goes here!');
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
|
||||
public function paymentCancel($payment_for, $id, $transactionId=false, $reference=false, $identifier=false)
|
||||
{
|
||||
switch ($payment_for) {
|
||||
case 7: //promotion
|
||||
$PromotionUser = PromotionUser::findOrFail($id);
|
||||
return redirect(url($PromotionUser->url));
|
||||
dd('Your payment has been declend. The payment cancelation page goes here!');
|
||||
case 8: //shop
|
||||
$userShop = UserShop::findOrFail($id);
|
||||
return redirect(url($userShop->url));
|
||||
dd('Your payment has been declend. The payment cancelation page goes here!');
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
|
||||
|
||||
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
|
|
@ -4,17 +4,18 @@
|
|||
namespace App\Http\Controllers;
|
||||
|
||||
use App\Models\Models\UserCreditMargin as ModelsUserCreditMargin;
|
||||
use Carbon;
|
||||
use Request;
|
||||
use App\User;
|
||||
use App\Services\Util;
|
||||
use App\Services\Credit;
|
||||
use App\Services\Payment;
|
||||
use App\Models\UserCredit;
|
||||
use App\Models\ShoppingOrderMargin;
|
||||
use App\Models\UserCredit;
|
||||
use App\Models\UserCreditMargin;
|
||||
use App\Repositories\CreditRepository;
|
||||
use App\Services\Credit;
|
||||
use App\Services\Payment;
|
||||
use App\Services\Payment\UserBot;
|
||||
use App\Services\Util;
|
||||
use App\User;
|
||||
use Carbon;
|
||||
use Illuminate\Support\Collection;
|
||||
use Request;
|
||||
|
||||
class PaymentCreditController extends Controller
|
||||
{
|
||||
|
|
@ -23,10 +24,12 @@ class PaymentCreditController extends Controller
|
|||
private $endYear;
|
||||
private $rangeYears;
|
||||
private $activeYear;
|
||||
private $userBot;
|
||||
|
||||
public function __construct()
|
||||
public function __construct(UserBot $userBot)
|
||||
{
|
||||
$this->middleware('auth');
|
||||
$this->userBot = $userBot;
|
||||
$this->startYear = 2021;
|
||||
$this->endYear = date('Y');
|
||||
$this->rangeYears = range($this->startYear, $this->endYear);
|
||||
|
|
@ -41,7 +44,11 @@ class PaymentCreditController extends Controller
|
|||
}
|
||||
|
||||
|
||||
|
||||
/**
|
||||
* fügt eine neue Manuelle Gutschrift hinzu
|
||||
*
|
||||
* @return \Illuminate\Http\RedirectResponse
|
||||
*/
|
||||
public function store(){
|
||||
$data = Request::all();
|
||||
|
||||
|
|
@ -64,7 +71,6 @@ class PaymentCreditController extends Controller
|
|||
|
||||
$credit = Util::reFormatNumber($data['credit']);
|
||||
$credit = number_format($credit, 2, '.', '');
|
||||
|
||||
Payment::addUserCreditMargin($user, $credit, 3, $data['message']);
|
||||
\Session()->flash('alert-success', "Guthaben hinzugefügt");
|
||||
}
|
||||
|
|
@ -72,6 +78,11 @@ class PaymentCreditController extends Controller
|
|||
return redirect(route('admin_payments_credit'));
|
||||
}
|
||||
|
||||
/**
|
||||
* Erstellt eine neue komplette Gutschrift für einen Benutzer
|
||||
*
|
||||
* @return \Illuminate\Http\RedirectResponse
|
||||
*/
|
||||
public function create(){
|
||||
$data = Request::all();
|
||||
if(isset($data['action'])){
|
||||
|
|
@ -95,65 +106,18 @@ class PaymentCreditController extends Controller
|
|||
}
|
||||
}
|
||||
|
||||
private function makeData(){
|
||||
private function makeData(): array
|
||||
{
|
||||
$this->setActiveYears();
|
||||
//$date1 = Carbon::parse('01.01.'.$this->activeYear." 00:00:00")->format('Y-m-d H:i:s');
|
||||
//$date2 = Carbon::parse('31.12.'.$this->activeYear." 23:59:59")->toDateString();
|
||||
|
||||
$ShoppingOrderMargins = ShoppingOrderMargin::join('users', 'm_sponsor_id', '=', 'users.id')
|
||||
->groupBy('m_sponsor_id')
|
||||
->join('user_accounts', 'account_id', '=', 'user_accounts.id')
|
||||
->select('users.id as user_id', 'users.email', 'user_accounts.first_name', 'user_accounts.last_name')
|
||||
->wherePaid(true)
|
||||
->whereCancellation(false)
|
||||
->wherePartnerCommissionPaid(false)
|
||||
->where('partner_commission_pending_to', '<', Carbon::now())
|
||||
->get();
|
||||
|
||||
$ShoppingOrderMarginPendings = ShoppingOrderMargin::join('users', 'm_sponsor_id', '=', 'users.id')
|
||||
->groupBy('m_sponsor_id')
|
||||
->join('user_accounts', 'account_id', '=', 'user_accounts.id')
|
||||
->select('users.id as user_id', 'users.email', 'user_accounts.first_name', 'user_accounts.last_name')
|
||||
->wherePaid(true)
|
||||
->whereCancellation(false)
|
||||
->wherePartnerCommissionPaid(false)
|
||||
->where('partner_commission_pending_to', '>=', Carbon::now())
|
||||
->get();
|
||||
|
||||
$UserCreditMargins = UserCreditMargin::wherePaid(false)->get();
|
||||
$ShoppingOrderMarginUserIds = ShoppingOrderMargin::select('m_sponsor_id')->groupBy('m_sponsor_id')
|
||||
->wherePaid(true)
|
||||
->whereCancellation(false)
|
||||
->wherePartnerCommissionPaid(false)
|
||||
->where('partner_commission_pending_to', '<', Carbon::now())
|
||||
->get()->pluck('m_sponsor_id')->toArray();
|
||||
$this->userBot->readUserHasCredits();
|
||||
$this->userBot->readUserHasPendingCredit();
|
||||
|
||||
$onlyUserCreditMargins = [];
|
||||
foreach($UserCreditMargins as $key => $UserCreditMargin){
|
||||
if(!in_array($UserCreditMargin->user_id, $ShoppingOrderMarginUserIds)){
|
||||
if(isset($onlyUserCreditMargins[$UserCreditMargin->user_id])){
|
||||
$onlyUserCreditMargins[$UserCreditMargin->user_id]['sum'] += $UserCreditMargin->credit;
|
||||
$onlyUserCreditMargins[$UserCreditMargin->user_id]['entries'][$UserCreditMargin->id] = $UserCreditMargin;
|
||||
}else{
|
||||
$onlyUserCreditMargins[$UserCreditMargin->user_id] = [
|
||||
'user_id' => $UserCreditMargin->user->id,
|
||||
'first_name' => $UserCreditMargin->user->account->first_name,
|
||||
'last_name' => $UserCreditMargin->user->account->last_name,
|
||||
'email' => $UserCreditMargin->user->email,
|
||||
'sum' => $UserCreditMargin->credit,
|
||||
'entries' => [$UserCreditMargin->id => $UserCreditMargin],
|
||||
];
|
||||
}
|
||||
}
|
||||
}
|
||||
$data = [
|
||||
return [
|
||||
'years' => $this->rangeYears,
|
||||
'active_year' => $this->activeYear,
|
||||
'ShoppingOrderMargins' => $ShoppingOrderMargins,
|
||||
'ShoppingOrderMarginPendings' => $ShoppingOrderMarginPendings,
|
||||
'onlyUserCreditMargins' => $onlyUserCreditMargins,
|
||||
'users_credits' => $this->userBot->getUsers(),
|
||||
'users_credits_pending' => $this->userBot->getUsersPending(),
|
||||
];
|
||||
return $data;
|
||||
}
|
||||
|
||||
private function setActiveYears(){
|
||||
|
|
@ -173,19 +137,25 @@ class PaymentCreditController extends Controller
|
|||
\Session()->flash('alert-error', "Guthaben kann nicht gelöscht werden");
|
||||
}
|
||||
}
|
||||
if($del === 'shopping_order_margin'){
|
||||
$ShoppingOrderMargin = ShoppingOrderMargin::findOrFail($id);
|
||||
$ShoppingOrderMargin->out_paid = true;
|
||||
$ShoppingOrderMargin->save();
|
||||
\Session()->flash('alert-success', "Gutschrift ist gelöscht");
|
||||
}
|
||||
return redirect(route('admin_payments_credit'));
|
||||
}
|
||||
|
||||
public function datatable(){
|
||||
|
||||
$this->setActiveYears();
|
||||
$date1 = Carbon::parse('01.01.'.$this->activeYear)->format('Y-m-d');
|
||||
$date2 = Carbon::parse('31.12.'.$this->activeYear)->format('Y-m-d');
|
||||
$startDate = Carbon::parse("01.01.{$this->activeYear}")->format('Y-m-d');
|
||||
$endDate = Carbon::parse("31.12.{$this->activeYear}")->format('Y-m-d');
|
||||
|
||||
$query = UserCredit::with('user', 'user.account')->select('user_credits.*')
|
||||
//::with('shopping_user', )->select('shopping_orders.*')
|
||||
//->where('paid', '=', 1)
|
||||
->whereBetween('date', [$date1, $date2]);
|
||||
->whereBetween('date', [$startDate, $endDate]);
|
||||
//->orderBy('created_at', 'DESC');
|
||||
|
||||
return \DataTables::eloquent($query)
|
||||
|
|
|
|||
|
|
@ -62,7 +62,7 @@ class PaymentInvoiceController extends Controller
|
|||
|
||||
return \DataTables::eloquent($query)
|
||||
->addColumn('id', function (ShoppingOrder $ShoppingOrder) {
|
||||
return '<a href="' . route('admin_sales_customers_detail', [$ShoppingOrder->id]) . '" class="btn icon-btn btn-sm btn-primary"><span class="fa fa-edit"></span></a>';
|
||||
return '<a href="' . route('admin_sales_detail', [$ShoppingOrder->id]) . '" class="btn icon-btn btn-sm btn-primary"><span class="fa fa-edit"></span></a>';
|
||||
})
|
||||
->addColumn('total_shipping', function (ShoppingOrder $ShoppingOrder) {
|
||||
return $ShoppingOrder->getFormattedTotalShipping()." €";
|
||||
|
|
@ -80,6 +80,9 @@ class PaymentInvoiceController extends Controller
|
|||
->addColumn('txaction', function (ShoppingOrder $ShoppingOrder) {
|
||||
return Payment::getShoppingOrderBadge($ShoppingOrder);
|
||||
})
|
||||
->addColumn('payment_for', function (ShoppingOrder $ShoppingOrder) {
|
||||
return Payment::getPaymentForTypeBadge($ShoppingOrder);
|
||||
})
|
||||
->addColumn('invoice', function (ShoppingOrder $ShoppingOrder) {
|
||||
$ret = "";
|
||||
if(Invoice::isInvoice($ShoppingOrder)){
|
||||
|
|
@ -95,8 +98,9 @@ class PaymentInvoiceController extends Controller
|
|||
->orderColumn('invoice_number', 'invoice_number $1')
|
||||
->orderColumn('txaction', 'txaction $1')
|
||||
->orderColumn('shipped', 'shipped $1')
|
||||
->orderColumn('payment_for', 'payment_for $1')
|
||||
->orderColumn('total_shipping', 'total_shipping $1')
|
||||
->rawColumns(['id', 'shipping_order', 'txaction', 'invoice'])
|
||||
->rawColumns(['id', 'shipping_order', 'txaction', 'payment_for', 'invoice'])
|
||||
->make(true);
|
||||
}
|
||||
}
|
||||
|
|
@ -4,7 +4,6 @@ namespace App\Http\Controllers;
|
|||
|
||||
|
||||
use App\Models\PaymentMethod;
|
||||
use App\Models\UserLevel;
|
||||
use Request;
|
||||
|
||||
|
||||
|
|
|
|||
147
app/Http/Controllers/PaymentReminderController.php
Normal file
147
app/Http/Controllers/PaymentReminderController.php
Normal file
|
|
@ -0,0 +1,147 @@
|
|||
<?php
|
||||
|
||||
|
||||
namespace App\Http\Controllers;
|
||||
|
||||
use Carbon;
|
||||
use Request;
|
||||
use App\Models\PaymentReminder;
|
||||
use App\Models\ShoppingPayment;
|
||||
use App\Services\PaymentReminderService;
|
||||
|
||||
class PaymentReminderController extends Controller
|
||||
{
|
||||
|
||||
private $filter_user_status;
|
||||
private $paymentReminderService;
|
||||
|
||||
public function __construct(PaymentReminderService $paymentReminderService)
|
||||
{
|
||||
$this->middleware('auth');
|
||||
$this->paymentReminderService = $paymentReminderService;
|
||||
}
|
||||
|
||||
public function index()
|
||||
{
|
||||
// Hole die detaillierten Daten für die Tabellen-Ansicht
|
||||
$detailedData = $this->paymentReminderService->getDetailedPaymentsData();
|
||||
// $summaryData = $this->paymentReminderService->getAllOpenPayments();
|
||||
|
||||
// Statistiken für die Übersicht
|
||||
$totalPayments = collect($detailedData)->count();
|
||||
$totalAmount = collect($detailedData)->sum('amount')/100;
|
||||
$clearingTypes = collect($detailedData)->groupBy('clearingtype')->map->count();
|
||||
|
||||
$data = [
|
||||
'reminders' => PaymentReminder::all(),
|
||||
'detailedData' => $detailedData,
|
||||
//'summaryData' => $summaryData,
|
||||
'totalPayments' => $totalPayments,
|
||||
'totalAmount' => $totalAmount,
|
||||
'clearingTypes' => $clearingTypes,
|
||||
];
|
||||
return view('admin.payment.reminder.index', $data);
|
||||
}
|
||||
|
||||
public function create()
|
||||
{
|
||||
$reminder = new PaymentReminder();
|
||||
$reminder->active = true;
|
||||
$data = [
|
||||
'reminder' => $reminder,
|
||||
];
|
||||
return view('admin.payment.reminder.edit', $data);
|
||||
}
|
||||
|
||||
public function edit($id)
|
||||
{
|
||||
$data = [
|
||||
'reminder' => PaymentReminder::find($id),
|
||||
];
|
||||
return view('admin.payment.reminder.edit', $data);
|
||||
}
|
||||
|
||||
public function store()
|
||||
{
|
||||
$data = Request::all();
|
||||
$data['active'] = isset($data['active']) ? true : false;
|
||||
$data['action'] = isset($data['action']) ? $data['action'] : NULL;
|
||||
|
||||
if ($data['id'] === 'new') {
|
||||
PaymentReminder::create($data);
|
||||
} else {
|
||||
$reminder = PaymentReminder::find($data['id']);
|
||||
$reminder->update($data);
|
||||
}
|
||||
return redirect()->route('admin_payments_reminder')->with('success', 'Erinnerung gespeichert');
|
||||
}
|
||||
|
||||
public function action($action, $id)
|
||||
{
|
||||
|
||||
$payment = ShoppingPayment::find($id);
|
||||
if($action == 'send_reminder'){
|
||||
$bool = $this->paymentReminderService->sendReminder($payment);
|
||||
if($bool){
|
||||
\Session()->flash('alert-success', "Zahlungserinnerung gesendet");
|
||||
}else{
|
||||
\Session()->flash('alert-error', "Keine Zahlungserinnerung gesendet");
|
||||
}
|
||||
}
|
||||
if($action == 'no_payment'){
|
||||
$this->paymentReminderService->setNoNPayment($payment);
|
||||
\Session()->flash('alert-success', "Zahlung als nicht bezahlt markiert");
|
||||
}
|
||||
return redirect()->route('admin_payments_reminder');
|
||||
}
|
||||
|
||||
public function delete($id)
|
||||
{
|
||||
$reminder = PaymentReminder::find($id);
|
||||
$reminder->delete();
|
||||
return redirect()->route('admin_payments_reminder');
|
||||
}
|
||||
|
||||
public function logs()
|
||||
{
|
||||
// Hole die Log-Statistiken für verschiedene Zeiträume
|
||||
$stats7Days = $this->paymentReminderService->getLogStatistics(7);
|
||||
$stats30Days = $this->paymentReminderService->getLogStatistics(30);
|
||||
$stats90Days = $this->paymentReminderService->getLogStatistics(90);
|
||||
|
||||
// Hole die neuesten Logs
|
||||
$recentLogs = $this->paymentReminderService->getPaymentReminderLogs(50);
|
||||
|
||||
// Filter-Parameter
|
||||
$orderId = Request::get('order_id');
|
||||
$action = Request::get('action');
|
||||
$startDate = Request::get('start_date');
|
||||
$endDate = Request::get('end_date');
|
||||
|
||||
// Gefilterte Logs
|
||||
$filteredLogs = null;
|
||||
if ($orderId || $action || $startDate || $endDate) {
|
||||
if ($startDate && $endDate) {
|
||||
$filteredLogs = $this->paymentReminderService->getLogsForDateRange($startDate, $endDate);
|
||||
} elseif ($orderId) {
|
||||
$filteredLogs = $this->paymentReminderService->getLogsForPayment($orderId);
|
||||
} elseif ($action) {
|
||||
$filteredLogs = $this->paymentReminderService->getPaymentReminderLogs(100, null, $action);
|
||||
}
|
||||
}
|
||||
|
||||
$data = [
|
||||
'stats7Days' => $stats7Days,
|
||||
'stats30Days' => $stats30Days,
|
||||
'stats90Days' => $stats90Days,
|
||||
'recentLogs' => $recentLogs,
|
||||
'filteredLogs' => $filteredLogs,
|
||||
'orderId' => $orderId,
|
||||
'action' => $action,
|
||||
'startDate' => $startDate,
|
||||
'endDate' => $endDate,
|
||||
];
|
||||
|
||||
return view('admin.payment.reminder.logs', $data);
|
||||
}
|
||||
}
|
||||
|
|
@ -3,6 +3,8 @@
|
|||
namespace App\Http\Controllers;
|
||||
|
||||
use App\Models\Country;
|
||||
use App\Models\Ingredient;
|
||||
use App\Models\PackagingItem;
|
||||
use App\Models\Product;
|
||||
use App\Models\ProductImage;
|
||||
use App\Models\ProductIngredient;
|
||||
|
|
@ -10,49 +12,52 @@ use App\Repositories\ProductRepository;
|
|||
use Request;
|
||||
use Validator;
|
||||
|
||||
|
||||
|
||||
class ProductController extends Controller
|
||||
{
|
||||
protected $productRepo;
|
||||
|
||||
public function __construct(ProductRepository $productRepo)
|
||||
{
|
||||
$this->middleware('admin');
|
||||
$this->middleware('copyreader');
|
||||
$this->productRepo = $productRepo;
|
||||
}
|
||||
|
||||
public function index()
|
||||
{
|
||||
if(Request::get('show_active_products')){
|
||||
if (Request::get('show_active_products')) {
|
||||
set_user_attr('show_active_products', Request::get('show_active_products'));
|
||||
}
|
||||
if(get_user_attr('show_active_products') === "true"){
|
||||
if (get_user_attr('show_active_products') === 'true') {
|
||||
$values = Product::where('active', true)->orderBy('pos', 'DESC')->orderBy('id', 'DESC')->get();
|
||||
}else{
|
||||
} else {
|
||||
$values = Product::orderBy('pos', 'DESC')->orderBy('id', 'DESC')->get();
|
||||
|
||||
}
|
||||
$data = [
|
||||
'values' => $values
|
||||
'values' => $values,
|
||||
];
|
||||
|
||||
return view('admin.product.index', $data);
|
||||
}
|
||||
|
||||
public function edit($id)
|
||||
{
|
||||
if($id === "new"){
|
||||
$model = new Product();
|
||||
if ($id === 'new') {
|
||||
$model = new Product;
|
||||
$model->active = true;
|
||||
}else{
|
||||
} else {
|
||||
$model = Product::findOrFail($id);
|
||||
$model->load(['packagings.packagingMaterial']);
|
||||
}
|
||||
|
||||
$country_for_prices = Country::where('own_eur', '=', true)->orWhere('currency', '=', true)->get();
|
||||
$data = [
|
||||
'product' => $model,
|
||||
'country_for_prices' => $country_for_prices,
|
||||
'ingredient_catalog' => Ingredient::query()->where('active', true)->with('materialQuality')->orderBy('name')->get(['id', 'name', 'inci', 'effect', 'default_factor', 'material_quality_id']),
|
||||
'packaging_catalog' => PackagingItem::query()->where('active', true)->with('packagingMaterial')->orderBy('name')->get(),
|
||||
];
|
||||
|
||||
return view('admin.product.edit', $data);
|
||||
}
|
||||
|
||||
|
|
@ -61,34 +66,36 @@ class ProductController extends Controller
|
|||
|
||||
$data = Request::all();
|
||||
|
||||
$rules = array(
|
||||
$rules = [
|
||||
'name' => 'required',
|
||||
);
|
||||
];
|
||||
/*if(isset($data['number']) && $data['number'] != ""){
|
||||
$rules['number'] = 'int';
|
||||
}*/
|
||||
if(isset($data['wp_number'])){
|
||||
if($data['id'] !== "new"){
|
||||
if (isset($data['wp_number'])) {
|
||||
if ($data['id'] !== 'new') {
|
||||
$model = Product::findOrFail($data['id']);
|
||||
$rules['wp_number'] = 'unique:products,wp_number,'.$model->id;
|
||||
}else{
|
||||
} else {
|
||||
$rules['wp_number'] = 'unique:products,wp_number';
|
||||
|
||||
}
|
||||
}
|
||||
$validator = Validator::make(Request::all(), $rules);
|
||||
|
||||
if($data['id'] === "new"){
|
||||
$model = new Product();
|
||||
}else{
|
||||
if ($data['id'] === 'new') {
|
||||
$model = new Product;
|
||||
} else {
|
||||
$model = Product::findOrFail($data['id']);
|
||||
$model->load(['packagings.packagingMaterial']);
|
||||
}
|
||||
$country_for_prices = Country::where('own_eur', '=', true)->orWhere('currency', '=', true)->get();
|
||||
|
||||
$data = [
|
||||
'product' => $model,
|
||||
'country_for_prices' => $country_for_prices,
|
||||
|
||||
'ingredient_catalog' => Ingredient::query()->where('active', true)->with('materialQuality')->orderBy('name')->get(['id', 'name', 'inci', 'effect', 'default_factor', 'material_quality_id']),
|
||||
'packaging_catalog' => PackagingItem::query()->where('active', true)->with('packagingMaterial')->orderBy('name')->get(),
|
||||
];
|
||||
|
||||
if ($validator->fails()) {
|
||||
|
|
@ -98,119 +105,68 @@ class ProductController extends Controller
|
|||
} else {
|
||||
$product = $this->productRepo->update(Request::all());
|
||||
\Session()->flash('alert-save', true);
|
||||
|
||||
return redirect(route('admin_product_edit', [$product->id]));
|
||||
}
|
||||
|
||||
\Session()->flash('alert-save', '1');
|
||||
return redirect(route('admin_product_show'));
|
||||
}
|
||||
|
||||
public function copy($id){
|
||||
public function copy($id)
|
||||
{
|
||||
$model = Product::findOrFail($id);
|
||||
$product = $this->productRepo->copy($model);
|
||||
\Session()->flash('alert-success', 'Eintrag kopiert');
|
||||
|
||||
return redirect(route('admin_product_show'));
|
||||
}
|
||||
|
||||
public function delete($id, $do = 'product', $did = null){
|
||||
if($do === 'product'){
|
||||
public function delete($id, $do = 'product', $did = null)
|
||||
{
|
||||
if ($do === 'product') {
|
||||
$model = Product::findOrFail($id);
|
||||
$model->delete();
|
||||
\Session()->flash('alert-success', 'Eintrag gelöscht');
|
||||
|
||||
return redirect(route('admin_product_show'));
|
||||
}
|
||||
|
||||
if($do === 'ingredient'){
|
||||
if ($do === 'ingredient') {
|
||||
$model = Product::findOrFail($id);
|
||||
$ProductIngredient = ProductIngredient::where('ingredient_id', $did)->where('product_id', $model->id)->first();
|
||||
if($ProductIngredient){
|
||||
$ProductIngredient->delete();
|
||||
$productIngredient = ProductIngredient::where('ingredient_id', $did)->where('product_id', $model->id)->first();
|
||||
if ($productIngredient) {
|
||||
$productIngredient->delete();
|
||||
\Session()->flash('alert-success', 'Eintrag gelöscht');
|
||||
return redirect(route('admin_product_edit', [$model->id]));
|
||||
}
|
||||
|
||||
return redirect(route('admin_product_edit', [$model->id]));
|
||||
}
|
||||
|
||||
abort(404);
|
||||
}
|
||||
|
||||
// Upload FILE -----------------------------------------------------------------------------------------------------------------------
|
||||
public function imageUpload(){
|
||||
public function imageUpload()
|
||||
{
|
||||
|
||||
$product_id = Request::get('product_id');
|
||||
$product = Product::findOrFail($product_id);
|
||||
|
||||
try {
|
||||
$image = \App\Services\Slim::getImages('images')[0];
|
||||
|
||||
if ( isset($image['output']['data']) )
|
||||
{
|
||||
|
||||
// Base64 of the image
|
||||
$data = $image['output']['data'];
|
||||
$file_ex = array( 'image/jpeg' => 'jpg', 'image/png' => 'png');
|
||||
|
||||
if (!isset($file_ex[$image['output']['type']])) {
|
||||
\Session()->flash('alert-danger', 'File is not jpg or png!');
|
||||
return redirect(route('admin_product_edit', [$product->id]));
|
||||
}
|
||||
|
||||
$ext = $file_ex[$image['output']['type']];
|
||||
// Original file name
|
||||
$name = $image['output']['name'];
|
||||
$name = \App\Services\Slim::sanitizeFileName($name);
|
||||
$name = uniqid() . '_' . $name;
|
||||
|
||||
$data = \Storage::disk('public')->put(
|
||||
'images/product/'.$product->id.'/'.$name,
|
||||
$data
|
||||
);
|
||||
|
||||
ProductImage::create([
|
||||
'product_id' => $product->id,
|
||||
'filename' => $name,
|
||||
'original_name' => $image['output']['name'],
|
||||
'ext' => $ext,
|
||||
'mine' => $image['output']['type'],
|
||||
'size' => $image['input']['size']
|
||||
]);
|
||||
|
||||
|
||||
\Session()->flash('alert-success', "Datei hochgeladen");
|
||||
return redirect(route('admin_product_edit', [$product->id]));
|
||||
}
|
||||
\Session()->flash('alert-danger', "Datei leer");
|
||||
return redirect(route('admin_product_edit', [$product->id]));
|
||||
if (Request::has('product_id')) {
|
||||
$product = Product::findOrFail(Request::get('product_id'));
|
||||
|
||||
return \App\Services\ProductImage::imageUpload('product', $product, Request::get('upload_type'));
|
||||
}
|
||||
catch (\Exception $e) {
|
||||
\Session()->flash('alert-danger', "Fehler".$e);
|
||||
return redirect(route('admin_product_edit', [$product->id]));
|
||||
}
|
||||
}
|
||||
|
||||
public function imageDelete($image_id, $product_id){
|
||||
|
||||
$product = Product::findOrFail($product_id);
|
||||
$product_image = ProductImage::findOrFail($image_id);
|
||||
|
||||
if($product_image->product_id == $product->id){
|
||||
$file = 'images/product/'.$product->id.'/'.$product_image->filename;
|
||||
\Storage::disk('public')->delete($file);
|
||||
|
||||
$product_image->delete();
|
||||
|
||||
\Session()->flash('alert-success', "Datei gelöscht");
|
||||
return redirect(route('admin_product_edit', [$product->id]));
|
||||
|
||||
}
|
||||
\Session()->flash('alert-danger', "Datei nicht gefunden");
|
||||
return redirect(route('admin_product_edit', [$product->id]));
|
||||
|
||||
}
|
||||
|
||||
public function imageAttribute($product_id, $attr, $val = false){
|
||||
public function imageDelete($product_image_id, $product_id)
|
||||
{
|
||||
$product = Product::findOrFail($product_id);
|
||||
|
||||
if(is_numeric($val) && $val < 0){
|
||||
return \App\Services\ProductImage::imageDelete('product', $product, $product_image_id);
|
||||
|
||||
}
|
||||
|
||||
public function imageAttribute($product_id, $attr, $val = false)
|
||||
{
|
||||
|
||||
if (is_numeric($val) && $val < 0) {
|
||||
$val = 0;
|
||||
}
|
||||
|
||||
|
|
@ -219,9 +175,9 @@ class ProductController extends Controller
|
|||
$product_image->{$attr} = $val;
|
||||
$product_image->save();
|
||||
|
||||
\Session()->flash('alert-success', "Wert gespeichert");
|
||||
\Session()->flash('alert-success', 'Wert gespeichert');
|
||||
|
||||
return redirect()->back();
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -2,26 +2,197 @@
|
|||
|
||||
namespace App\Http\Controllers;
|
||||
|
||||
use Request;
|
||||
use App\Models\Setting;
|
||||
use App\Models\UserShop;
|
||||
use App\Services\Payment;
|
||||
use App\Models\ShoppingUser;
|
||||
use App\Models\ShoppingOrder;
|
||||
use App\Models\UserPayCredit;
|
||||
use App\Models\ShoppingPayment;
|
||||
use App\Models\PaymentTransaction;
|
||||
use App\Services\CustomerPriority;
|
||||
use App\Models\ShoppingUser;
|
||||
use App\Repositories\InvoiceRepository;
|
||||
use App\Services\CustomerPriority;
|
||||
use App\Services\Invoice;
|
||||
use App\Services\Payment;
|
||||
use App\Services\PaymentService;
|
||||
use Request;
|
||||
|
||||
class SalesController extends Controller
|
||||
{
|
||||
|
||||
public function __construct(){
|
||||
public function __construct()
|
||||
{
|
||||
$this->middleware('admin');
|
||||
}
|
||||
|
||||
public function users(){
|
||||
public function index()
|
||||
{
|
||||
|
||||
if (Request::get('reset') === 'filter') {
|
||||
set_user_attr('filter_txaction', null);
|
||||
set_user_attr('filter_member_id', null);
|
||||
set_user_attr('filter_art', null);
|
||||
set_user_attr('filter_shipped', null);
|
||||
|
||||
return redirect(route('admin_sales'));
|
||||
}
|
||||
// set Filter!
|
||||
$filter_members = ShoppingOrder::join('users', 'member_id', '=', 'users.id')->groupBy('member_id')->join('user_accounts', 'account_id', '=', 'user_accounts.id')->select('users.id', 'users.email', 'user_accounts.first_name', 'user_accounts.last_name')->get();
|
||||
$data = [
|
||||
'filter_members' => $filter_members,
|
||||
];
|
||||
|
||||
return view('admin.sales.index', $data);
|
||||
}
|
||||
|
||||
public function detail($id)
|
||||
{
|
||||
|
||||
$ShoppingOrder = ShoppingOrder::find($id);
|
||||
if ($ShoppingOrder->shipped == 0) {
|
||||
$ShoppingOrder->shipped = 1;
|
||||
$ShoppingOrder->save();
|
||||
}
|
||||
$data = [
|
||||
'shopping_order' => $ShoppingOrder,
|
||||
'isAdmin' => true,
|
||||
'isView' => $ShoppingOrder->auth_user_id ? 'sales_user' : 'sales_customer',
|
||||
];
|
||||
|
||||
return view('admin.sales.detail', $data);
|
||||
}
|
||||
|
||||
public function detailStore($id)
|
||||
{
|
||||
|
||||
$data = Request::all();
|
||||
$change_member_error = false;
|
||||
if ($data['action'] === 'shopping-order-change-member') {
|
||||
if (! isset($data['change_member_key']) || $data['change_member_key'] !== config('main.edit_data_pass')) {
|
||||
$change_member_error = 'Das Passwort ist falsch.';
|
||||
} else {
|
||||
// change
|
||||
$shopping_order = ShoppingOrder::findOrFail($data['id']);
|
||||
CustomerPriority::newMemberForOrder($shopping_order, $data['change_member_id'], $data['customer_set_member_for']);
|
||||
\Session()->flash('alert-save', true);
|
||||
|
||||
return redirect(route('admin_sales_detail', [$shopping_order->id]));
|
||||
}
|
||||
}
|
||||
if ($data['action'] === 'shopping-user-is-like-member') {
|
||||
if (! isset($data['change_member_key']) || $data['change_member_key'] !== config('main.edit_data_pass')) {
|
||||
\Session()->flash('alert-error', 'Das Passwort ist falsch.');
|
||||
|
||||
return redirect($data['back']);
|
||||
} else {
|
||||
if (! isset($data['is_like_shopping_user_id'])) {
|
||||
\Session()->flash('alert-error', 'Keine Änderung ausgewählt');
|
||||
|
||||
return redirect($data['back']);
|
||||
}
|
||||
$shopping_user = ShoppingUser::findOrFail($data['id']);
|
||||
$set_like_shopping_user = ShoppingUser::findOrFail($data['is_like_shopping_user_id']);
|
||||
$send_member_mail = isset($data['send_member_mail']) ? true : false;
|
||||
$change_shopping_user = isset($data['change_shopping_user']) ? true : false;
|
||||
// Mail send in setIsLike
|
||||
CustomerPriority::setIsLike($shopping_user, $set_like_shopping_user, $send_member_mail, $change_shopping_user);
|
||||
\Session()->flash('alert-save', true);
|
||||
|
||||
return redirect($data['back']);
|
||||
}
|
||||
}
|
||||
$ShoppingOrder = ShoppingOrder::find($id);
|
||||
$data = [
|
||||
'change_member_error' => $change_member_error,
|
||||
'shopping_order' => $ShoppingOrder,
|
||||
'isAdmin' => true,
|
||||
'isView' => $ShoppingOrder->auth_user_id ? 'sales_user' : 'sales_customer',
|
||||
];
|
||||
|
||||
return view('admin.sales.detail', $data);
|
||||
}
|
||||
|
||||
public function datatable()
|
||||
{
|
||||
|
||||
$query = ShoppingOrder::with('shopping_user', 'shopping_payments')->select('shopping_orders.*');
|
||||
|
||||
set_user_attr('filter_txaction', Request::get('filter_txaction'));
|
||||
if (Request::get('filter_txaction') != '') {
|
||||
if (Request::get('filter_txaction') === 'NULL') {
|
||||
$query->where('txaction', '=', null);
|
||||
|
||||
} else {
|
||||
$query->where('txaction', '=', Request::get('filter_txaction'));
|
||||
}
|
||||
}
|
||||
set_user_attr('filter_member_id', Request::get('filter_member_id'));
|
||||
if (Request::get('filter_member_id') != '') {
|
||||
$query->where('member_id', '=', Request::get('filter_member_id'));
|
||||
}
|
||||
|
||||
set_user_attr('filter_art', Request::get('filter_art'));
|
||||
if (Request::get('filter_art') != '') {
|
||||
if (Request::get('filter_art') === 'user_order') {
|
||||
$query->where('shopping_orders.auth_user_id', '!=', null)->where('payment_for', '!=', 6);
|
||||
} elseif (Request::get('filter_art') === 'customer_order') {
|
||||
$query->where('shopping_orders.auth_user_id', null);
|
||||
} elseif (Request::get('filter_art') === 'user_for_customer') {
|
||||
$query->where('shopping_user_id', '!=', null)->where('payment_for', '=', 6);
|
||||
}
|
||||
// $query->where('payment_for', '=', Request::get('filter_art'));
|
||||
}
|
||||
set_user_attr('filter_shipped', Request::get('filter_shipped'));
|
||||
if (Request::get('filter_shipped') != '') {
|
||||
$query->where('shipped', '=', Request::get('filter_shipped'));
|
||||
}
|
||||
|
||||
return \DataTables::eloquent($query)
|
||||
->addColumn('id', function (ShoppingOrder $ShoppingOrder) {
|
||||
return '<a href="'.route('admin_sales_detail', [$ShoppingOrder->id]).'" class="btn icon-btn btn-sm btn-primary"><span class="fa fa-edit"></span></a>';
|
||||
})
|
||||
->addColumn('created_at', function (ShoppingOrder $ShoppingOrder) {
|
||||
return $ShoppingOrder->created_at->format('d.m.Y');
|
||||
})
|
||||
->addColumn('txaction', function (ShoppingOrder $ShoppingOrder) {
|
||||
return Payment::getShoppingOrderBadge($ShoppingOrder);
|
||||
})
|
||||
->addColumn('total_shipping', function (ShoppingOrder $ShoppingOrder) {
|
||||
return $ShoppingOrder->getFormattedTotalShipping().' €';
|
||||
})
|
||||
->addColumn('payment', function (ShoppingOrder $ShoppingOrder) {
|
||||
return $ShoppingOrder->getLastShoppingPayment('getPaymentType');
|
||||
})
|
||||
->addColumn('shipped', function (ShoppingOrder $ShoppingOrder) {
|
||||
return '<span class="badge badge-pill badge-'.$ShoppingOrder->getShippedColor().'">'.$ShoppingOrder->getShippedType().'</span>';
|
||||
})
|
||||
->addColumn('payment_for', function (ShoppingOrder $ShoppingOrder) {
|
||||
return Payment::getPaymentForTypeBadge($ShoppingOrder);
|
||||
})
|
||||
->addColumn('reference', function (ShoppingOrder $ShoppingOrder) {
|
||||
return $ShoppingOrder->getLastShoppingPayment('reference');
|
||||
})
|
||||
->addColumn('member_id', function (ShoppingOrder $ShoppingOrder) {
|
||||
if ($ShoppingOrder->member_id) {
|
||||
return $ShoppingOrder->member_id ? '<a href="'.route('admin_lead_edit', [$ShoppingOrder->member_id]).'">'.$ShoppingOrder->member->getFullName().'</a>' : '';
|
||||
}
|
||||
if ($ShoppingOrder->shopping_user && $ShoppingOrder->shopping_user->is_like) {
|
||||
return '<button type="button" class="btn btn-xs btn-outline-info" data-toggle="modal" data-target="#modals-load-content"
|
||||
data-id="'.$ShoppingOrder->shopping_user->id.'"
|
||||
data-action="shopping-user-is-like-member"
|
||||
data-back="'.route('admin_sales').'"
|
||||
data-modal="modal-xl"
|
||||
data-route="'.route('modal_load').'"><span class="fa fa-edit"></span> Vertriebspartner zuordnen</button>';
|
||||
}
|
||||
|
||||
return '';
|
||||
})
|
||||
|
||||
->orderColumn('id', 'id $1')
|
||||
->orderColumn('txaction', 'txaction $1')
|
||||
->orderColumn('payment_for', 'payment_for $1')
|
||||
->orderColumn('member_id', 'member_id $1')
|
||||
->orderColumn('shipped', 'shipped $1')
|
||||
->orderColumn('total_shipping', 'total_shipping $1')
|
||||
->rawColumns(['id', 'member_id', 'txaction', 'user_shop_id', 'payment_for', 'shipped'])
|
||||
->make(true);
|
||||
}
|
||||
|
||||
/*public function users(){
|
||||
|
||||
if(Request::get('reset') === 'filter'){
|
||||
return redirect(route('admin_sales_users'));
|
||||
|
|
@ -81,17 +252,8 @@ class SalesController extends Controller
|
|||
->addColumn('shipped', function (ShoppingOrder $ShoppingOrder) {
|
||||
return '<span class="badge badge-pill badge-'.$ShoppingOrder->getShippedColor().'">'.$ShoppingOrder->getShippedType().'</span>';
|
||||
})
|
||||
->addColumn('is_for', function (ShoppingOrder $ShoppingOrder) {
|
||||
if($ShoppingOrder->shopping_user->is_for === 'me'){
|
||||
return '<span class="badge badge-pill badge-secondary">Vertriebspartnerbestellung</span>';
|
||||
}
|
||||
if($ShoppingOrder->shopping_user->is_for === 'ot'){
|
||||
return '<span class="badge badge-pill badge-info">Kundenbestellung</span>';
|
||||
}
|
||||
if($ShoppingOrder->shopping_user->is_for === 'hp'){
|
||||
return '<span class="badge badge-pill badge-dark">Homepartybestellung</span>';
|
||||
}
|
||||
return '-';
|
||||
->addColumn('payment_for', function (ShoppingOrder $ShoppingOrder) {
|
||||
return Payment::getPaymentForTypeBadge($ShoppingOrder);
|
||||
})
|
||||
->addColumn('reference', function (ShoppingOrder $ShoppingOrder) {
|
||||
return $ShoppingOrder->getLastShoppingPayment('reference');
|
||||
|
|
@ -101,10 +263,11 @@ class SalesController extends Controller
|
|||
})
|
||||
->orderColumn('id', 'id $1')
|
||||
->orderColumn('txaction', 'txaction $1')
|
||||
->orderColumn('payment_for', 'payment_for $1')
|
||||
->orderColumn('shipped', 'shipped $1')
|
||||
->orderColumn('total_shipping', 'total_shipping $1')
|
||||
|
||||
->rawColumns(['id', 'txaction', 'is_for', 'shipped'])
|
||||
->rawColumns(['id', 'txaction', 'payment_for', 'shipped'])
|
||||
->make(true);
|
||||
}
|
||||
|
||||
|
|
@ -113,7 +276,7 @@ class SalesController extends Controller
|
|||
if(Request::get('reset') === 'filter'){
|
||||
set_user_attr('filter_txaction', null);
|
||||
set_user_attr('filter_member_id', null);
|
||||
return redirect(route('admin_sales_customers'));
|
||||
return redirect(route('admin_sales'));
|
||||
}
|
||||
$filter_members = ShoppingOrder::join('users', 'member_id', '=', 'users.id')->groupBy('member_id')->join('user_accounts', 'account_id', '=', 'user_accounts.id')->select('users.id', 'users.email', 'user_accounts.first_name', 'user_accounts.last_name')->get(); //->pluck('email', 'id')->unique()->toArray();
|
||||
$data = [
|
||||
|
|
@ -149,7 +312,7 @@ class SalesController extends Controller
|
|||
$shopping_order = ShoppingOrder::findOrFail($data['id']);
|
||||
CustomerPriority::newMemberForOrder($shopping_order, $data['change_member_id'], $data['customer_set_member_for']);
|
||||
\Session()->flash('alert-save', true);
|
||||
return redirect(route('admin_sales_customers_detail', [$shopping_order->id]));
|
||||
return redirect(route('admin_sales_detail', [$shopping_order->id]));
|
||||
}
|
||||
}
|
||||
if($data['action']==='shopping-user-is-like-member'){
|
||||
|
|
@ -177,7 +340,7 @@ class SalesController extends Controller
|
|||
'isAdmin' => true,
|
||||
'isView' => 'sales_customer',
|
||||
];
|
||||
return view('admin.sales.customer_detail', $data);
|
||||
return view('admin.sales._detail', $data);
|
||||
}
|
||||
|
||||
public function customersDatatable(){
|
||||
|
|
@ -200,7 +363,7 @@ class SalesController extends Controller
|
|||
|
||||
return \DataTables::eloquent($query)
|
||||
->addColumn('id', function (ShoppingOrder $ShoppingOrder) {
|
||||
return '<a href="' . route('admin_sales_customers_detail', [$ShoppingOrder->id]) . '" class="btn icon-btn btn-sm btn-primary"><span class="fa fa-edit"></span></a>';
|
||||
return '<a href="' . route('admin_sales_detail', [$ShoppingOrder->id]) . '" class="btn icon-btn btn-sm btn-primary"><span class="fa fa-edit"></span></a>';
|
||||
})
|
||||
->addColumn('created_at', function (ShoppingOrder $ShoppingOrder) {
|
||||
return $ShoppingOrder->created_at->format("d.m.Y");
|
||||
|
|
@ -217,17 +380,8 @@ class SalesController extends Controller
|
|||
->addColumn('shipped', function (ShoppingOrder $ShoppingOrder) {
|
||||
return '<span class="badge badge-pill badge-'.$ShoppingOrder->getShippedColor().'">'.$ShoppingOrder->getShippedType().'</span>';
|
||||
})
|
||||
->addColumn('is_for', function (ShoppingOrder $ShoppingOrder) {
|
||||
if($ShoppingOrder->shopping_user->is_for === 'me'){
|
||||
return '<span class="badge badge-pill badge-secondary">Vertriebspartnerbestellung</span>';
|
||||
}
|
||||
if($ShoppingOrder->shopping_user->is_for === 'ot'){
|
||||
return '<span class="badge badge-pill badge-info">Kundenbestellung</span>';
|
||||
}
|
||||
if($ShoppingOrder->shopping_user->is_for === 'hp'){
|
||||
return '<span class="badge badge-pill badge-dark">Homepartybestellung</span>';
|
||||
}
|
||||
return '-';
|
||||
->addColumn('payment_for', function (ShoppingOrder $ShoppingOrder) {
|
||||
return Payment::getPaymentForTypeBadge($ShoppingOrder);
|
||||
})
|
||||
->addColumn('reference', function (ShoppingOrder $ShoppingOrder) {
|
||||
return $ShoppingOrder->getLastShoppingPayment('reference');
|
||||
|
|
@ -239,9 +393,9 @@ class SalesController extends Controller
|
|||
if($ShoppingOrder->shopping_user && $ShoppingOrder->shopping_user->is_like){
|
||||
return '<button type="button" class="btn btn-xs btn-outline-info" data-toggle="modal" data-target="#modals-load-content"
|
||||
data-id="'.$ShoppingOrder->shopping_user->id.'"
|
||||
data-action="shopping-user-is-like-member"
|
||||
data-back="'.route('admin_sales_customers').'"
|
||||
data-modal="modal-xl"
|
||||
data-action="shopping-user-is-like-member"
|
||||
data-back="'.route('admin_sales').'"
|
||||
data-modal="modal-xl"
|
||||
data-route="'.route('modal_load').'"><span class="fa fa-edit"></span> Vertriebspartner zuordnen</button>';
|
||||
}
|
||||
return '';
|
||||
|
|
@ -249,130 +403,166 @@ class SalesController extends Controller
|
|||
|
||||
->orderColumn('id', 'id $1')
|
||||
->orderColumn('txaction', 'txaction $1')
|
||||
->orderColumn('payment_for', 'payment_for $1')
|
||||
->orderColumn('member_id', 'member_id $1')
|
||||
->orderColumn('shipped', 'shipped $1')
|
||||
->orderColumn('total_shipping', 'total_shipping $1')
|
||||
->rawColumns(['id', 'member_id', 'txaction', 'user_shop_id', 'is_for', 'shipped'])
|
||||
->rawColumns(['id', 'member_id', 'txaction', 'user_shop_id', 'payment_for', 'shipped'])
|
||||
->make(true);
|
||||
}
|
||||
}*/
|
||||
|
||||
public function store(){
|
||||
public function store()
|
||||
{
|
||||
$data = Request::all();
|
||||
if(!isset($data['id'])){
|
||||
if (! isset($data['id'])) {
|
||||
abort(404);
|
||||
}
|
||||
if(isset($data['action'])){
|
||||
if($data['action'] === 'store_shipped' && isset($data['shipped'])){
|
||||
if (isset($data['action'])) {
|
||||
if ($data['action'] === 'store_shipped' && isset($data['shipped'])) {
|
||||
$shopping_order = ShoppingOrder::findOrFail($data['id']);
|
||||
$shopping_order->shipped = $data['shipped'];
|
||||
$shopping_order->save();
|
||||
// handel Promotion Product and credit by storno
|
||||
Payment::handelUserPromotionOrder($shopping_order);
|
||||
Payment::handelUserShopOrder($shopping_order);
|
||||
|
||||
if($shopping_order->getAPIShippedType() === 'sent' || $shopping_order->getAPIShippedType() === 'close'){
|
||||
if(!$shopping_order->shipped_at){
|
||||
if ($shopping_order->getAPIShippedType() === 'sent' || $shopping_order->getAPIShippedType() === 'close') {
|
||||
if (! $shopping_order->shipped_at) {
|
||||
$shopping_order->shipped_at = now();
|
||||
$shopping_order->save();
|
||||
//set to oder_margin
|
||||
if($shopping_order->shopping_order_margin && $shopping_order->shopping_order_margin->hasPartnerCommission()){
|
||||
$days = Setting::getContentBySlug('pending_partner_commissions_in_days');
|
||||
$days = $days ? $days : 20;
|
||||
$partner_commission_pending_to = $shopping_order->shipped_at;
|
||||
$partner_commission_pending_to->addDays($days);
|
||||
$shopping_order->shopping_order_margin->partner_commission_pending_to = $partner_commission_pending_to;
|
||||
$shopping_order->shopping_order_margin->save();
|
||||
// is shipped set pending_to
|
||||
if ($shopping_order->shopping_order_margin) {
|
||||
if ($shopping_order->shopping_order_margin->hasPartnerCommission()) {
|
||||
$days = Setting::getContentBySlug('pending_partner_commissions_in_days');
|
||||
$days = $days ? $days : 20;
|
||||
$partner_commission_pending_to = $shopping_order->shipped_at;
|
||||
$partner_commission_pending_to->addDays($days);
|
||||
$shopping_order->shopping_order_margin->partner_commission_pending_to = $partner_commission_pending_to;
|
||||
$shopping_order->shopping_order_margin->save();
|
||||
} else {
|
||||
$days = Setting::getContentBySlug('pending_order_margins_in_days');
|
||||
$days = $days ? $days : 20;
|
||||
$margin_pending_to = $shopping_order->shipped_at;
|
||||
$margin_pending_to->addDays($days);
|
||||
$shopping_order->shopping_order_margin->margin_pending_to = $margin_pending_to;
|
||||
$shopping_order->shopping_order_margin->save();
|
||||
}
|
||||
}
|
||||
}
|
||||
}else{
|
||||
} else {
|
||||
$shopping_order->shipped_at = null;
|
||||
$shopping_order->save();
|
||||
if($shopping_order->shopping_order_margin && $shopping_order->shopping_order_margin->hasPartnerCommission()){
|
||||
if ($shopping_order->shopping_order_margin) {
|
||||
// zurücksetzen der pending_to
|
||||
$shopping_order->shopping_order_margin->partner_commission_pending_to = null;
|
||||
$shopping_order->shopping_order_margin->margin_pending_to = null;
|
||||
$shopping_order->shopping_order_margin->save();
|
||||
}
|
||||
}
|
||||
if($shopping_order->getAPIShippedType() === 'cancel'){
|
||||
if($shopping_order->shopping_order_margin){
|
||||
if ($shopping_order->getAPIShippedType() === 'cancel') {
|
||||
if ($shopping_order->shopping_order_margin) {
|
||||
$shopping_order->shopping_order_margin->cancellation = true;
|
||||
$shopping_order->shopping_order_margin->partner_commission_pending_to = null;
|
||||
$shopping_order->shopping_order_margin->margin_pending_to = null;
|
||||
$shopping_order->shopping_order_margin->save();
|
||||
}
|
||||
}else{
|
||||
if($shopping_order->shopping_order_margin && $shopping_order->shopping_order_margin->cancellation){
|
||||
} else {
|
||||
if ($shopping_order->shopping_order_margin && $shopping_order->shopping_order_margin->cancellation) {
|
||||
$shopping_order->shopping_order_margin->cancellation = false;
|
||||
$shopping_order->shopping_order_margin->partner_commission_pending_to = null;
|
||||
$shopping_order->shopping_order_margin->margin_pending_to = null;
|
||||
$shopping_order->shopping_order_margin->save();
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
|
||||
if($data['action'] === 'store_txaction' && isset($data['txaction']) && isset($data['payment_id'])){
|
||||
$shopping_order = ShoppingOrder::findOrFail($data['id']);
|
||||
$shopping_payment = ShoppingPayment::findOrFail($data['payment_id']);
|
||||
|
||||
if($shopping_order->shopping_order_margin && $shopping_order->shopping_order_margin->from_payment_credit > 0){
|
||||
$last_UserPayCredit = UserPayCredit::where('shopping_order_id', $shopping_order->id)->whereIn('status', [2, 4])->orderBy('id', 'DESC')->first();
|
||||
//Status Keine Zahlung, Guthaben zurückführen, wenn status 2 / deduction from payment
|
||||
if($last_UserPayCredit && $data['txaction'] === 'non' && $last_UserPayCredit->status === 2){
|
||||
Payment::handelUserPayCredits($shopping_order, 'return');
|
||||
}
|
||||
//Status Zahlung, voher gab es eine Storno, Guthaben abziehen wenn status 4 / return from order
|
||||
if($last_UserPayCredit && $last_UserPayCredit->status === 4 && ($data['txaction'] === 'open' || $data['txaction'] === 'paid')){
|
||||
Payment::handelUserPayCredits($shopping_order, 'deduction');
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
$payt = PaymentTransaction::create([
|
||||
'shopping_payment_id' => $shopping_payment->id,
|
||||
'request' => 'transaction',
|
||||
'txid' => 0,
|
||||
'userid' => 0,
|
||||
'status' => $shopping_payment->clearingtype,
|
||||
'transmitted_data' => NULL,
|
||||
'txaction' => $data['txaction'],
|
||||
'mode' => $shopping_payment->mode,
|
||||
]);
|
||||
|
||||
$shopping_order->txaction = $data['txaction'];
|
||||
$shopping_order->paid = $payt->txaction === 'paid' ? true : false;
|
||||
$shopping_order->save();
|
||||
$shopping_payment->txaction = $data['txaction'];
|
||||
$shopping_payment->save();
|
||||
|
||||
if($payt->status === 'vor' && $payt->txaction === 'paid'){
|
||||
$send_link = Payment::paymentStatusPaidAction($shopping_order, true);
|
||||
}
|
||||
|
||||
$edata = [
|
||||
'mode' => $payt->mode,
|
||||
'txaction' => $payt->txaction,
|
||||
'send_link' => false,
|
||||
];
|
||||
//TODO can send MAIL
|
||||
Payment::paymentStatusSendMail($shopping_order, $shopping_payment, $edata);
|
||||
/* txaction ändern
|
||||
änderung der txaction von der Bestellung, Status Zahlung, offen, bezahlt, keine zahlung */
|
||||
if ($data['action'] === 'store_txaction' && isset($data['txaction']) && isset($data['payment_id'])) {
|
||||
PaymentService::updateTransactionStatus($data['id'], $data['txaction'], $data['payment_id']);
|
||||
}
|
||||
|
||||
}
|
||||
if(isset($data['back'])){
|
||||
if (isset($data['back'])) {
|
||||
return redirect($data['back']);
|
||||
}
|
||||
|
||||
return back();
|
||||
}
|
||||
|
||||
|
||||
public function invoice(){
|
||||
public function invoice()
|
||||
{
|
||||
$data = Request::all();
|
||||
//$data['id'] ShoppingOrder id
|
||||
if(!isset($data['id'])){
|
||||
if (! isset($data['id'])) {
|
||||
abort(404);
|
||||
}
|
||||
if(isset($data['action'])){
|
||||
if($data['action'] === 'create_invoice'){
|
||||
if (isset($data['action'])) {
|
||||
if ($data['action'] === 'create_invoice') {
|
||||
$shopping_order = ShoppingOrder::findOrFail($data['id']);
|
||||
$invoice_repo = new InvoiceRepository($shopping_order);
|
||||
$invoice_repo->create($data);
|
||||
return redirect(route('admin_sales_users_detail', [$shopping_order->id]));
|
||||
if (Invoice::isInvoice($shopping_order)) {
|
||||
$user_invoice = $invoice_repo->update($data);
|
||||
} else {
|
||||
$user_invoice = $invoice_repo->create($data);
|
||||
}
|
||||
|
||||
return redirect(route('admin_sales_detail', [$shopping_order->id]));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
public function invoiceCancellation()
|
||||
{
|
||||
$data = Request::all();
|
||||
if (! isset($data['id'])) {
|
||||
abort(404);
|
||||
}
|
||||
if (isset($data['action'])) {
|
||||
if ($data['action'] === 'create_cancellation_invoice') {
|
||||
$shopping_order = ShoppingOrder::findOrFail($data['id']);
|
||||
|
||||
// Prüfen ob bereits eine Rechnung existiert
|
||||
if (! Invoice::isInvoice($shopping_order)) {
|
||||
\Session()->flash('alert-error', 'Es existiert keine Rechnung, die storniert werden kann.');
|
||||
|
||||
return redirect(route('admin_sales_detail', [$shopping_order->id]));
|
||||
}
|
||||
|
||||
// Prüfen ob bereits eine Stornorechnung existiert
|
||||
if (Invoice::isCancellationInvoice($shopping_order)) {
|
||||
\Session()->flash('alert-error', 'Es existiert bereits eine Stornorechnung für diese Bestellung.');
|
||||
|
||||
return redirect(route('admin_sales_detail', [$shopping_order->id]));
|
||||
}
|
||||
|
||||
$invoice_repo = new InvoiceRepository($shopping_order);
|
||||
$cancellation_invoice = $invoice_repo->createCancellation($data);
|
||||
|
||||
if ($cancellation_invoice) {
|
||||
\Session()->flash('alert-success', 'Stornorechnung wurde erfolgreich erstellt.');
|
||||
} else {
|
||||
\Session()->flash('alert-error', 'Fehler beim Erstellen der Stornorechnung.');
|
||||
}
|
||||
|
||||
return redirect(route('admin_sales_detail', [$shopping_order->id]));
|
||||
}
|
||||
}
|
||||
|
||||
return redirect(route('admin_sales'));
|
||||
}
|
||||
|
||||
public function sendLogisticMail($id)
|
||||
{
|
||||
$shopping_order = ShoppingOrder::findOrFail($id);
|
||||
|
||||
if (Invoice::isInvoice($shopping_order)) {
|
||||
Invoice::sendLogisticMail($shopping_order);
|
||||
\Session()->flash('alert-success', 'Rechnung / Lieferschein wurde an den Versand gesendet.');
|
||||
} else {
|
||||
\Session()->flash('alert-error', 'Keine Rechnung vorhanden.');
|
||||
}
|
||||
|
||||
return redirect(route('admin_sales_detail', [$shopping_order->id]));
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -24,7 +24,7 @@ class SettingController extends Controller
|
|||
{
|
||||
|
||||
$data = [
|
||||
'values' => Ingredient::all(),
|
||||
'values' => [],
|
||||
];
|
||||
return view('admin.settings.index', $data);
|
||||
}
|
||||
|
|
|
|||
192
app/Http/Controllers/Stats/SalesController.php
Executable file
192
app/Http/Controllers/Stats/SalesController.php
Executable file
|
|
@ -0,0 +1,192 @@
|
|||
<?php
|
||||
|
||||
|
||||
namespace App\Http\Controllers\Stats;
|
||||
|
||||
use Auth;
|
||||
use Request;
|
||||
use App\User;
|
||||
use Carbon\Carbon;
|
||||
use Faker\Core\Number;
|
||||
use App\Exports\ExcelExport;
|
||||
use App\Services\HTMLHelper;
|
||||
use App\Models\ShoppingOrder;
|
||||
use App\Services\Stats\Sales;
|
||||
use App\Models\ShoppingOrderItem;
|
||||
use App\Http\Controllers\Controller;
|
||||
use Maatwebsite\Excel\Facades\Excel;
|
||||
use App\Services\BusinessPlan\ExportBot;
|
||||
use Illuminate\Database\Eloquent\Collection;
|
||||
|
||||
class SalesController extends Controller
|
||||
{
|
||||
|
||||
private $serviceSales;
|
||||
|
||||
public function __construct(Sales $serviceSales)
|
||||
{
|
||||
$this->middleware('admin');
|
||||
$this->serviceSales = $serviceSales;
|
||||
}
|
||||
|
||||
public function index()
|
||||
{
|
||||
$this->setFilterVars();
|
||||
$data = [
|
||||
'filter_months' => HTMLHelper::getTransMonths(true),
|
||||
'filter_years' => HTMLHelper::getYearRange(2020),
|
||||
'filter_products' => $this->serviceSales->setFilterProducts(),
|
||||
];
|
||||
return view('admin.stats.salesvolume', $data);
|
||||
}
|
||||
|
||||
|
||||
public function download()
|
||||
{
|
||||
$this->setFilterVars();
|
||||
|
||||
if (Request::get('action') === "filter") {
|
||||
// $data = Request::all();
|
||||
return back();
|
||||
}
|
||||
|
||||
if (Request::get('action') === "export") {
|
||||
$objects = $this->serviceSales->getObjects();
|
||||
$columns = [];
|
||||
$filename = "gs-absatzmengen-" . session('product_sales_vol_filter_month') . '_' . session('product_sales_vol_filter_year') . "-export";
|
||||
$headers = array(
|
||||
'#',
|
||||
'Produkt',
|
||||
'Artikelnummer',
|
||||
'Menge',
|
||||
'Gesamt Netto in EURO',
|
||||
'Vorjahr Menge',
|
||||
'Vorjahr Gesamt Netto in EURO',
|
||||
'Einzelrabatt',
|
||||
'Einzelrabatt %',
|
||||
'VP Einzelrabatt %',
|
||||
|
||||
|
||||
);
|
||||
if ($objects) {
|
||||
foreach ($objects as $key => $obj) {
|
||||
$columns[] = array(
|
||||
'id' => $key,
|
||||
'name' => $obj['name'],
|
||||
'number' => $obj['number'],
|
||||
'qty' => $obj['qty'],
|
||||
'total' => $obj['total'],
|
||||
'pre_qty' => $obj['pre_qty'],
|
||||
'pre_total' => $obj['pre_total'],
|
||||
'single_commission' => $obj['single_commission'],
|
||||
'value_commission' => $obj['value_commission'],
|
||||
'partner_commission' => $obj['partner_commission'],
|
||||
|
||||
);
|
||||
}
|
||||
}
|
||||
return Excel::download(new ExcelExport($columns, $headers), $filename . '.xls');
|
||||
}
|
||||
}
|
||||
|
||||
private function setFilterVars()
|
||||
{
|
||||
|
||||
if (!session('product_sales_vol_filter_month')) {
|
||||
session(['product_sales_vol_filter_month' => intval(date('m'))]);
|
||||
}
|
||||
if (!session('product_sales_vol_filter_year')) {
|
||||
session(['product_sales_vol_filter_year' => intval(date('Y'))]);
|
||||
}
|
||||
if (!session('product_sales_vol_filter_products')) {
|
||||
session(['product_sales_vol_filter_products' => []]);
|
||||
}
|
||||
if (Request::get('product_sales_vol_filter_month')) {
|
||||
session(['product_sales_vol_filter_month' => Request::get('product_sales_vol_filter_month')]);
|
||||
}
|
||||
if (Request::get('product_sales_vol_filter_year')) {
|
||||
session(['product_sales_vol_filter_year' => Request::get('product_sales_vol_filter_year')]);
|
||||
}
|
||||
if (Request::get('product_sales_vol_filter_products')) {
|
||||
session(['product_sales_vol_filter_products' => Request::get('product_sales_vol_filter_products')]);
|
||||
}
|
||||
|
||||
$this->serviceSales->setFilterVars(
|
||||
session('product_sales_vol_filter_month'),
|
||||
session('product_sales_vol_filter_year'),
|
||||
session('product_sales_vol_filter_products')
|
||||
);
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
public function datatable()
|
||||
{
|
||||
|
||||
$this->setFilterVars();
|
||||
$collection = $this->serviceSales->getCollection();
|
||||
|
||||
/* $collect = collect([
|
||||
['id' => 1, 'name' => 'John', 'number'=>92012, 'value'=>123],
|
||||
['id' => 2, 'name' => 'Jane', 'number'=>92012, 'value'=>123],
|
||||
['id' => 3, 'name' => 'James', 'number'=>92012, 'value'=>123],
|
||||
]);
|
||||
*/
|
||||
|
||||
return \DataTables::of($collection)->toJson();
|
||||
}
|
||||
|
||||
/*private function testCheckFunction(){
|
||||
|
||||
//$date_start = Carbon::parse('01.'.session('product_sales_vol_filter_month').'.'.session('product_sales_vol_filter_year'))->format('Y-m-d');
|
||||
//$date_end = Carbon::parse('01.'.session('product_sales_vol_filter_month').'.'.session('product_sales_vol_filter_year'))->endOfMonth()->format('Y-m-d');
|
||||
|
||||
$date_start = Carbon::parse('01.01.2024')->format('Y-m-d H:i:s');
|
||||
$date_end = Carbon::parse('01.01.2024')->endOfMonth()->format('Y-m-d H:i:s');
|
||||
dump($date_start);
|
||||
dump($date_end);
|
||||
|
||||
$ShoppingOrders = ShoppingOrder::where('mode', 'live')->whereBetween('created_at', [$date_start, $date_end])->get();
|
||||
|
||||
$objects = [];
|
||||
$counter = 0;
|
||||
foreach($ShoppingOrders as $ShoppingOrder){
|
||||
foreach($ShoppingOrder->shopping_order_items as $shopping_order_item){
|
||||
|
||||
if($shopping_order_item->product){
|
||||
if($shopping_order_item->product->id === 122){
|
||||
//dump($shopping_order_item->qty);
|
||||
//$counter += $shopping_order_item->qty;
|
||||
if(isset($objects[$shopping_order_item->product->id])){
|
||||
$value = intval($objects[$shopping_order_item->product->id]['value'] + $shopping_order_item->qty);
|
||||
$objects[$shopping_order_item->product->id]['value'] = $value;
|
||||
}else{
|
||||
$objects[$shopping_order_item->product->id] = [
|
||||
'name' => $shopping_order_item->product->name,
|
||||
'number' => $shopping_order_item->product->number,
|
||||
'value' => $shopping_order_item->qty
|
||||
];
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
$ShoppingOrderItems = ShoppingOrderItem::whereProductId(122)->whereBetween('created_at', [$date_start, $date_end])->get();
|
||||
$counter = 0;
|
||||
foreach($ShoppingOrderItems as $ShoppingOrderItem){
|
||||
$counter += $ShoppingOrderItem->qty;
|
||||
dump($ShoppingOrderItem->id);
|
||||
}
|
||||
// dump($objects);
|
||||
dump($counter);
|
||||
dd("OKAY");
|
||||
}*/
|
||||
}
|
||||
|
|
@ -35,10 +35,9 @@ class AdminToolsController extends Controller
|
|||
public function index($action)
|
||||
{
|
||||
|
||||
dd($action);
|
||||
switch ($action) {
|
||||
case 'pay_credits':
|
||||
# code...
|
||||
dd($action);
|
||||
$value = $this->makeUserPayCredits();
|
||||
$data = [
|
||||
'values' => $value,
|
||||
|
|
@ -46,9 +45,28 @@ class AdminToolsController extends Controller
|
|||
];
|
||||
return view('sys.admin.index', $data);
|
||||
break;
|
||||
case 'value':
|
||||
# code...
|
||||
break;
|
||||
case 'export_vp':
|
||||
$values = User::with('account')->select('users.*')->where('users.deleted_at', '=', null)->where('users.admin', "<", 4)->get();
|
||||
$data = [
|
||||
'values' => $values,
|
||||
'text' => '',
|
||||
];
|
||||
return view('sys.admin.export_vp', $data);
|
||||
break;
|
||||
|
||||
case 'dbaction':
|
||||
$values = [];
|
||||
$data = [
|
||||
'values' => $values,
|
||||
//'text' => 'Add payment_for in shopping_order', //_dbOrderPaymentFor
|
||||
//'text' => 'Calculate TAX for shopping_order in tax_split array ',
|
||||
'text' => 'show in AdminToolsController dbaction',
|
||||
|
||||
|
||||
];
|
||||
return view('sys.admin.index', $data);
|
||||
break;
|
||||
|
||||
}
|
||||
|
||||
|
||||
|
|
@ -57,23 +75,76 @@ class AdminToolsController extends Controller
|
|||
|
||||
public function store($action)
|
||||
{
|
||||
|
||||
|
||||
dd($action);
|
||||
|
||||
|
||||
$data = [];
|
||||
switch ($action) {
|
||||
case 'pay_credits':
|
||||
# code...
|
||||
dd($action);
|
||||
return view('sys.admin.index', $data);
|
||||
|
||||
break;
|
||||
case 'value':
|
||||
# code...
|
||||
case 'export_vp':
|
||||
return $this->export_vp();
|
||||
break;
|
||||
case 'dbaction':
|
||||
//return $this->_dbOrderPaymentFor();
|
||||
break;
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
private function _dbOrderPaymentFor(){
|
||||
$c = 0;
|
||||
$ShoppingUsers = ShoppingUser::all();
|
||||
foreach($ShoppingUsers as $ShoppingUser){
|
||||
if($ShoppingUser->shopping_order){
|
||||
$ShoppingUser->shopping_order->payment_for = $ShoppingUser->getOrderPaymentFor();
|
||||
$ShoppingUser->shopping_order->save();
|
||||
$c ++;
|
||||
}
|
||||
}
|
||||
dd($c);
|
||||
}
|
||||
private function export_vp(){
|
||||
|
||||
$query = User::with('account')->select('users.*')->where('users.deleted_at', '=', null)->where('users.admin', "<", 4)->get();
|
||||
$fileName = "GS-VP-export-".date("d-m-Y").".csv";
|
||||
$headers = array(
|
||||
"Content-type" => "text/csv",
|
||||
"Content-Disposition" => "attachment; filename=$fileName",
|
||||
"Pragma" => "no-cache",
|
||||
"Cache-Control" => "must-revalidate, post-check=0, pre-check=0",
|
||||
"Expires" => "0"
|
||||
);
|
||||
|
||||
$columns = array('ID', 'Email', 'Firma', 'Anrede', 'Vorname', 'Nachname', 'Mitglied', 'Bis');
|
||||
$callback = function() use($query, $columns) {
|
||||
|
||||
$file = fopen('php://output', 'w');
|
||||
fputcsv($file, $columns);
|
||||
$row = [];
|
||||
|
||||
foreach ($query as $val) {
|
||||
$row['ID'] = $val->id;
|
||||
$row['Email'] = $val->email;
|
||||
$row['Firma'] = $val->account->company;
|
||||
$row['Anrede'] = $val->account->salutation == 'mr' ? 'Herr' : 'Frau' ;
|
||||
$row['Vorname'] = $val->account->first_name;
|
||||
$row['Nachname'] = $val->account->last_name;
|
||||
$row['Mitglied'] = $val->payment_account ? ($val->isActiveAccount() ? 'JA' : 'Abgelaufen') : "Nein";
|
||||
$row['Bis'] = $val->payment_account ? $val->getPaymentAccountDateFormat(false) : "-";
|
||||
fputcsv($file, $row);
|
||||
|
||||
}
|
||||
|
||||
fclose($file);
|
||||
};
|
||||
|
||||
return response()->stream($callback, 200, $headers);
|
||||
|
||||
//dd("ok");
|
||||
|
||||
}
|
||||
|
||||
private function makeUserPayCredits()
|
||||
{
|
||||
//is the first of
|
||||
|
|
@ -214,7 +285,7 @@ class AdminToolsController extends Controller
|
|||
$text = "";
|
||||
|
||||
$kas = new KasController();
|
||||
$domain = 'mivita.care';
|
||||
$domain = 'hier die DOMAIN';
|
||||
|
||||
$ssl = KasSLLController::getApiSSLParameter();
|
||||
|
||||
|
|
|
|||
|
|
@ -106,7 +106,6 @@ class CheckoutController extends Controller
|
|||
$shopping_user->billing_state = Shop::getCountryShippingCountryId($shopping_user->billing_country_id);
|
||||
$shopping_user->shipping_state = Shop::getCountryShippingCountryId($shopping_user->shipping_country_id);
|
||||
$shopping_user->same_as_billing = $shopping_user->same_as_billing ? false : true; //reinvert
|
||||
|
||||
}
|
||||
if($shopping_user->same_as_billing === NULL){
|
||||
$shopping_user->same_as_billing = false;
|
||||
|
|
@ -410,7 +409,7 @@ class CheckoutController extends Controller
|
|||
'shopping_user_id' => $shopping_user->id,
|
||||
'auth_user_id' => $shopping_user->auth_user_id,
|
||||
'country_id' => Yard::instance('shopping')->getShippingCountryId(),
|
||||
'payment_for' => Util::getUserPaymentFor(),
|
||||
'payment_for' => $shopping_user->getOrderPaymentFor(),
|
||||
'total' => Yard::instance('shopping')->total(2, '.', ''),
|
||||
'subtotal_full' => Yard::instance('shopping')->subtotal(2, '.', '', false),
|
||||
'discount' => $discount,
|
||||
|
|
@ -499,11 +498,16 @@ class CheckoutController extends Controller
|
|||
'net_amount' => Yard::instance('shopping')->getYardMargin()->net_amount,
|
||||
'from_payment_credit' => Yard::instance('shopping')->totalfromCredit(2, '.', ''),
|
||||
'from' => now(),
|
||||
'status' => $shopping_order->payment_for, //7 => 'from promotion', 8 => 'from shop',
|
||||
'content' => serialize(Yard::instance('shopping')->getYardMargin()->toArray())
|
||||
];
|
||||
if(Yard::instance('shopping')->getYardMargin()->net_partner_commission > 0){
|
||||
$data['m_sponsor_id'] = $shopping_order->auth_user->m_sponsor;
|
||||
$data['net_partner_commission'] = Yard::instance('shopping')->getYardMargin()->net_partner_commission;
|
||||
if(isset($shopping_order->auth_user->m_sponsor)){
|
||||
if($shopping_order->auth_user->user_sponsor && $shopping_order->auth_user->user_sponsor->isActiveAccount()){
|
||||
$data['m_sponsor_id'] = $shopping_order->auth_user->m_sponsor;
|
||||
$data['net_partner_commission'] = Yard::instance('shopping')->getYardMargin()->net_partner_commission;
|
||||
}
|
||||
}
|
||||
}
|
||||
$shopping_order_margin = false;
|
||||
if ($this->getPayments('shopping_order_margin_id')) {
|
||||
|
|
@ -518,6 +522,7 @@ class CheckoutController extends Controller
|
|||
$this->putPayments('shopping_order_margin_id', $shopping_order_margin->id);
|
||||
}
|
||||
}
|
||||
|
||||
private function putPayments($key, $value){
|
||||
$content = $this->getContent();
|
||||
$content->put($key, $value);
|
||||
|
|
@ -581,8 +586,6 @@ class CheckoutController extends Controller
|
|||
];
|
||||
Payment::paymentStatusSendMail($shopping_order, $shopping_payment, $data);
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
|
|
@ -370,7 +370,11 @@ class HomepartyController extends Controller
|
|||
$date = date('d.m.Y H:i:s', $time);
|
||||
$user = User::find(Auth::user()->id);
|
||||
Yard::instance('shopping')->destroy();
|
||||
Yard::instance('shopping')->add($homeparty->id, 'Bestellung Homeparty '.$date, 1, \App\Services\HomepartyCart::$price, ['image' => "", 'slug' => $time, 'weight' => 0]);
|
||||
die("STOP nicht getestet");
|
||||
Yard::instance('shopping')->add($homeparty->id, 'Bestellung Homeparty '.$date, 1, \App\Services\HomepartyCart::$price, /*need TAX*/ 1, ['image' => "", 'slug' => $time, 'weight' => 0]);
|
||||
|
||||
// $cartItem = Yard::instance('shopping')->add($homeparty->id, 'Bestellung Homeparty '.$date, 1, \App\Services\HomepartyCart::$ek_price, false, false, ['image' => "", 'slug' => $time, 'weight' => 0]);
|
||||
Yard::setTax($cartItem->rowId, 0);
|
||||
do {
|
||||
$identifier = Util::getToken();
|
||||
} while( ShoppingInstance::where('identifier', $identifier)->count() );
|
||||
|
|
|
|||
94
app/Http/Controllers/User/MyOrderController.php
Normal file
94
app/Http/Controllers/User/MyOrderController.php
Normal file
|
|
@ -0,0 +1,94 @@
|
|||
<?php
|
||||
|
||||
|
||||
namespace App\Http\Controllers\User;
|
||||
use Auth;
|
||||
use Yard;
|
||||
use Request;
|
||||
use App\User;
|
||||
use Validator;
|
||||
use App\Services\Util;
|
||||
use App\Models\Product;
|
||||
use App\Models\UserShop;
|
||||
use App\Services\Payment;
|
||||
use App\Models\UserHistory;
|
||||
use App\Models\ShoppingUser;
|
||||
use App\Models\ShoppingOrder;
|
||||
use App\Models\ProductCategory;
|
||||
use App\Models\ShippingCountry;
|
||||
use App\Models\ShoppingInstance;
|
||||
use App\Http\Controllers\Controller;
|
||||
use App\Models\ProductBuy;
|
||||
|
||||
class MyOrderController extends Controller
|
||||
{
|
||||
|
||||
public function __construct()
|
||||
{
|
||||
$this->middleware('active.account');
|
||||
}
|
||||
|
||||
public function index()
|
||||
{
|
||||
|
||||
$data = [
|
||||
];
|
||||
return view('user.order.index', $data);
|
||||
}
|
||||
|
||||
public function detail($id)
|
||||
{
|
||||
$user = User::find(\Auth::user()->id);
|
||||
$shopping_order = ShoppingOrder::findOrFail($id);
|
||||
if($shopping_order->auth_user_id !== $user->id){
|
||||
abort(404);
|
||||
}
|
||||
$shopping_order->getLastShoppingPayment();
|
||||
|
||||
$data = [
|
||||
'shopping_order' => $shopping_order,
|
||||
'isAdmin' => false,
|
||||
];
|
||||
return view('user.order.detail', $data);
|
||||
}
|
||||
|
||||
public function datatable(){
|
||||
|
||||
$user = User::find(\Auth::user()->id);
|
||||
$query = ShoppingOrder::with('shopping_user', 'shopping_payments')->select('shopping_orders.*')->where('auth_user_id', '=', $user->id)->where('txaction', '!=', NULL);
|
||||
|
||||
return \DataTables::eloquent($query)
|
||||
->addColumn('id', function (ShoppingOrder $ShoppingOrder) {
|
||||
return '<a href="' . route('user_myorder_detail', [$ShoppingOrder->id]) . '" class="btn icon-btn btn-sm btn-primary"><span class="fa fa-edit"></span></a>';
|
||||
})
|
||||
->addColumn('created_at', function (ShoppingOrder $ShoppingOrder) {
|
||||
return $ShoppingOrder->created_at->format("d.m.Y");
|
||||
})
|
||||
->addColumn('txaction', function (ShoppingOrder $ShoppingOrder) {
|
||||
return Payment::getShoppingOrderBadge($ShoppingOrder);
|
||||
})
|
||||
->addColumn('total_shipping', function (ShoppingOrder $ShoppingOrder) {
|
||||
return $ShoppingOrder->getFormattedTotalShipping()." €";
|
||||
})
|
||||
->addColumn('payment', function (ShoppingOrder $ShoppingOrder) {
|
||||
return $ShoppingOrder->getLastShoppingPayment('getPaymentType');
|
||||
})
|
||||
->addColumn('shipped', function (ShoppingOrder $ShoppingOrder) {
|
||||
return '<span class="badge badge-pill badge-'.$ShoppingOrder->getShippedColor().'">'.$ShoppingOrder->getShippedType().'</span>';
|
||||
})
|
||||
->addColumn('payment_for', function (ShoppingOrder $ShoppingOrder) {
|
||||
return Payment::getPaymentForTypeBadge($ShoppingOrder);
|
||||
})
|
||||
->addColumn('reference', function (ShoppingOrder $ShoppingOrder) {
|
||||
return $ShoppingOrder->getLastShoppingPayment('reference');
|
||||
})
|
||||
->orderColumn('id', 'id $1')
|
||||
->orderColumn('txaction', 'txaction $1')
|
||||
->orderColumn('payment_for', 'payment_for $1')
|
||||
->orderColumn('shipped', 'shipped $1')
|
||||
->orderColumn('total_shipping', 'total_shipping $1')
|
||||
->rawColumns(['id', 'txaction', 'payment_for', 'shipped'])
|
||||
->make(true);
|
||||
}
|
||||
|
||||
}
|
||||
|
|
@ -7,18 +7,20 @@ use Yard;
|
|||
use Request;
|
||||
use App\User;
|
||||
use Validator;
|
||||
use App\Services\Shop;
|
||||
use App\Services\Util;
|
||||
use App\Models\Product;
|
||||
use App\Models\UserShop;
|
||||
use App\Services\Payment;
|
||||
use App\Models\ProductBuy;
|
||||
use App\Models\UserHistory;
|
||||
use App\Models\ShoppingUser;
|
||||
use App\Models\ShoppingOrder;
|
||||
use App\Services\UserService;
|
||||
use App\Models\ProductCategory;
|
||||
use App\Models\ShippingCountry;
|
||||
use App\Models\ShoppingInstance;
|
||||
use App\Http\Controllers\Controller;
|
||||
use App\Models\ProductBuy;
|
||||
|
||||
class OrderController extends Controller
|
||||
{
|
||||
|
|
@ -28,88 +30,15 @@ class OrderController extends Controller
|
|||
$this->middleware('active.account');
|
||||
}
|
||||
|
||||
public function index()
|
||||
{
|
||||
|
||||
$data = [
|
||||
];
|
||||
return view('user.order.index', $data);
|
||||
}
|
||||
|
||||
public function detail($id)
|
||||
{
|
||||
$user = User::find(\Auth::user()->id);
|
||||
$shopping_order = ShoppingOrder::findOrFail($id);
|
||||
if($shopping_order->auth_user_id !== $user->id){
|
||||
abort(404);
|
||||
}
|
||||
$shopping_order->getLastShoppingPayment();
|
||||
|
||||
$data = [
|
||||
'shopping_order' => $shopping_order,
|
||||
'isAdmin' => false,
|
||||
];
|
||||
return view('user.order.detail', $data);
|
||||
}
|
||||
|
||||
public function ordersDatatable(){
|
||||
|
||||
$user = User::find(\Auth::user()->id);
|
||||
$query = ShoppingOrder::with('shopping_user', 'shopping_payments')->select('shopping_orders.*')->where('auth_user_id', '=', $user->id)->where('txaction', '!=', NULL);
|
||||
|
||||
return \DataTables::eloquent($query)
|
||||
->addColumn('id', function (ShoppingOrder $ShoppingOrder) {
|
||||
return '<a href="' . route('user_order_detail', [$ShoppingOrder->id]) . '" class="btn icon-btn btn-sm btn-primary"><span class="fa fa-edit"></span></a>';
|
||||
})
|
||||
->addColumn('created_at', function (ShoppingOrder $ShoppingOrder) {
|
||||
return $ShoppingOrder->created_at->format("d.m.Y");
|
||||
})
|
||||
->addColumn('txaction', function (ShoppingOrder $ShoppingOrder) {
|
||||
return Payment::getShoppingOrderBadge($ShoppingOrder);
|
||||
})
|
||||
->addColumn('total_shipping', function (ShoppingOrder $ShoppingOrder) {
|
||||
return $ShoppingOrder->getFormattedTotalShipping()." €";
|
||||
})
|
||||
->addColumn('payment', function (ShoppingOrder $ShoppingOrder) {
|
||||
return $ShoppingOrder->getLastShoppingPayment('getPaymentType');
|
||||
})
|
||||
->addColumn('shipped', function (ShoppingOrder $ShoppingOrder) {
|
||||
return '<span class="badge badge-pill badge-'.$ShoppingOrder->getShippedColor().'">'.$ShoppingOrder->getShippedType().'</span>';
|
||||
})
|
||||
->addColumn('is_for', function (ShoppingOrder $ShoppingOrder) {
|
||||
if($ShoppingOrder->shopping_user->is_for === 'me'){
|
||||
return '<span class="badge badge-pill badge-secondary">Vertriebspartnerbestellung</span>';
|
||||
}
|
||||
if($ShoppingOrder->shopping_user->is_for === 'ot'){
|
||||
return '<span class="badge badge-pill badge-info">Kundenbestellung</span>';
|
||||
}
|
||||
if($ShoppingOrder->shopping_user->is_for === 'hp'){
|
||||
return '<span class="badge badge-pill badge-dark">Homepartybestellung</span>';
|
||||
}
|
||||
return '-';
|
||||
})
|
||||
->addColumn('reference', function (ShoppingOrder $ShoppingOrder) {
|
||||
return $ShoppingOrder->getLastShoppingPayment('reference');
|
||||
})
|
||||
->orderColumn('id', 'id $1')
|
||||
->orderColumn('txaction', 'txaction $1')
|
||||
->orderColumn('shipped', 'shipped $1')
|
||||
->orderColumn('total_shipping', 'total_shipping $1')
|
||||
->rawColumns(['id', 'txaction', 'is_for', 'shipped'])
|
||||
->make(true);
|
||||
}
|
||||
|
||||
|
||||
public function delivery($for, $id=null)
|
||||
{
|
||||
$user = User::find(\Auth::user()->id);
|
||||
|
||||
$shopping_user = null;
|
||||
$delivery_id = null;
|
||||
if($for === 'ot'){
|
||||
$shopping_user = $this->checkShoppingUser($id, $user);
|
||||
if(strpos($for, 'ot') !== false){
|
||||
$shopping_user = Shop::checkShoppingUser($id, $user);
|
||||
$delivery_id = $shopping_user->id;
|
||||
if(!$this->checkShoppingCountry($for, $delivery_id) && !\Session()->has('custom-error')){
|
||||
if(!Shop::checkShoppingCountry($for, $delivery_id) && !\Session()->has('custom-error')){
|
||||
\Session()->flash('custom-error', __('validation.custom.shipping_not_found'));
|
||||
return redirect(route('user_order_my_delivery', [$for, $delivery_id]));
|
||||
}
|
||||
|
|
@ -117,12 +46,11 @@ class OrderController extends Controller
|
|||
|
||||
if(Request::get('action') === 'next'){
|
||||
Yard::instance('shopping')->destroy();
|
||||
if(Request::get('switchers-radio-is-for') === 'ot'){
|
||||
if(strpos(Request::get('switchers-radio-is-for'), 'ot') !== false){
|
||||
$delivery_id = $id;
|
||||
}
|
||||
return redirect(route('user_order_my_list', [Request::get('switchers-radio-is-for'), $delivery_id]));
|
||||
}
|
||||
|
||||
$data = [
|
||||
'shopping_user' => $shopping_user,
|
||||
'isAdmin' => false,
|
||||
|
|
@ -139,20 +67,32 @@ class OrderController extends Controller
|
|||
$user = User::find(\Auth::user()->id);
|
||||
$shopping_user = null;
|
||||
$delivery_id = null;
|
||||
|
||||
if($for === 'ot'){
|
||||
$shopping_user = $this->checkShoppingUser($id, $user);
|
||||
|
||||
if(strpos($for, 'ot') !== false){
|
||||
$shopping_user = Shop::checkShoppingUser($id, $user);
|
||||
$delivery_id = $shopping_user->id;
|
||||
}
|
||||
$shipping_country_id = $this->checkShoppingCountry($for, $id);
|
||||
if(!$shipping_country_id){
|
||||
\Session()->flash('custom-error', __('validation.custom.shipping_not_found'));
|
||||
return redirect(route('user_order_my_delivery', [$for, $delivery_id]));
|
||||
if($for === 'ot-customer'){ //noch nicht implementiert
|
||||
//Liederung an ot-customer (Kunden) Zahlung und Rechnung geht an Kunden
|
||||
UserService::initCustomerYard($shopping_user, $for);
|
||||
}else{
|
||||
//Lieferung an user oder ot-member (Kunden) rechnung geht an User
|
||||
//lieferland und rechnungsland prüfen
|
||||
$shipping_country_id = Shop::checkShoppingCountry($for, $id);
|
||||
if(!$shipping_country_id){
|
||||
\Session()->flash('custom-error', __('validation.custom.shipping_not_found'));
|
||||
return redirect(route('user_order_my_delivery', [$for, $delivery_id]));
|
||||
}
|
||||
UserService::initUserYard($user, $shipping_country_id, $for);
|
||||
}
|
||||
|
||||
Yard::instance('shopping')->setShippingCountryWithPrice($shipping_country_id, $for);
|
||||
Yard::instance('shopping')->setShoppingUser($user, true);
|
||||
if($for === 'cr'){
|
||||
Yard::instance('shopping')->setGlobalTaxRate(0);
|
||||
Yard::instance('shopping')->setShoppingUser($user, false);
|
||||
|
||||
}else{
|
||||
Yard::instance('shopping')->setShoppingUser($user, true);
|
||||
}
|
||||
$data = [
|
||||
'shopping_user' => $shopping_user,
|
||||
'user' => $user,
|
||||
|
|
@ -166,24 +106,29 @@ class OrderController extends Controller
|
|||
}
|
||||
|
||||
public function payment($for, $id=null){
|
||||
|
||||
$data = Request::all();
|
||||
$user = User::find(Auth::user()->id);
|
||||
|
||||
$rules = array(
|
||||
'shipping_salutation' => 'required',
|
||||
'shipping_firstname'=>'required',
|
||||
'shipping_lastname'=>'required',
|
||||
'shipping_address'=>'required',
|
||||
'shipping_zipcode'=>'required',
|
||||
'shipping_firstname' => 'required',
|
||||
'shipping_lastname' => 'required',
|
||||
'shipping_address' => 'required',
|
||||
'shipping_zipcode' => 'required',
|
||||
'shipping_city' => 'required',
|
||||
'shipping_state' => 'required',
|
||||
);
|
||||
|
||||
$validator = Validator::make(Request::all(), $rules);
|
||||
|
||||
if ($validator->fails()) {
|
||||
return back()->withErrors($validator)->withInput(Request::all());
|
||||
}
|
||||
//hier prüfen, ob versand etc richtig berechnet wurde
|
||||
$this->checkSendYardForPayment($data, $id);
|
||||
|
||||
if(Yard::instance('shopping')->getNumComp() > 0){
|
||||
if(Yard::instance('shopping')->getNumComp() > 0){
|
||||
if(!isset($data['switchers-comp-product'])){
|
||||
$validator->errors()->add('switchers-comp-product', __('Bitte wähle ein Kompensationsprodukt aus'));
|
||||
}else{
|
||||
|
|
@ -200,13 +145,17 @@ class OrderController extends Controller
|
|||
}
|
||||
}
|
||||
|
||||
/*do {
|
||||
/*
|
||||
do {
|
||||
$identifier = Util::getToken();
|
||||
} while( ShoppingInstance::where('identifier', $identifier)->count() );*/
|
||||
} while( ShoppingInstance::where('identifier', $identifier)->count() );
|
||||
*/
|
||||
|
||||
$identifier = Util::getToken();
|
||||
$data['is_from'] = 'user_order';
|
||||
$data['is_for'] = $for;
|
||||
$data['shopping_user_id'] = $id;
|
||||
$data['user_price_infos'] = Yard::instance('shopping')->getUserPriceInfos();
|
||||
unset($data['quantity']);
|
||||
unset($data['_token']);
|
||||
|
||||
|
|
@ -221,7 +170,6 @@ class OrderController extends Controller
|
|||
'country_id' => Yard::instance('shopping')->getShippingCountryId(),
|
||||
'shopping_data' => $data,
|
||||
'back' => url()->previous(),
|
||||
|
||||
]);
|
||||
Yard::instance('shopping')->store($identifier);
|
||||
*/
|
||||
|
|
@ -233,57 +181,128 @@ class OrderController extends Controller
|
|||
return redirect(route('user_checkout', [$identifier]));
|
||||
}
|
||||
|
||||
private function checkShoppingCountry($for, $id=null){
|
||||
|
||||
private function checkSendYardForPayment($data, $id){
|
||||
|
||||
$country_id = null;
|
||||
if($for === 'me'){
|
||||
$user = User::find(\Auth::user()->id);
|
||||
if($user->same_as_billing){
|
||||
$country_id = $user->account->country_id;
|
||||
}else{
|
||||
$country_id = $user->account->shipping_country_id;
|
||||
}
|
||||
$user = User::find(\Auth::user()->id);
|
||||
$shopping_user = null;
|
||||
if(strpos($data['shipping_is_for'], 'ot') !== false){
|
||||
$shopping_user = Shop::checkShoppingUser($id, $user);
|
||||
}
|
||||
if($for === 'ot' && $id){
|
||||
$shopping_user = ShoppingUser::findOrFail($id);
|
||||
if($shopping_user->same_as_billing){
|
||||
$country_id = $shopping_user->billing_country_id;
|
||||
}else{
|
||||
$country_id = $shopping_user->shipping_country_id;
|
||||
}
|
||||
|
||||
$shipping_country_id = Shop::checkShoppingCountry($data['shipping_is_for'], $id);
|
||||
if(!$shipping_country_id){
|
||||
$identifier = 'error-'.time().mt_rand(1000000, 9999999);
|
||||
Yard::instance('shopping')->store($identifier);
|
||||
$data['user_id'] = Auth::user()->id;
|
||||
$data['shopping_user_id'] = $id;
|
||||
\App\Services\MyLog::writeLog('payment', 'error', 'no shipping_country_id found | Yard identifier: '.$identifier, $data);
|
||||
abort(403, __('msg.shipping_country_was_not_found'));
|
||||
}
|
||||
//must be the same shipping country
|
||||
if($shipping_country_id != Yard::instance('shopping')->getShippingCountryId()){
|
||||
$identifier = 'error-'.time().mt_rand(1000000, 9999999);
|
||||
Yard::instance('shopping')->store($identifier);
|
||||
$data['user_id'] = Auth::user()->id;
|
||||
$data['shopping_user_id'] = $id;
|
||||
\App\Services\MyLog::writeLog('payment', 'error', 'shipping_country_id is not the same from Yard | Yard identifier: '.$identifier, $data);
|
||||
abort(403, __('msg.shipping_country_was_not_correctly'));
|
||||
}
|
||||
|
||||
if($country_id){
|
||||
if($shipping_country = ShippingCountry::whereCountryId($country_id)->first()){
|
||||
return $shipping_country->id;
|
||||
if($data['shipping_is_for'] !== 'ot-customer'){
|
||||
if(Yard::instance('shopping')->shipping_free){
|
||||
$identifier = 'error-'.time().mt_rand(1000000, 9999999);
|
||||
Yard::instance('shopping')->store($identifier);
|
||||
$data['user_id'] = Auth::user()->id;
|
||||
$data['shopping_user_id'] = $id;
|
||||
\App\Services\MyLog::writeLog('payment', 'error', 'Yard can by not shipping_free | Yard identifier: '.$identifier, $data);
|
||||
abort(403, __('msg.shopping_cart_was_shipping_free'));
|
||||
}
|
||||
}
|
||||
return false;
|
||||
|
||||
if($data['shipping_is_for'] === 'ot-customer'){
|
||||
if(!$user->shop){
|
||||
$identifier = 'error-'.time().mt_rand(1000000, 9999999);
|
||||
Yard::instance('shopping')->store($identifier);
|
||||
$data['user_id'] = Auth::user()->id;
|
||||
$data['shopping_user_id'] = $id;
|
||||
\App\Services\MyLog::writeLog('payment', 'error', 'User has no Shop for an User to Customer order| Yard identifier: '.$identifier, $data);
|
||||
abort(403, __('msg.shopping_cart_was_not_user_shop'));
|
||||
}
|
||||
}
|
||||
|
||||
$shipping_price = Shop::getShippingPriceByShippingCountryId($shipping_country_id, Yard::instance('shopping')->weight());
|
||||
//for other and has weight - check
|
||||
if(strpos($data['shipping_is_for'], 'ot') !== false && $data['shipping_is_for'] !== 'ot-customer' && Yard::instance('shopping')->weight() > 0){
|
||||
if(!Yard::instance('shopping')->getShippingPrice() || Yard::instance('shopping')->getShippingPrice() == 0){
|
||||
$identifier = 'error-'.time().mt_rand(1000000, 9999999);
|
||||
Yard::instance('shopping')->store($identifier);
|
||||
$data['user_id'] = Auth::user()->id;
|
||||
$data['shopping_user_id'] = $id;
|
||||
\App\Services\MyLog::writeLog('payment', 'error', 'Yard OT shipping_price is 0 or | Yard identifier: '.$identifier, $data);
|
||||
abort(403, __('msg.shipping_cost_cannot_be_0'));
|
||||
}
|
||||
if(Yard::instance('shopping')->getShippingPrice() != $shipping_price->price){
|
||||
$identifier = 'error-'.time().mt_rand(1000000, 9999999);
|
||||
Yard::instance('shopping')->store($identifier);
|
||||
$data['user_id'] = Auth::user()->id;
|
||||
$data['shopping_user_id'] = $id;
|
||||
\App\Services\MyLog::writeLog('payment', 'error', 'Yard OT shipping_price is not the same from shipping_price | Yard identifier: '.$identifier, $data);
|
||||
abort(403, __('msg.shipping_costs_were_not_calculated_correctly'));
|
||||
}
|
||||
}
|
||||
|
||||
if($data['shipping_is_for'] == 'me' && Yard::instance('shopping')->weight() > 0){
|
||||
if(!Yard::instance('shopping')->getShippingPrice() || Yard::instance('shopping')->getShippingPrice() == 0){
|
||||
$identifier = 'error-'.time().mt_rand(1000000, 9999999);
|
||||
Yard::instance('shopping')->store($identifier);
|
||||
$data['user_id'] = Auth::user()->id;
|
||||
$data['shopping_user_id'] = $id;
|
||||
\App\Services\MyLog::writeLog('payment', 'error', 'Yard ME shipping_price is 0 or | Yard identifier: '.$identifier, $data);
|
||||
abort(403, __('msg.shipping_cost_cannot_be_0'));
|
||||
}
|
||||
if(Yard::instance('shopping')->getShippingPrice() != $shipping_price->price_comp){
|
||||
$identifier = 'error-'.time().mt_rand(1000000, 9999999);
|
||||
Yard::instance('shopping')->store($identifier);
|
||||
$data['user_id'] = Auth::user()->id;
|
||||
$data['shopping_user_id'] = $id;
|
||||
\App\Services\MyLog::writeLog('payment', 'error', 'Yard ME shipping_price is not the same from shipping_price | Yard identifier: '.$identifier, $data);
|
||||
abort(403, __('msg.shipping_costs_were_not_calculated_correctly'));
|
||||
}
|
||||
|
||||
if(Yard::instance('shopping')->getNumComp() != $shipping_price->num_comp){
|
||||
$identifier = 'error-'.time().mt_rand(1000000, 9999999);
|
||||
Yard::instance('shopping')->store($identifier);
|
||||
$data['user_id'] = Auth::user()->id;
|
||||
$data['shopping_user_id'] = $id;
|
||||
\App\Services\MyLog::writeLog('payment', 'error', 'Yard num_comp is 0 | Yard identifier: '.$identifier, $data);
|
||||
abort(403, __('msg.compensation_products_cannot_be_0'));
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
private function checkShoppingUser($id, $user){
|
||||
if($id === null){
|
||||
abort(403, 'Error: Keine User ID');
|
||||
}
|
||||
$shopping_user = ShoppingUser::findOrFail($id);
|
||||
if($shopping_user->member_id !== $user->id){
|
||||
abort(403, 'Error: Falsche User ID');
|
||||
}
|
||||
$shopping_user = ShoppingUser::findOrFail($id);
|
||||
if($shopping_user->is_like){
|
||||
abort(403, 'Error: Kunde in Prüfung');
|
||||
}
|
||||
return $shopping_user;
|
||||
}
|
||||
|
||||
public function datatable(){
|
||||
|
||||
$not_show_pids = ProductBuy::getNotShowProductIDs(Auth::user()->id);
|
||||
if(Request::get('shipping_is_for') === 'me'){
|
||||
$query = Product::select('products.*')->where('active', true)->whereJsonContains('show_on', '2');
|
||||
}else{
|
||||
$query = Product::select('products.*')->where('active', true)->whereJsonContains('show_on', '1');
|
||||
|
||||
switch (Request::get('shipping_is_for')) {
|
||||
case 'me':
|
||||
$query = Product::select('products.*')->where('active', true)->whereJsonContains('show_on', '2');
|
||||
break;
|
||||
case 'mp':
|
||||
$query = Product::select('products.*')->where('active', true)->whereJsonContains('show_on', '2');
|
||||
break;
|
||||
case 'cr':
|
||||
$query = Product::select('products.*')->where('active', true)->whereJsonContains('show_on', '6');
|
||||
break;
|
||||
case 'ot':
|
||||
$query = Product::select('products.*')->where('active', true)->whereJsonContains('show_on', '1');
|
||||
break;
|
||||
}
|
||||
|
||||
|
||||
foreach($not_show_pids as $not_show_pid){
|
||||
$query->where('id', '!=', $not_show_pid);
|
||||
|
|
@ -292,7 +311,6 @@ class OrderController extends Controller
|
|||
return \DataTables::eloquent($query)
|
||||
|
||||
->addColumn('product', function (Product $product) {
|
||||
|
||||
$cartItem = Yard::instance('shopping')->getCartItemByProduct($product->id);
|
||||
$qty = isset($cartItem->qty) ? $cartItem->qty : 0;
|
||||
$rowId = isset($cartItem->rowId) ? $cartItem->rowId : '';
|
||||
|
|
@ -309,7 +327,6 @@ class OrderController extends Controller
|
|||
</div>';
|
||||
})
|
||||
/*
|
||||
|
||||
->addColumn('add_card', function (Product $product) {
|
||||
return '<button type="button" class="btn btn-sm btn-md-extra btn-secondary add-product-basket" data-product-id="'.$product->id.'">
|
||||
<strong>€ '.$product->getFormattedPriceWith().'</strong> +<span class="ion ion-md-cart"></span>
|
||||
|
|
@ -418,7 +435,11 @@ class OrderController extends Controller
|
|||
}
|
||||
|
||||
//get the card item
|
||||
$cartItem = Yard::instance('shopping')->add($product->id, $product->getLang('name'), 1, $product->getPriceWith(false, true), $product->tax,
|
||||
|
||||
//Yard::instance('shopping')->add($product->id, $product->getLang('name'), 1, $product->price, $product->tax, ['image' => $image, 'slug' => $product->slug, 'weight' => $product->weight]);
|
||||
|
||||
$cartItem = Yard::instance('shopping')->add($product->id, $product->getLang('name'), 1, $product->price, $product->tax,
|
||||
//$product->getPriceWith(Yard::instance('shopping')->getUserTaxFree(), true, Yard::instance('shopping')->getUserCountry()), $product->getTaxWith(Yard::instance('shopping')->getUserCountry()), //$product->tax, true?
|
||||
[
|
||||
'image' => $image,
|
||||
'slug' => $product->slug,
|
||||
|
|
@ -428,7 +449,14 @@ class OrderController extends Controller
|
|||
'value_commission' => $product->value_commission,
|
||||
'partner_commission' => $product->partner_commission,
|
||||
]);
|
||||
Yard::setTax($cartItem->rowId, $product->tax);
|
||||
|
||||
if(Yard::instance('shopping')->getUserTaxFree()){
|
||||
//Yard::setTax($cartItem->rowId, 0);
|
||||
Yard::instance('shopping')->setGlobalTaxRate(0);
|
||||
}else{
|
||||
//Yard::setTax($cartItem->rowId, $product->getTaxWith(Yard::instance('shopping')->getUserCountry()));
|
||||
}
|
||||
|
||||
|
||||
if(isset($data['qty']) && $data['qty'] > 0){
|
||||
Yard::instance('shopping')->update($cartItem->rowId, $data['qty']);
|
||||
|
|
@ -446,6 +474,16 @@ class OrderController extends Controller
|
|||
return response()->json(['response' => true, 'data'=>$data, 'html_card'=>$html_card, 'html_comp'=>$html_comp]);
|
||||
}
|
||||
}
|
||||
if($data['action'] === 'reCalculateCart') {
|
||||
//set use_payment_credit
|
||||
$data['reduce_payment_credit'] = $data['reduce_payment_credit'] == 'true' ? true: false;
|
||||
Yard::instance('shopping')->setReducePaymentCredit($data['reduce_payment_credit']);
|
||||
Yard::instance('shopping')->reCalculate();
|
||||
$html_card = view("user.order.yard_view_form", $data)->render();
|
||||
$html_comp = view("user.order.comp_product", $data)->render();
|
||||
return response()->json(['response' => true, 'data'=>$data, 'html_card'=>$html_card, 'html_comp'=>$html_comp]);
|
||||
}
|
||||
|
||||
if($data['action'] === 'clearCart') {
|
||||
Yard::instance('shopping')->destroy();
|
||||
return response()->json(['response' => true, 'data'=>Yard::instance('shopping')->count(), 'html_card'=>'', 'html_comp'=>'']);
|
||||
|
|
@ -454,7 +492,7 @@ class OrderController extends Controller
|
|||
if($data['action'] === 'updateShippingCountry') {
|
||||
if(isset($data['shipping_country_id'])){
|
||||
if($shipping_country = ShippingCountry::find($data['shipping_country_id'])){
|
||||
Yard::instance('shopping')->setShippingCountryWithPrice($shipping_country->id, $is_for);
|
||||
Yard::instance('shopping')->setShippingCountryWithPrice($shipping_country->id, $is_for); //$is_for == 'ot' or 'me'
|
||||
$this->checkCompProduct(Yard::instance('shopping')->getNumComp());
|
||||
}
|
||||
}
|
||||
|
|
@ -498,37 +536,52 @@ class OrderController extends Controller
|
|||
}
|
||||
}
|
||||
|
||||
if(isset($data['comp_product_id'])) {
|
||||
if ($product = Product::find($data['comp_product_id'])) {
|
||||
$image = "";
|
||||
if ($product->images->count()) {
|
||||
$image = $product->images->first()->slug;
|
||||
}
|
||||
$cartItem = Yard::instance('shopping')->add($product->id, $product->getLang('name'), 1, 0, 0,
|
||||
[
|
||||
'image' => $image,
|
||||
'slug' => $product->slug,
|
||||
'weight' => 0,
|
||||
'single_commission' => 0,
|
||||
'amount_commission' => 0,
|
||||
'value_commission' => 0,
|
||||
'partner_commission' => 0,
|
||||
'comp' => $data['comp_num'],
|
||||
'product_id' => $product->id
|
||||
]);
|
||||
Yard::setTax($cartItem->rowId, 0);
|
||||
if(isset($data['comp_product_id'])) {
|
||||
if ($product = Product::find($data['comp_product_id'])) {
|
||||
$image = "";
|
||||
if ($product->images->count()) {
|
||||
$image = $product->images->first()->slug;
|
||||
}
|
||||
$cartItem = Yard::instance('shopping')->add($product->id, $product->getLang('name'), 1, 0, 0,
|
||||
[
|
||||
'image' => $image,
|
||||
'slug' => $product->slug,
|
||||
'weight' => 0,
|
||||
'single_commission' => 0,
|
||||
'amount_commission' => 0,
|
||||
'value_commission' => 0,
|
||||
'partner_commission' => 0,
|
||||
'comp' => $data['comp_num'],
|
||||
'product_id' => $product->id
|
||||
]);
|
||||
Yard::setTax($cartItem->rowId, 0);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private function getCompProducts($for){
|
||||
|
||||
if($for === 'me' && \App\Models\Setting::getContentBySlug('order_partner_is_comp_me')){
|
||||
return Product::whereActive(true)->whereJsonContains('show_on', ['2'])->where('shipping_addon', true)->orderBy('pos', 'DESC')->get();
|
||||
private function getCompProducts($for) {
|
||||
if($for === 'me' && \App\Models\Setting::getContentBySlug('order_partner_is_comp_me')) {
|
||||
return Product::whereActive(true)
|
||||
->where(function($query) {
|
||||
$query->whereRaw("JSON_CONTAINS(show_on, '\"2\"')")
|
||||
->orWhereRaw("JSON_CONTAINS(show_on, '\"11\"')");
|
||||
})
|
||||
->where('shipping_addon', true)
|
||||
->orderBy('pos', 'DESC')
|
||||
->get();
|
||||
}
|
||||
if($for === 'ot' && \App\Models\Setting::getContentBySlug('order_partner_is_comp_ot')){
|
||||
return Product::whereActive(true)->whereJsonContains('show_on', ['1'])->where('shipping_addon', true)->orderBy('pos', 'DESC')->get();
|
||||
|
||||
if($for === 'ot' && \App\Models\Setting::getContentBySlug('order_partner_is_comp_ot')) {
|
||||
return Product::whereActive(true)
|
||||
->where(function($query) {
|
||||
$query->whereRaw("JSON_CONTAINS(show_on, '\"1\"')")
|
||||
->orWhereRaw("JSON_CONTAINS(show_on, '\"11\"')");
|
||||
})
|
||||
->where('shipping_addon', true)
|
||||
->orderBy('pos', 'DESC')
|
||||
->get();
|
||||
}
|
||||
|
||||
return null;
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -45,10 +45,12 @@ class PaymentController extends Controller
|
|||
->addColumn('message', function (UserPayCredit $user_pay_credit) {
|
||||
if($user_pay_credit->status === 3){
|
||||
return nl2br($user_pay_credit->message);
|
||||
}elseif($user_pay_credit->status === 5 || $user_pay_credit->status === 6){
|
||||
return trans('payment.'.$user_pay_credit->message).
|
||||
' <a class="btn btn-outline-secondary btn-xs" href="'.route('user_sales_detail', [$user_pay_credit->shopping_order_id]).'"><i class="ion ion-md-eye"></i></a>';
|
||||
}else{
|
||||
return trans('payment.'.$user_pay_credit->message).
|
||||
' <a class="btn btn-outline-secondary btn-xs" href="'.route('user_order_detail', [$user_pay_credit->shopping_order_id]).'"><i class="ion ion-md-eye"></i></a>';
|
||||
|
||||
' <a class="btn btn-outline-secondary btn-xs" href="'.route('user_myorder_detail', [$user_pay_credit->shopping_order_id]).'"><i class="ion ion-md-eye"></i></a>';
|
||||
}
|
||||
})
|
||||
->addColumn('credit', function (UserPayCredit $user_pay_credit) {
|
||||
|
|
|
|||
|
|
@ -3,15 +3,14 @@
|
|||
namespace App\Http\Controllers\User;
|
||||
|
||||
use Request;
|
||||
use Validator;
|
||||
use App\Models\PromotionUser;
|
||||
use App\Models\PromotionAdmin;
|
||||
use App\Http\Controllers\Controller;
|
||||
use Response;
|
||||
use Illuminate\Support\Facades\Auth;
|
||||
use App\Models\PromotionAdminProduct;
|
||||
use App\Repositories\UserPromotionRepository;
|
||||
use Validator;
|
||||
use App\Services\Util;
|
||||
use App\Models\PromotionUser;
|
||||
use App\Services\UserService;
|
||||
use App\Http\Controllers\Controller;
|
||||
use Illuminate\Support\Facades\Auth;
|
||||
use App\Repositories\UserPromotionRepository;
|
||||
|
||||
class PromotionController extends Controller
|
||||
{
|
||||
|
|
@ -38,7 +37,10 @@ class PromotionController extends Controller
|
|||
if($user_promotion->user_id != Auth::user()->id){
|
||||
abort(404);
|
||||
}
|
||||
$user_promotion->about_you = !$user_promotion->about_you ? $user_promotion->user->account->about_you : $user_promotion->about_you;
|
||||
|
||||
$user_promotion->description = $user_promotion->description ? $user_promotion->description : $user_promotion->promotion_admin->user_description;
|
||||
$about_you = $user_promotion->user->account->about_you ?$user_promotion->user->account->about_you : $user_promotion->promotion_admin->user_about;
|
||||
$user_promotion->about_you = $user_promotion->about_you ? $user_promotion->about_you : $about_you;
|
||||
$data = [
|
||||
'checkPaymentCredit' => $user_promotion->checkPaymentCredit(),
|
||||
'user_promotion_cart' => PromotionUser::preCalculateCart($user_promotion, 'user_promotion'),
|
||||
|
|
@ -59,14 +61,21 @@ class PromotionController extends Controller
|
|||
if(isset($data['action']) && $data['action'] === 'save-user-promotion'){
|
||||
$rules = array(
|
||||
'name' => 'required',
|
||||
'user_promotion_url' => ' required|alpha_dash|profanity|unique:promotion_users,url,'.\Auth::user()->id.',user_id|min:4|max:20',
|
||||
'user_promotion_url' => ' required|alpha_dash|'.'unique:promotion_users,url,'.$id.',id'.'|min:4|max:20|full_word_check',
|
||||
);
|
||||
Validator::extend('full_word_check', function ($attribute, $value, $parameters, $validator) {
|
||||
$profanity = \App\Models\Setting::getContentBySlug('promotion_user_url_profanity');
|
||||
$profanity = array_map('trim', explode(',', $profanity));
|
||||
if(in_array($value, $profanity)){
|
||||
return false;
|
||||
}
|
||||
return true;
|
||||
});
|
||||
$validator = Validator::make(Request::all(), $rules);
|
||||
if ($validator->fails()) {
|
||||
return redirect(route('user_promotion_detail', [$id]))->withErrors($validator)->withInput(Request::all());
|
||||
}
|
||||
$model = $this->promoRepo->update($id, Request::all());
|
||||
|
||||
}
|
||||
\Session()->flash('alert-save', true);
|
||||
return redirect(route('user_promotion_detail', [$model->id]));
|
||||
|
|
@ -91,19 +100,23 @@ class PromotionController extends Controller
|
|||
|
||||
public function load(){
|
||||
$data = Request::all();
|
||||
|
||||
if(Request::ajax()) {
|
||||
if(isset($data['action']) && $data['action'] === 'validate_url'){
|
||||
$unique = 'unique:promotion_users,url';
|
||||
if(isset($data['puid'])){
|
||||
$unique .= ','.$data['puid'].',id';
|
||||
}
|
||||
$rules = array(
|
||||
//'user_promotion_url' => ' required|alpha_dash|profanity|unique:user_shops,name|min:4|max:20|full_word_check',
|
||||
'user_promotion_url' => ' required|alpha_dash|profanity|unique:promotion_users,url,'.\Auth::user()->id.',user_id|min:4|max:20',
|
||||
'user_promotion_url' => ' required|alpha_dash|'.$unique.'|min:4|max:20|full_word_check',
|
||||
);
|
||||
/*Validator::extend('full_word_check', function ($attribute, $value, $parameters, $validator) {
|
||||
if(in_array($value, config('profanity.full_word_check'))){
|
||||
Validator::extend('full_word_check', function ($attribute, $value, $parameters, $validator) {
|
||||
$profanity = \App\Models\Setting::getContentBySlug('promotion_user_url_profanity');
|
||||
$profanity = array_map('trim', explode(',', $profanity));
|
||||
if(in_array($value, $profanity)){
|
||||
return false;
|
||||
}
|
||||
return true;
|
||||
});*/
|
||||
});
|
||||
$validator = Validator::make(Request::all(), $rules);
|
||||
|
||||
if ($validator->fails()) {
|
||||
|
|
|
|||
|
|
@ -1,53 +0,0 @@
|
|||
<?php
|
||||
|
||||
|
||||
namespace App\Http\Controllers\User;
|
||||
use App\Http\Controllers\Controller;
|
||||
use App\User;
|
||||
use Request;
|
||||
use Carbon;
|
||||
use App\Models\ShoppingOrder;
|
||||
|
||||
|
||||
class RevenueController extends Controller
|
||||
{
|
||||
|
||||
public function __construct()
|
||||
{
|
||||
$this->middleware('auth');
|
||||
}
|
||||
|
||||
public function index()
|
||||
{
|
||||
$start = 2021;
|
||||
$end = date('Y');
|
||||
$years = range($start, $end);
|
||||
|
||||
if(Request::get('filter_sales_year')){
|
||||
$active_year = Request::get('filter_sales_year');
|
||||
}else{
|
||||
$active_year = $end;
|
||||
}
|
||||
|
||||
$date1 = Carbon::parse('01.01.'.$active_year." 00:00:00")->format('Y-m-d H:i:s');
|
||||
$date2 = Carbon::parse('31.12.'.$active_year." 23:59:59")->toDateString();
|
||||
|
||||
|
||||
$values = ShoppingOrder::where('shopping_orders.auth_user_id', '!=', NULL) //::with('shopping_user', )->select('shopping_orders.*')
|
||||
->where('mode', '=', 'live')
|
||||
->where('paid', '=', 1)
|
||||
->whereHas('shopping_order_items', function($q) {
|
||||
|
||||
$q->where('product_id', 34)->OrWhere('product_id', 35)->OrWhere('product_id', 36)->OrWhere('product_id', 67)->OrWhere('product_id', 69);
|
||||
})
|
||||
->whereBetween('created_at', [$date1, $date2])
|
||||
->get();
|
||||
|
||||
$data = [
|
||||
'years' => $years,
|
||||
'active_year' => $active_year,
|
||||
'values' => $values,
|
||||
];
|
||||
return view('user.revenue.index', $data);
|
||||
}
|
||||
}
|
||||
92
app/Http/Controllers/User/SalesController.php
Executable file
92
app/Http/Controllers/User/SalesController.php
Executable file
|
|
@ -0,0 +1,92 @@
|
|||
<?php
|
||||
|
||||
namespace App\Http\Controllers\User;
|
||||
|
||||
use App\Http\Controllers\Controller;
|
||||
use App\Models\ShoppingOrder;
|
||||
use App\Services\Payment;
|
||||
use App\User;
|
||||
|
||||
class SalesController extends Controller
|
||||
{
|
||||
protected $userShopRepo;
|
||||
|
||||
public function __construct()
|
||||
{
|
||||
$this->middleware('active.account');
|
||||
}
|
||||
|
||||
|
||||
public function index()
|
||||
{
|
||||
$data = [
|
||||
];
|
||||
return view('user.sales.index', $data);
|
||||
}
|
||||
|
||||
public function detail($id)
|
||||
{
|
||||
$user = User::find(\Auth::user()->id);
|
||||
$shopping_order = ShoppingOrder::findOrFail($id);
|
||||
if($shopping_order->member_id !== $user->id){
|
||||
abort(404);
|
||||
}
|
||||
if($shopping_order->payment_for !== 6 && $shopping_order->payment_for !== 7 && $shopping_order->payment_for !== 8){
|
||||
return redirect(route('user_myorder_detail', [$shopping_order->id]));
|
||||
abort(403, 'Beraterbestellung');
|
||||
}
|
||||
$data = [
|
||||
'shopping_order' => $shopping_order,
|
||||
'isAdmin' => false,
|
||||
];
|
||||
|
||||
return view('user.sales.detail', $data);
|
||||
}
|
||||
|
||||
public function datatable(){
|
||||
|
||||
$user = User::find(\Auth::user()->id);
|
||||
$query = ShoppingOrder::with('shopping_user')->select('shopping_orders.*')->where('shopping_orders.member_id', $user->id);
|
||||
|
||||
return \DataTables::eloquent($query)
|
||||
->addColumn('id', function (ShoppingOrder $ShoppingOrder) {
|
||||
return '<a href="' . route('user_sales_detail', [$ShoppingOrder->id]) . '" class="btn icon-btn btn-sm btn-primary"><span class="fa fa-edit"></span></a>';
|
||||
})
|
||||
->addColumn('created_at', function (ShoppingOrder $ShoppingOrder) {
|
||||
return $ShoppingOrder->created_at->format("d.m.Y");
|
||||
})
|
||||
->addColumn('txaction', function (ShoppingOrder $ShoppingOrder) {
|
||||
return Payment::getShoppingOrderBadge($ShoppingOrder);
|
||||
})
|
||||
->addColumn('total_shipping', function (ShoppingOrder $ShoppingOrder) {
|
||||
return '<span class="no-line-break">'.$ShoppingOrder->getFormattedTotalShipping()." €</span>";
|
||||
})
|
||||
->addColumn('orders', function (ShoppingOrder $ShoppingOrder) {
|
||||
return $ShoppingOrder->shopping_user ? $ShoppingOrder->shopping_user->orders : '';
|
||||
})
|
||||
->addColumn('user_shop_id', function (ShoppingOrder $ShoppingOrder) {
|
||||
return $ShoppingOrder->user_shop ? '<a href="'.$ShoppingOrder->user_shop->getSubdomain(false).'" target="_blank">'.$ShoppingOrder->user_shop->getSubdomain(false).'</span>' : '';
|
||||
})
|
||||
->addColumn('payment_for', function (ShoppingOrder $ShoppingOrder) {
|
||||
return Payment::getPaymentForTypeBadge($ShoppingOrder);
|
||||
})
|
||||
->addColumn('shipped', function (ShoppingOrder $ShoppingOrder) {
|
||||
return '<span class="badge badge-pill badge-'.$ShoppingOrder->getShippedColor().'">'.$ShoppingOrder->getShippedType().'</span>
|
||||
';
|
||||
})
|
||||
->addColumn('invoice', function (ShoppingOrder $ShoppingOrder) {
|
||||
return $ShoppingOrder->isInvoice() ? '<span class="no-line-break"><a href="'.route('storage_file', [$ShoppingOrder->id, 'invoice', 'download']).'" class="btn btn-primary btn-xs"><i class="fa fa-download"></i></a>
|
||||
<a href="'.route('storage_file', [$ShoppingOrder->id, 'invoice', 'stream']).'" target="_blank" class="btn btn-warning btn-xs"><i class="fa fa-eye"></i></a></span>' : '-';
|
||||
})
|
||||
->orderColumn('payment_for', 'payment_for $1')
|
||||
->orderColumn('id', 'id $1')
|
||||
->orderColumn('txaction', 'txaction $1')
|
||||
->orderColumn('user_shop_id', 'user_shop_id $1')
|
||||
->orderColumn('total_shipping', 'total_shipping $1')
|
||||
|
||||
->rawColumns(['id', 'txaction', 'user_shop_id', 'total_shipping', 'invoice', 'shipped', 'payment_for'])
|
||||
->make(true);
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
119
app/Http/Controllers/User/ShopController.php
Normal file
119
app/Http/Controllers/User/ShopController.php
Normal file
|
|
@ -0,0 +1,119 @@
|
|||
<?php
|
||||
|
||||
namespace App\Http\Controllers\User;
|
||||
|
||||
use Request;
|
||||
use App\User;
|
||||
use Response;
|
||||
use Validator;
|
||||
use App\Services\Util;
|
||||
use App\Models\UserShop;
|
||||
use App\Models\PromotionUser;
|
||||
use App\Services\UserService;
|
||||
use App\Http\Controllers\Controller;
|
||||
use Illuminate\Support\Facades\Auth;
|
||||
use App\Repositories\UserShopRepository;
|
||||
|
||||
class ShopController extends Controller
|
||||
{
|
||||
protected $userShopRepo;
|
||||
|
||||
public function __construct(UserShopRepository $userShopRepo)
|
||||
{
|
||||
$this->middleware('active.account');
|
||||
$this->userShopRepo = $userShopRepo;
|
||||
}
|
||||
|
||||
public function index(){
|
||||
|
||||
$user = Auth::user();
|
||||
|
||||
// $user_shop = UserShop::where('user_id', Auth::user()->id)->first();
|
||||
if(!$user->shop){
|
||||
//create new shop
|
||||
$user = $this->createNewUserShop(Auth::user());
|
||||
}
|
||||
if($user->shop->user_id != Auth::user()->id){
|
||||
abort(404);
|
||||
}
|
||||
$data = [
|
||||
'user_shop' => $user->shop,
|
||||
];
|
||||
|
||||
return view('user.shop.detail', $data);
|
||||
}
|
||||
private function createNewUserShop($user){
|
||||
return $this->userShopRepo->create($user);
|
||||
}
|
||||
|
||||
public function store()
|
||||
{
|
||||
$data = Request::all();
|
||||
$user = Auth::user();
|
||||
|
||||
if(isset($data['action']) && $data['action'] === 'save-user-shop'){
|
||||
$rules = array(
|
||||
'name' => 'required',
|
||||
'user_shop_url' => ' required|alpha_dash|'.'unique:user_shops,url,'.$user->shop->id.',id'.'|min:4|max:20|full_word_check',
|
||||
);
|
||||
Validator::extend('full_word_check', function ($attribute, $value, $parameters, $validator) {
|
||||
$profanity = \App\Models\Setting::getContentBySlug('promotion_user_url_profanity');
|
||||
$profanity = array_map('trim', explode(',', $profanity));
|
||||
if(in_array($value, $profanity)){
|
||||
return false;
|
||||
}
|
||||
return true;
|
||||
});
|
||||
$validator = Validator::make(Request::all(), $rules);
|
||||
if ($validator->fails()) {
|
||||
return redirect(route('user_shop'))->withErrors($validator)->withInput(Request::all());
|
||||
}
|
||||
$model = $this->userShopRepo->update($user->shop->id, Request::all());
|
||||
}
|
||||
\Session()->flash('alert-save', true);
|
||||
return redirect(route('user_shop'));
|
||||
}
|
||||
|
||||
public function load(){
|
||||
$data = Request::all();
|
||||
|
||||
if(Request::ajax()) {
|
||||
if(isset($data['action']) && $data['action'] === 'validate_url'){
|
||||
$unique = 'unique:user_shops,url';
|
||||
if(isset($data['usid'])){
|
||||
$unique .= ','.$data['usid'].',id';
|
||||
}
|
||||
$rules = array(
|
||||
'user_shop_url' => ' required|alpha_dash|'.$unique.'|min:4|max:20|full_word_check',
|
||||
);
|
||||
Validator::extend('full_word_check', function ($attribute, $value, $parameters, $validator) {
|
||||
$profanity = \App\Models\Setting::getContentBySlug('promotion_user_url_profanity');
|
||||
$profanity = array_map('trim', explode(',', $profanity));
|
||||
if(in_array($value, $profanity)){
|
||||
return false;
|
||||
}
|
||||
return true;
|
||||
});
|
||||
$validator = Validator::make(Request::all(), $rules);
|
||||
|
||||
if ($validator->fails()) {
|
||||
//$messages = $validator->messages();
|
||||
return Response::json(array(
|
||||
'success' => false,
|
||||
'errors' => $validator->getMessageBag()->toArray()
|
||||
|
||||
));
|
||||
}
|
||||
//$slug = SlugService::createSlug(UserShop::class, 'slug', Request::get('user_promotion_url'));
|
||||
$name = Util::sanitize(Request::get('user_shop_url'), true, false, true, true);
|
||||
|
||||
return Response::json(array(
|
||||
'success' => true,
|
||||
'preview_user_shop_url' => config('app.shop_url')."/".$name,
|
||||
));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
|
|
@ -1,74 +0,0 @@
|
|||
<?php
|
||||
|
||||
|
||||
namespace App\Http\Controllers\User;
|
||||
use App\Http\Controllers\Controller;
|
||||
use App\Models\ShoppingOrder;
|
||||
use App\Services\Payment;
|
||||
use App\User;
|
||||
|
||||
|
||||
class ShopSalesController extends Controller
|
||||
{
|
||||
|
||||
public function __construct()
|
||||
{
|
||||
$this->middleware('active.shop');
|
||||
}
|
||||
|
||||
public function orders()
|
||||
{
|
||||
$data = [
|
||||
];
|
||||
return view('user.shop.sales.orders', $data);
|
||||
}
|
||||
|
||||
public function orderDetail($id)
|
||||
{
|
||||
$user = User::find(\Auth::user()->id);
|
||||
$shopping_order = ShoppingOrder::findOrFail($id);
|
||||
if($shopping_order->member_id !== $user->id){
|
||||
abort(404);
|
||||
}
|
||||
$data = [
|
||||
'shopping_order' => $shopping_order,
|
||||
'isAdmin' => false,
|
||||
];
|
||||
return view('user.shop.sales.order_detail', $data);
|
||||
}
|
||||
|
||||
public function ordersDatatable(){
|
||||
|
||||
$user = User::find(\Auth::user()->id);
|
||||
$query = ShoppingOrder::with('shopping_user')->select('shopping_orders.*')->where('member_id', $user->id);
|
||||
|
||||
return \DataTables::eloquent($query)
|
||||
->addColumn('id', function (ShoppingOrder $ShoppingOrder) {
|
||||
return '<a href="' . route('user_shop_order_detail', [$ShoppingOrder->id]) . '" class="btn icon-btn btn-sm btn-primary"><span class="fa fa-edit"></span></a>';
|
||||
})
|
||||
->addColumn('created_at', function (ShoppingOrder $ShoppingOrder) {
|
||||
return $ShoppingOrder->created_at->format("d.m.Y");
|
||||
})
|
||||
->addColumn('txaction', function (ShoppingOrder $ShoppingOrder) {
|
||||
return Payment::getShoppingOrderBadge($ShoppingOrder);
|
||||
})
|
||||
->addColumn('total_shipping', function (ShoppingOrder $ShoppingOrder) {
|
||||
return $ShoppingOrder->getFormattedTotalShipping();
|
||||
})
|
||||
->addColumn('orders', function (ShoppingOrder $ShoppingOrder) {
|
||||
return $ShoppingOrder->shopping_user ? $ShoppingOrder->shopping_user->orders : '';
|
||||
})
|
||||
->addColumn('user_shop_id', function (ShoppingOrder $ShoppingOrder) {
|
||||
return $ShoppingOrder->user_shop ? '<a href="'.$ShoppingOrder->user_shop->getSubdomain(false).'" target="_blank">'.$ShoppingOrder->user_shop->getSubdomain(false).'</span>' : '';
|
||||
})
|
||||
|
||||
->orderColumn('id', 'id $1')
|
||||
->orderColumn('txaction', 'txaction $1')
|
||||
->orderColumn('user_shop_id', 'user_shop_id $1')
|
||||
->rawColumns(['id', 'txaction', 'user_shop_id'])
|
||||
->make(true);
|
||||
}
|
||||
|
||||
|
||||
|
||||
}
|
||||
|
|
@ -39,6 +39,15 @@ class UserDataController extends Controller
|
|||
/*if(!$user->account){
|
||||
$user->account = new UserAccount();
|
||||
}*/
|
||||
$data = Request::all();
|
||||
if(isset($data['action']) && $data['action'] == "reverse_charge_validate"){
|
||||
return $this->userRepo->reverse_charge_validate($data, $user, route('user_edit', [$user->id]));
|
||||
}
|
||||
|
||||
if(isset($data['action']) && $data['action'] == "reverse_charge_delete"){
|
||||
return $this->userRepo->reverse_charge_delete($data, $user, route('user_edit', [$user->id]));
|
||||
}
|
||||
|
||||
$rules = array(
|
||||
'salutation' => 'required',
|
||||
'first_name'=>'required',
|
||||
|
|
@ -50,9 +59,6 @@ class UserDataController extends Controller
|
|||
'mobil' => 'required_without:phone',
|
||||
'tax_number' => 'required_without:tax_identification_number',
|
||||
'tax_identification_number' => 'required_without:tax_number',
|
||||
'birthday_day' => 'required',
|
||||
'birthday_month' => 'required',
|
||||
'birthday_year' => 'required',
|
||||
'country_id' => 'required|integer|min:1',
|
||||
'email' => 'required|string|email|max:255|exists:users,email',
|
||||
'email-confirm' => 'required|same:email',
|
||||
|
|
@ -79,7 +85,7 @@ class UserDataController extends Controller
|
|||
} else {
|
||||
$this->userRepo->update(Request::all());
|
||||
\Session()->flash('alert-save', true);
|
||||
return redirect('/user/edit');
|
||||
return redirect(route('user_edit', [$user->id]));
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -24,7 +24,7 @@ class UserLevelController extends Controller
|
|||
{
|
||||
|
||||
$data = [
|
||||
'values' => UserLevel::all(),
|
||||
'values' => UserLevel::orderBy('pos')->get(),
|
||||
'trans' => array_keys(config('localization.supportedLocales')),
|
||||
];
|
||||
return view('admin.level.index', $data);
|
||||
|
|
@ -57,6 +57,7 @@ class UserLevelController extends Controller
|
|||
$user_level = UserLevel::create([
|
||||
'name' => $data['name'],
|
||||
'pos' => $data['pos'],
|
||||
'payment_year' => isset($data['payment_year']) ? true : false,
|
||||
'content' => $data['content'],
|
||||
'partner_provision' => isset($data['partner_provision']) ? true : false,
|
||||
'active' => isset($data['active']) ? true : false,
|
||||
|
|
@ -65,6 +66,7 @@ class UserLevelController extends Controller
|
|||
$user_level = UserLevel::find($data['id']);
|
||||
$user_level->name = $data['name'];
|
||||
$user_level->pos = $data['pos'];
|
||||
$user_level->payment_year =isset($data['payment_year']) ? true : false;
|
||||
$user_level->content = $data['content'];
|
||||
$user_level->partner_provision = isset($data['partner_provision']) ? true : false;
|
||||
$user_level->active = isset($data['active']) ? true : false;
|
||||
|
|
|
|||
|
|
@ -270,7 +270,7 @@ class UserShopController extends Controller
|
|||
|
||||
if(Request::get('shop_submit') == 'check'){
|
||||
$rules = array(
|
||||
'user_shop_name' => ' required|alpha_dash|profanity|unique:user_shops,name|min:4|max:20|full_word_check',
|
||||
'user_shop_name' => ' required|alpha_dash|unique:user_shops,name|min:4|max:20|full_word_check',
|
||||
);
|
||||
Validator::extend('full_word_check', function ($attribute, $value, $parameters, $validator) {
|
||||
if(in_array($value, config('profanity.full_word_check'))){
|
||||
|
|
@ -291,7 +291,7 @@ class UserShopController extends Controller
|
|||
if(Request::get('shop_submit') == 'action') {
|
||||
|
||||
$rules = array(
|
||||
'user_shop_name' => ' required|alpha_dash|profanity|unique:user_shops,name|min:4|max:20|full_word_check',
|
||||
'user_shop_name' => ' required|alpha_dash|unique:user_shops,name|min:4|max:20|full_word_check',
|
||||
);
|
||||
Validator::extend('full_word_check', function ($attribute, $value, $parameters, $validator) {
|
||||
if(in_array($value, config('profanity.full_word_check'))){
|
||||
|
|
@ -343,8 +343,10 @@ class UserShopController extends Controller
|
|||
|
||||
public function userShopRegisterSubDomain($slug){
|
||||
|
||||
return ['success' => false, 'error' => 'no KAS'];
|
||||
/*
|
||||
$kas = new KasController();
|
||||
$domain = 'mivita.care';
|
||||
$domain = 'HIER DIE DOMAIN';
|
||||
|
||||
|
||||
//check if exisist
|
||||
|
|
@ -360,7 +362,7 @@ class UserShopController extends Controller
|
|||
$pra = array(
|
||||
'subdomain_name' => $slug,
|
||||
'domain_name' => $domain,
|
||||
'subdomain_path' => '/mein.mivita.care/public/',
|
||||
'subdomain_path' => '/hier der Ordner /public/',
|
||||
'php_version' => '7.3',
|
||||
//'ssl_proxy' => 'Y',
|
||||
//'redirect_status' => 0
|
||||
|
|
@ -370,6 +372,7 @@ class UserShopController extends Controller
|
|||
return ['success' => true];
|
||||
}
|
||||
return ['success' => false, 'error' => $add_subdomain];
|
||||
*/
|
||||
}
|
||||
|
||||
/**
|
||||
|
|
@ -378,7 +381,7 @@ class UserShopController extends Controller
|
|||
public function checkUserShopName(){
|
||||
|
||||
$rules = array(
|
||||
'user_shop_name' => ' required|alpha_dash|profanity|unique:user_shops,name|min:4|max:20|full_word_check',
|
||||
'user_shop_name' => ' required|alpha_dash|unique:user_shops,name|min:4|max:20|full_word_check',
|
||||
);
|
||||
Validator::extend('full_word_check', function ($attribute, $value, $parameters, $validator) {
|
||||
if(in_array($value, config('profanity.full_word_check'))){
|
||||
|
|
|
|||
|
|
@ -3,14 +3,15 @@
|
|||
|
||||
namespace App\Http\Controllers;
|
||||
|
||||
use App\Mail\MailActivateUser;
|
||||
use App\User;
|
||||
use Auth;
|
||||
use Validator;
|
||||
use Request;
|
||||
use Carbon\Carbon;
|
||||
use Illuminate\Database\Connection;
|
||||
use App\Mail\MailActivateUser;
|
||||
use Illuminate\Support\Facades\Mail;
|
||||
use Illuminate\Support\Str;
|
||||
use Request;
|
||||
use Validator;
|
||||
|
||||
class UserUpdateEmailController extends Controller
|
||||
{
|
||||
|
|
@ -146,13 +147,13 @@ class UserUpdateEmailController extends Controller
|
|||
public function sendActivationMail($user, array $data)
|
||||
{
|
||||
$token = $this->createActivation($user, $data);
|
||||
Mail::to($data['email'])->send(new MailActivateUser($token, $user));
|
||||
Mail::to($data['email'])->bcc(config('app.info_mail'))->send(new MailActivateUser($token, $user));
|
||||
}
|
||||
|
||||
|
||||
protected function getToken()
|
||||
{
|
||||
return hash_hmac('sha256', str_random(40), config('app.key'));
|
||||
return hash_hmac('sha256', Str::random(40), config('app.key'));
|
||||
}
|
||||
|
||||
public function createActivation($user, array $data)
|
||||
|
|
|
|||
|
|
@ -2,15 +2,23 @@
|
|||
|
||||
namespace App\Http\Controllers\Web;
|
||||
|
||||
use Yard;
|
||||
use Request;
|
||||
use Response;
|
||||
use Validator;
|
||||
use App\Services\Util;
|
||||
use App\Models\Product;
|
||||
use App\Models\Category;
|
||||
use App\Services\Payment;
|
||||
use App\Models\UserHistory;
|
||||
use App\Models\PaymentMethod;
|
||||
use App\Models\PromotionUser;
|
||||
use App\Models\ShoppingOrder;
|
||||
use App\Models\ShoppingPayment;
|
||||
use App\Services\UserCart;
|
||||
use App\Models\PaymentTransaction;
|
||||
use App\Http\Controllers\Controller;
|
||||
|
||||
use App\Repositories\CheckoutRepository;
|
||||
|
||||
class PromotionController extends Controller
|
||||
{
|
||||
|
|
@ -23,32 +31,57 @@ class PromotionController extends Controller
|
|||
public function serve($path = null)
|
||||
{
|
||||
if(!isset($path)){
|
||||
abort(402);
|
||||
$path = 'grueneseele';
|
||||
//abort(402);
|
||||
|
||||
}
|
||||
|
||||
if($path === 'impressum'){
|
||||
return view('web.legal.impressum');
|
||||
}
|
||||
if($path === 'datenschutzerklaerung'){
|
||||
return view('web.legal.datenschutzerklaerung');
|
||||
}
|
||||
if($path === 'widerrufsbelehrung'){
|
||||
return view('web.legal.widerrufsbelehrung');
|
||||
}
|
||||
if($path === 'versandarten'){
|
||||
return view('web.legal.versandarten');
|
||||
}
|
||||
|
||||
//search for promo
|
||||
$PromotionUser = PromotionUser::where('url', trim($path))->whereNull('user_deleted_at')->first();
|
||||
if(!$PromotionUser){
|
||||
abort(402);
|
||||
}
|
||||
if($PromotionUser->checkOutOfStock()){
|
||||
if(!$PromotionUser->promotion_admin->isActive() || $PromotionUser->checkOutOfStock()){
|
||||
$data = [
|
||||
'promotion_user' => $PromotionUser,
|
||||
];
|
||||
return view('web.promotion.outofstock', $data);
|
||||
}
|
||||
|
||||
UserCart::initYard('prom', null, $PromotionUser);
|
||||
|
||||
$first_category_id = false;
|
||||
if(Request::get('catid')){
|
||||
$first_category_id = Request::get('catid');
|
||||
}
|
||||
|
||||
//$first_category = Category::where('active', true)->whereJsonContains('show_on', ['3'])->orderBy('pos', 'DESC')->first();
|
||||
//$first_category_id = isset($first_category->id) ? $first_category->id : false;
|
||||
$shop_products = $this->getShowProducts($first_category_id);
|
||||
|
||||
$data = [
|
||||
'promotion_user' => $PromotionUser,
|
||||
'shop_products' => Product::where('active', true)->whereJsonContains('show_on', ['1', '2', '3'])->orderBy('pos', 'ASC')->get(),
|
||||
'shop_products' => $shop_products,
|
||||
'user_payment_methods' => PaymentMethod::getDefaultAsArray()->toArray(),
|
||||
'first_category_id' => $first_category_id,
|
||||
'categories_by_show_on' => '3'
|
||||
];
|
||||
return view('web.promotion.index', $data);
|
||||
}
|
||||
|
||||
public function goto($load, $id){
|
||||
public function goto($load, $id, $transactionId=false, $reference=false, $identifier=false){
|
||||
$PromotionUser = PromotionUser::findOrFail($id);
|
||||
|
||||
$data = [
|
||||
'promotion_user' => $PromotionUser,
|
||||
];
|
||||
|
|
@ -56,15 +89,29 @@ class PromotionController extends Controller
|
|||
if($load === 'thanksreminder'){
|
||||
return view('web.promotion.thanksreminder', $data);
|
||||
}
|
||||
if($load === 'thanksorder'){
|
||||
return view('web.promotion.thanksorder', $data);
|
||||
}
|
||||
if($load === 'notactive'){
|
||||
return view('web.promotion.notactive', $data);
|
||||
}
|
||||
if($load === 'thanksorder'){
|
||||
$payt = PaymentTransaction::findOrFail($transactionId);
|
||||
if($payt->shopping_payment->reference != $reference){
|
||||
abort(404);
|
||||
}
|
||||
Yard::instance('shopping')->destroy();
|
||||
$checkRepo = new CheckoutRepository();
|
||||
$checkRepo->destroy();
|
||||
if(($payt->status === 'fnc' || $payt->status === 'vor' || $payt->status === 'pp' || $payt->status === 'non') && $payt->txaction === 'prev'){
|
||||
$this->directPaymentStatus($payt, $identifier);
|
||||
}
|
||||
$data = [
|
||||
'promotion_user' => $PromotionUser,
|
||||
'order_reference' => $payt->shopping_payment->reference,
|
||||
'pay_trans' => $payt,
|
||||
];
|
||||
return view('web.promotion.thanksorder', $data);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
public function store($id){
|
||||
|
||||
$PromotionUser = PromotionUser::findOrFail($id);
|
||||
|
|
@ -75,25 +122,171 @@ class PromotionController extends Controller
|
|||
}
|
||||
if($data['action'] === 'submit-reminder-service'){
|
||||
return redirect(route('web_promotion_goto', ['thanksreminder', $PromotionUser->id]));
|
||||
|
||||
}
|
||||
|
||||
if($data['action'] === 'submit-promotion-order'){
|
||||
return redirect(route('web_promotion_goto', ['thanksorder', $PromotionUser->id]));
|
||||
$rules = array(
|
||||
'billing_firstname'=>'required',
|
||||
'billing_lastname'=>'required',
|
||||
'billing_address'=>'required',
|
||||
'billing_zipcode'=>'required',
|
||||
'billing_city' => 'required',
|
||||
'billing_state' => 'required',
|
||||
'billing_email'=>'required|email',
|
||||
);
|
||||
|
||||
if(Request::get('same_as_billing')){
|
||||
$rules = array_merge($rules, [
|
||||
'shipping_firstname'=>'required',
|
||||
'shipping_lastname'=>'required',
|
||||
'shipping_address'=>'required',
|
||||
'shipping_zipcode'=>'required',
|
||||
'shipping_city' => 'required',
|
||||
'shipping_salutation' => 'required'
|
||||
]);
|
||||
}
|
||||
$validator = Validator::make(Request::all(), $rules);
|
||||
|
||||
if ($validator->fails()) {
|
||||
return back()->withErrors($validator)->withInput(Request::all());
|
||||
}
|
||||
$identifier = Util::getToken();
|
||||
$data['is_from'] = 'shopping';
|
||||
$data['is_for'] = 'pr';
|
||||
unset($data['_token']);
|
||||
Yard::instance('shopping')->putYardExtra('shopping_data', $data);
|
||||
|
||||
UserHistory::create(['user_id' => $PromotionUser->user_id, 'action'=>'web_promotion_payment', 'status'=>1, 'product_id'=>null, 'identifier'=>$identifier]);
|
||||
$checkRepo = new CheckoutRepository();
|
||||
$checkRepo->setPromotion(7, $PromotionUser);
|
||||
$checkRepo->init($identifier, $data);
|
||||
return $checkRepo->makePayment();
|
||||
}
|
||||
|
||||
dd($PromotionUser);
|
||||
}
|
||||
|
||||
private function directPaymentStatus(PaymentTransaction $payt, $identifier){
|
||||
|
||||
if(isset($payt->transmitted_data['param'])){
|
||||
$shopping_order = ShoppingOrder::find($payt->transmitted_data['param']);
|
||||
$shopping_payment = ShoppingPayment::where('reference', $payt->transmitted_data['reference'])->first();
|
||||
|
||||
$shopping_order->txaction = 'open';
|
||||
$shopping_order->save();
|
||||
$payt->txaction = "open";
|
||||
|
||||
//is Promotion Handel it
|
||||
if($shopping_order->promotion_user_id > 0){
|
||||
Payment::handelPromotionProduct($shopping_order);
|
||||
}
|
||||
if($shopping_payment){
|
||||
//Payment::handelUserPayCredits($shopping_order, 'deduction');
|
||||
if($payt->status === 'vor'){
|
||||
$shopping_payment->txaction = 'open';
|
||||
$shopping_order->txaction = 'open';
|
||||
$payt->txaction = "open";
|
||||
$shopping_order->save();
|
||||
|
||||
}
|
||||
if($payt->status === 'pp'){
|
||||
$send_link = Payment::paymentStatusPaidAction($shopping_order, true);
|
||||
$shopping_payment->txaction = 'paid';
|
||||
$shopping_order->txaction = 'paid';
|
||||
$payt->txaction = "paid";
|
||||
$shopping_order->save();
|
||||
}
|
||||
if($payt->status === 'fnc'){
|
||||
$send_link = Payment::paymentStatusPaidAction($shopping_order, true);
|
||||
$shopping_payment->txaction = 'paid';
|
||||
$shopping_order->txaction = 'paid';
|
||||
$payt->txaction = "paid";
|
||||
$shopping_order->save();
|
||||
|
||||
}
|
||||
if($payt->status === 'non'){
|
||||
$send_link = Payment::paymentStatusPaidAction($shopping_order, true);
|
||||
$shopping_payment->txaction = 'paid';
|
||||
$shopping_order->txaction = 'paid';
|
||||
$payt->txaction = "paid";
|
||||
$shopping_order->save();
|
||||
\App\Services\Shop::newUserOrder($shopping_order->shopping_user->number);
|
||||
}
|
||||
$shopping_payment->save();
|
||||
}
|
||||
$payt->save();
|
||||
$data = [
|
||||
'mode' => $payt->transmitted_data['mode'],
|
||||
'txaction' => $payt->txaction,
|
||||
'send_link' => false,
|
||||
];
|
||||
Payment::paymentStatusSendMail($shopping_order, $shopping_payment, $data);
|
||||
}
|
||||
}
|
||||
|
||||
public function load(){
|
||||
$data = Request::all();
|
||||
$ret = "";
|
||||
$status = false;
|
||||
|
||||
if(Request::ajax()){
|
||||
if($data['action'] === 'web-show-product'){
|
||||
$product = Product::find($data['id']); //current user form order
|
||||
$ret = view("web.promotion.show_product", compact('product', 'data'))->render();
|
||||
}
|
||||
if(isset($data['perform'])){
|
||||
if($data['action'] === 'switch-show_products'){
|
||||
$category_id = isset($data['show_products_option']) ? $data['show_products_option'] : false;
|
||||
$shop_products = $this->getShowProducts($category_id);
|
||||
$shop_products_view = view("web.promotion._shop_products_inner", compact('shop_products'))->render();
|
||||
return response()->json(['response' => $data, 'shop_products_view'=>$shop_products_view, 'status'=>$status]);
|
||||
}
|
||||
if($data['action'] === 'switch-free-product'){
|
||||
\App\Services\UserCart::updateFeeProduct($data);
|
||||
}
|
||||
if($data['action'] === 'add-shop-product'){
|
||||
$data['qty'] = \App\Services\UserCart::updateProduct($data, true);
|
||||
}
|
||||
if($data['action'] === 'update-shop-product'){
|
||||
$data['qty'] = \App\Services\UserCart::updateProduct($data);
|
||||
}
|
||||
if($data['action'] === 'remove-shop-product'){
|
||||
\App\Services\UserCart::updateProduct($data);
|
||||
$data['qty'] = 0;
|
||||
}
|
||||
if($data['action'] === 'clear-cart'){
|
||||
\App\Services\UserCart::clearCart($data);
|
||||
}
|
||||
if($data['action'] === 'switch-shipping'){
|
||||
\App\Services\UserCart::switchShipping($data);
|
||||
}
|
||||
if($data['action'] === 'change-state-shipping'){
|
||||
\App\Services\UserCart::changeStateShipping($data, 'prom');
|
||||
}
|
||||
|
||||
$cart = view("web.promotion._promotion_cart", compact('data'))->render();
|
||||
if(Yard::instance('shopping')->isQuickShipping()){
|
||||
$invoice = view("web.components._invoice_details_quick")->render();
|
||||
}else{
|
||||
$invoice = view("web.components._invoice_details")->render();
|
||||
}
|
||||
$checkout = view("web.components._checkout")->render();
|
||||
$data['shipping_price_formated'] = UserCart::getCurrentShippingPrice(2); //shipping_for === 2 promotion , 3 shop
|
||||
|
||||
return response()->json(['response' => $data, 'cart'=>$cart, 'invoice'=>$invoice, 'checkout'=>$checkout, 'status'=>$status, 'basketqty'=>Yard::instance('shopping')->count()]);
|
||||
}
|
||||
return response()->json(['response' => $data, 'html'=>$ret, 'status'=>$status]);
|
||||
}
|
||||
}
|
||||
|
||||
private function getShowProducts($category_id = false){
|
||||
$shop_products = [];
|
||||
if($category_id){
|
||||
$shop_products = Product::where('active', true)->whereJsonContains('show_on', ['3'])
|
||||
->whereHas('categories', function ($query) use ($category_id) {
|
||||
$query->where('category_id', $category_id); //->whereJsonContains('show_on', ['3']);
|
||||
})->orderBy('pos', 'ASC')->get();
|
||||
}else{
|
||||
$shop_products = Product::where('active', true)->whereJsonContains('show_on', ['3'])
|
||||
->orderBy('pos', 'ASC')->get();
|
||||
}
|
||||
return $shop_products;
|
||||
}
|
||||
}
|
||||
|
|
@ -3,19 +3,21 @@
|
|||
namespace App\Http\Controllers\Web;
|
||||
|
||||
|
||||
use App\Http\Controllers\Controller;
|
||||
use App\Mail\MailContact;
|
||||
use App\Mail\MailVerifyAccount;
|
||||
use App\Models\UserHistory;
|
||||
use App\Repositories\UserRepository;
|
||||
use App\Services\SysLog;
|
||||
use App\Services\UserService;
|
||||
use App\User;
|
||||
use GuzzleHttp\Client;
|
||||
use Request;
|
||||
use Illuminate\Support\Facades\Mail;
|
||||
use App\Services\Util;
|
||||
use App\User;
|
||||
use Validator;
|
||||
use App\Services\Util;
|
||||
use GuzzleHttp\Client;
|
||||
use App\Services\SysLog;
|
||||
use App\Mail\MailContact;
|
||||
use App\Models\UserHistory;
|
||||
use App\Models\UserRegister;
|
||||
use App\Services\UserService;
|
||||
use App\Mail\MailVerifyAccount;
|
||||
use App\Http\Controllers\Controller;
|
||||
use App\Repositories\UserRepository;
|
||||
use Illuminate\Support\Facades\Auth;
|
||||
use Illuminate\Support\Facades\Mail;
|
||||
|
||||
|
||||
class RegisterController extends Controller
|
||||
|
|
@ -34,71 +36,160 @@ class RegisterController extends Controller
|
|||
$this->userRepo = $userRepo;
|
||||
}
|
||||
|
||||
public function member($member_id = false)
|
||||
public function showConsentPage()
|
||||
{
|
||||
$data = [
|
||||
'from_member_id' => session('from_member_id')
|
||||
];
|
||||
return view('auth.recaptcha-consent', $data);
|
||||
}
|
||||
|
||||
public function acceptConsent()
|
||||
{
|
||||
if (!Request::has('recaptcha_consent')) {
|
||||
return back()->withErrors(['error' => 'Bitte stimmen Sie der Verwendung von reCAPTCHA zu']);
|
||||
}
|
||||
|
||||
session(['recaptcha_consent' => true]);
|
||||
return redirect()->route('register.form');
|
||||
}
|
||||
|
||||
public function showRegistrationForm()
|
||||
{
|
||||
if (!session('recaptcha_consent')) {
|
||||
return redirect()->route('register.consent');
|
||||
}
|
||||
$data = [
|
||||
'from_member_id' => session('from_member_id')
|
||||
];
|
||||
return view('auth.register', $data);
|
||||
}
|
||||
|
||||
public function member($from_member_id = false)
|
||||
{
|
||||
$this->userRepo->clearUserRegister();
|
||||
|
||||
if(!$from_member_id){
|
||||
return redirect()->route('register.consent');
|
||||
}
|
||||
|
||||
//ist ein gültiger Member ID und ist aktiv?
|
||||
$user_id = (int) str_replace('gs', '', $from_member_id) - config('main.add_number_id');
|
||||
$user = User::find($user_id);
|
||||
if(!$user || !$user->isActive() || !$user->isActiveAccount()){
|
||||
return redirect()->route('register.consent');
|
||||
}
|
||||
session(['from_member_id' => $from_member_id]);
|
||||
return redirect()->route('register.consent');
|
||||
|
||||
/*
|
||||
//hat einen Member ID?
|
||||
if(!$member_id){
|
||||
return redirect('/registrierung');
|
||||
}
|
||||
|
||||
//ist ein gültiger Member ID und ist aktiv?
|
||||
$user_id = (int) str_replace('gs', '', $member_id) - config('main.add_number_id');
|
||||
$user = User::find($user_id);
|
||||
if(!$user || !$user->isActive() || !$user->isActiveAccount()){
|
||||
return redirect('/registrierung');
|
||||
}
|
||||
|
||||
if (!session('recaptcha_consent')) {
|
||||
$data = [
|
||||
'from_member_id' => Request::get('from_member_id')
|
||||
];
|
||||
return view('auth.recaptcha-consent', $data);
|
||||
|
||||
//return redirect()->route('register.consent')->with(['from_member_id' => $member_id]);
|
||||
}
|
||||
|
||||
$data = [
|
||||
'from_member_id' => $member_id
|
||||
];
|
||||
return view('auth.register', $data);
|
||||
*/
|
||||
}
|
||||
|
||||
|
||||
public function register(){
|
||||
|
||||
|
||||
$this->userRepo->clearUserRegister();
|
||||
// Überprüfe zuerst die reCAPTCHA-Einwilligung
|
||||
|
||||
/* if (!Request::has('recaptcha_consent')) {
|
||||
return back()->withErrors(['recaptcha_consent' => 'Bitte stimmen Sie der Verwendung von reCAPTCHA zu'])->withInput(Request::all());
|
||||
}*/
|
||||
|
||||
// Überprüfe reCAPTCHA
|
||||
$recaptchaResponse = Request::input('g-recaptcha-response');
|
||||
if (!$this->verifyRecaptcha($recaptchaResponse)) {
|
||||
return back()->withErrors(['g-recaptcha-response' => 'Bitte bestätigen Sie, dass Sie kein Roboter sind'])->withInput(Request::all());
|
||||
}
|
||||
|
||||
$rules = array(
|
||||
'salutation' => 'required',
|
||||
'first_name'=>'required',
|
||||
'last_name'=>'required',
|
||||
'first_name'=>'required|string|min:2',
|
||||
'last_name'=>'required|string|min:2',
|
||||
'email' => 'required|string|email|max:255|unique:users',
|
||||
'password' => 'required|string|min:6|confirmed',
|
||||
'password_confirmation' => 'required|string|min:6',
|
||||
'accepted_data_protection' => 'required',
|
||||
'g-recaptcha-response' => 'required',
|
||||
);
|
||||
|
||||
|
||||
$validator = Validator::make(Request::all(), $rules);
|
||||
if ($validator->fails()) {
|
||||
return back()->withErrors($validator)->withInput(Request::all());
|
||||
}
|
||||
|
||||
//search in UserRegister
|
||||
$data = Request::all();
|
||||
$user = $this->userRepo->create($data);
|
||||
|
||||
$confirmation_code = UserService::createConfirmationCode();
|
||||
|
||||
$user->lang = !empty(\App::getLocale()) ? \App::getLocale() : "de";
|
||||
$user->confirmation_code = $confirmation_code;
|
||||
$user->confirmation_code_to = date('Y-m-d H:i:s', strtotime('+1 week'));
|
||||
$user->confirmation_code_remider = 0;
|
||||
if(isset($data['from_member_id'])){
|
||||
$user->m_sponsor = (int) str_replace('gs', '', $data['from_member_id']) - config('main.add_number_id');
|
||||
$UserRegister = UserRegister::where('identifier', $data['email'])->first();
|
||||
if($UserRegister){
|
||||
$exists = [
|
||||
'register_email' => $data['email']
|
||||
];
|
||||
return view('auth.existing', $exists);
|
||||
}
|
||||
$user->save();
|
||||
|
||||
$user = User::find($user->id);
|
||||
|
||||
$userObj = $this->userRepo->createUserRegister($data);
|
||||
$from_member_id = session('from_member_id');
|
||||
$user_id = isset($from_member_id) ? (int) str_replace('gs', '', $from_member_id) - config('main.add_number_id') : config('app.main_user_id'); // Krummel
|
||||
try {
|
||||
Mail::to($user->email)->send(new MailVerifyAccount($confirmation_code, $user));
|
||||
Mail::to($userObj->email)->bcc(config('app.info_mail'))->send(new MailVerifyAccount($userObj->confirmation_code, $userObj));
|
||||
}
|
||||
catch(\Exception $e){
|
||||
SysLog::action('register-user', 'auth_register', 5)
|
||||
->setUserId($user->id)
|
||||
->setModel($user->id, User::class)
|
||||
->setUserId($user_id)
|
||||
->setModel(null, UserRegister::class)
|
||||
->setMessage('Error send register E-Mail: '.$e->getMessage())
|
||||
->save();
|
||||
}
|
||||
UserHistory::create(['user_id' => $user->id, 'action'=>'register', 'status'=>0]);
|
||||
UserHistory::create(['user_id' => $user_id, 'action'=>'register', 'status'=>0]);
|
||||
|
||||
return redirect('/user_register/finish');
|
||||
}
|
||||
|
||||
// Neue Methode zur Überprüfung des reCAPTCHA
|
||||
private function verifyRecaptcha($recaptchaResponse)
|
||||
{
|
||||
if (empty($recaptchaResponse)) {
|
||||
return false;
|
||||
}
|
||||
|
||||
$client = new Client();
|
||||
$response = $client->post('https://www.google.com/recaptcha/api/siteverify', [
|
||||
'form_params' => [
|
||||
'secret' => config('services.recaptcha.secret_key'),
|
||||
'response' => $recaptchaResponse
|
||||
]
|
||||
]);
|
||||
|
||||
$body = json_decode((string)$response->getBody());
|
||||
return $body->success;
|
||||
}
|
||||
|
||||
public function finish()
|
||||
{
|
||||
$data = [
|
||||
|
|
@ -106,4 +197,40 @@ class RegisterController extends Controller
|
|||
];
|
||||
return view('auth.finish', $data);
|
||||
}
|
||||
|
||||
public function verify($confirmation_code){
|
||||
|
||||
if( ! $confirmation_code)
|
||||
{
|
||||
return redirect('/status/error');
|
||||
}
|
||||
|
||||
$UserRegister = UserRegister::where ('instance', $confirmation_code)->first();
|
||||
|
||||
if ( ! $UserRegister)
|
||||
{
|
||||
return redirect('/status/not/found');
|
||||
}
|
||||
|
||||
$user = $this->userRepo->create($UserRegister);
|
||||
|
||||
//Login!
|
||||
Auth::login($user);
|
||||
|
||||
return redirect('/home');
|
||||
}
|
||||
|
||||
public function registerAgain(){
|
||||
$data = Request::all();
|
||||
if(!isset($data['register_email'])){
|
||||
abort(403, "No E-Mail");
|
||||
}
|
||||
$UserRegister = UserRegister::where('identifier', $data['register_email'])->first();
|
||||
if(!$UserRegister){
|
||||
abort(403, "No E-Mail Register");
|
||||
}
|
||||
Mail::to($UserRegister->identifier)->bcc(config('app.info_mail'))->send(new MailVerifyAccount($UserRegister->instance, $UserRegister->content));
|
||||
return redirect('/user_register/finish');
|
||||
|
||||
}
|
||||
}
|
||||
294
app/Http/Controllers/Web/ShopController.php
Normal file
294
app/Http/Controllers/Web/ShopController.php
Normal file
|
|
@ -0,0 +1,294 @@
|
|||
<?php
|
||||
|
||||
namespace App\Http\Controllers\Web;
|
||||
|
||||
use Yard;
|
||||
use Request;
|
||||
use Response;
|
||||
use Validator;
|
||||
use App\Services\Util;
|
||||
use App\Models\Product;
|
||||
use App\Models\UserShop;
|
||||
use App\Services\Payment;
|
||||
use App\Models\UserHistory;
|
||||
use App\Models\PaymentMethod;
|
||||
use App\Models\ShoppingOrder;
|
||||
use App\Models\ShoppingPayment;
|
||||
use App\Services\UserCart;
|
||||
use App\Models\PaymentTransaction;
|
||||
use App\Http\Controllers\Controller;
|
||||
use App\Repositories\CheckoutRepository;
|
||||
|
||||
class ShopController extends Controller
|
||||
{
|
||||
|
||||
public function __construct()
|
||||
{
|
||||
|
||||
}
|
||||
|
||||
public function serve($path = null)
|
||||
{
|
||||
if(!isset($path)){
|
||||
$path = 'grueneseele';
|
||||
//abort(402);
|
||||
}
|
||||
if($path === 'impressum'){
|
||||
return view('web.legal.impressum');
|
||||
}
|
||||
if($path === 'datenschutzerklaerung'){
|
||||
return view('web.legal.datenschutzerklaerung');
|
||||
}
|
||||
if($path === 'widerrufsbelehrung'){
|
||||
return view('web.legal.widerrufsbelehrung');
|
||||
}
|
||||
if($path === 'versandarten'){
|
||||
return view('web.legal.versandarten');
|
||||
}
|
||||
|
||||
//search for promo
|
||||
$userShop = UserShop::where('url', trim($path))->first();
|
||||
if(!$userShop){
|
||||
//redirect !!!!
|
||||
abort(402);
|
||||
}
|
||||
if(!$userShop->isActive()){
|
||||
$data = [
|
||||
'user_shop' => $userShop,
|
||||
];
|
||||
//redirect !!!!
|
||||
return view('web.shop.outofstock', $data);
|
||||
}
|
||||
UserCart::initYard('shop', $userShop, null);
|
||||
$first_category_id = false;
|
||||
if(Request::get('catid')){
|
||||
$first_category_id = Request::get('catid');
|
||||
}
|
||||
|
||||
$userMargin = \App\Services\Shop::calculateUserShopMargins($userShop, null);
|
||||
|
||||
//$first_category = Category::where('active', true)->whereJsonContains('show_on', ['8'])->orderBy('pos', 'DESC')->first();
|
||||
// $first_category_id = isset($first_category->id) ? $first_category->id : false;
|
||||
$shop_products = $this->getShowProducts($first_category_id);
|
||||
|
||||
$data = [
|
||||
'user_shop' => $userShop,
|
||||
'shop_products' => $shop_products,
|
||||
'user_payment_methods' => PaymentMethod::getDefaultAsArray()->toArray(),
|
||||
'first_category_id' => $first_category_id,
|
||||
'categories_by_show_on' => '8',
|
||||
'userMargin' => $userMargin
|
||||
];
|
||||
return view('web.shop.index', $data);
|
||||
}
|
||||
|
||||
public function goto($load, $user_shop_id, $transactionId=false, $reference=false, $identifier=false){
|
||||
$userShop = UserShop::findOrFail($user_shop_id);
|
||||
$data = [
|
||||
'user_shop' => $userShop,
|
||||
];
|
||||
|
||||
if($load === 'thanksreminder'){
|
||||
return view('web.shop.thanksreminder', $data);
|
||||
}
|
||||
if($load === 'notactive'){
|
||||
return view('web.shop.notactive', $data);
|
||||
}
|
||||
if($load === 'thanksorder'){
|
||||
$payt = PaymentTransaction::findOrFail($transactionId);
|
||||
if($payt->shopping_payment->reference != $reference){
|
||||
abort(404);
|
||||
}
|
||||
Yard::instance('shopping')->destroy();
|
||||
$checkRepo = new CheckoutRepository();
|
||||
$checkRepo->destroy();
|
||||
if(($payt->status === 'fnc' || $payt->status === 'vor' || $payt->status === 'pp' || $payt->status === 'non') && $payt->txaction === 'prev'){
|
||||
$this->directPaymentStatus($payt, $identifier);
|
||||
}
|
||||
$data = [
|
||||
'user_shop' => $userShop,
|
||||
'order_reference' => $payt->shopping_payment->reference,
|
||||
'pay_trans' => $payt,
|
||||
];
|
||||
return view('web.shop.thanksorder', $data);
|
||||
}
|
||||
|
||||
}
|
||||
public function store($user_shop_id){
|
||||
|
||||
$userShop = UserShop::findOrFail($user_shop_id);
|
||||
$data = Request::all();
|
||||
if(!isset($data['action'])){
|
||||
abort(402);
|
||||
}
|
||||
|
||||
if($data['action'] === 'submit-reminder-service'){
|
||||
return redirect(route('web_shop_goto', ['thanksreminder', $userShop->id]));
|
||||
}
|
||||
if($data['action'] === 'submit-order'){
|
||||
$rules = array(
|
||||
'billing_firstname'=>'required',
|
||||
'billing_lastname'=>'required',
|
||||
'billing_address'=>'required',
|
||||
'billing_zipcode'=>'required',
|
||||
'billing_city' => 'required',
|
||||
'billing_state' => 'required',
|
||||
'billing_email'=>'required|email',
|
||||
);
|
||||
|
||||
if(Request::get('same_as_billing')){
|
||||
$rules = array_merge($rules, [
|
||||
'shipping_firstname'=>'required',
|
||||
'shipping_lastname'=>'required',
|
||||
'shipping_address'=>'required',
|
||||
'shipping_zipcode'=>'required',
|
||||
'shipping_city' => 'required',
|
||||
'shipping_salutation' => 'required'
|
||||
]);
|
||||
}
|
||||
$validator = Validator::make(Request::all(), $rules);
|
||||
|
||||
if ($validator->fails()) {
|
||||
return back()->withErrors($validator)->withInput(Request::all());
|
||||
}
|
||||
$identifier = Util::getToken();
|
||||
$data['is_from'] = 'shopping';
|
||||
$data['is_for'] = 'us'; //usershopping
|
||||
unset($data['_token']);
|
||||
Yard::instance('shopping')->putYardExtra('shopping_data', $data);
|
||||
|
||||
UserHistory::create(['user_id' => $userShop->user_id, 'action'=>'web_shop_payment', 'status'=>1, 'product_id'=>null, 'identifier'=>$identifier]);
|
||||
$checkRepo = new CheckoutRepository();
|
||||
$checkRepo->setUserShop(8, $userShop);
|
||||
$checkRepo->init($identifier, $data);
|
||||
return $checkRepo->makePayment();
|
||||
}
|
||||
}
|
||||
|
||||
private function directPaymentStatus(PaymentTransaction $payt, $identifier){
|
||||
|
||||
if(isset($payt->transmitted_data['param'])){
|
||||
$shopping_order = ShoppingOrder::find($payt->transmitted_data['param']);
|
||||
$shopping_payment = ShoppingPayment::where('reference', $payt->transmitted_data['reference'])->first();
|
||||
|
||||
$shopping_order->txaction = 'open';
|
||||
$shopping_order->save();
|
||||
$payt->txaction = "open";
|
||||
|
||||
//is Promotion Handel it
|
||||
if($shopping_order->promotion_user_id > 0){
|
||||
Payment::handelPromotionProduct($shopping_order);
|
||||
}
|
||||
if($shopping_payment){
|
||||
//Payment::handelUserPayCredits($shopping_order, 'deduction');
|
||||
if($payt->status === 'vor'){
|
||||
$shopping_payment->txaction = 'open';
|
||||
$shopping_order->txaction = 'open';
|
||||
$payt->txaction = "open";
|
||||
$shopping_order->save();
|
||||
|
||||
}
|
||||
if($payt->status === 'pp'){
|
||||
$send_link = Payment::paymentStatusPaidAction($shopping_order, true);
|
||||
$shopping_payment->txaction = 'paid';
|
||||
$shopping_order->txaction = 'paid';
|
||||
$payt->txaction = "paid";
|
||||
$shopping_order->save();
|
||||
}
|
||||
if($payt->status === 'fnc'){
|
||||
$send_link = Payment::paymentStatusPaidAction($shopping_order, true);
|
||||
$shopping_payment->txaction = 'paid';
|
||||
$shopping_order->txaction = 'paid';
|
||||
$payt->txaction = "paid";
|
||||
$shopping_order->save();
|
||||
|
||||
}
|
||||
if($payt->status === 'non'){
|
||||
$send_link = Payment::paymentStatusPaidAction($shopping_order, true);
|
||||
$shopping_payment->txaction = 'paid';
|
||||
$shopping_order->txaction = 'paid';
|
||||
$payt->txaction = "paid";
|
||||
$shopping_order->save();
|
||||
\App\Services\Shop::newUserOrder($shopping_order->shopping_user->number);
|
||||
}
|
||||
$shopping_payment->save();
|
||||
}
|
||||
$payt->save();
|
||||
$data = [
|
||||
'mode' => $payt->transmitted_data['mode'],
|
||||
'txaction' => $payt->txaction,
|
||||
'send_link' => false,
|
||||
];
|
||||
Payment::paymentStatusSendMail($shopping_order, $shopping_payment, $data);
|
||||
}
|
||||
}
|
||||
|
||||
public function load(){
|
||||
$data = Request::all();
|
||||
$ret = "";
|
||||
$status = false;
|
||||
|
||||
if(Request::ajax()){
|
||||
if($data['action'] === 'web-show-product'){
|
||||
$product = Product::find($data['id']); //current user form order
|
||||
$ret = view("web.shop.show_product", compact('product', 'data'))->render();
|
||||
}
|
||||
if(isset($data['perform'])){
|
||||
if($data['action'] === 'switch-show_products'){
|
||||
$category_id = isset($data['show_products_option']) ? $data['show_products_option'] : false;
|
||||
$shop_products = $this->getShowProducts($category_id);
|
||||
$shop_products_view = view("web.shop._shop_products_inner", compact('shop_products'))->render();
|
||||
return response()->json(['response' => $data, 'shop_products_view'=>$shop_products_view, 'status'=>$status]);
|
||||
}
|
||||
if($data['action'] === 'add-shop-product'){
|
||||
$data['qty'] = \App\Services\UserCart::updateProduct($data, true);
|
||||
}
|
||||
if($data['action'] === 'minus-shop-product'){
|
||||
$data['qty'] = \App\Services\UserCart::updateProduct($data, false, true);
|
||||
}
|
||||
if($data['action'] === 'update-shop-product'){
|
||||
$data['qty'] = \App\Services\UserCart::updateProduct($data);
|
||||
}
|
||||
if($data['action'] === 'remove-shop-product'){
|
||||
\App\Services\UserCart::updateProduct($data);
|
||||
$data['qty'] = 0;
|
||||
}
|
||||
if($data['action'] === 'clear-cart'){
|
||||
\App\Services\UserCart::clearCart($data);
|
||||
}
|
||||
if($data['action'] === 'switch-shipping'){
|
||||
\App\Services\UserCart::switchShipping($data);
|
||||
}
|
||||
if($data['action'] === 'change-state-shipping'){
|
||||
\App\Services\UserCart::changeStateShipping($data, 'shop');
|
||||
}
|
||||
|
||||
$cart = view("web.shop._shop_cart", compact('data'))->render();
|
||||
if(Yard::instance('shopping')->isQuickShipping()){
|
||||
$invoice = view("web.components._invoice_details_quick")->render();
|
||||
}else{
|
||||
$invoice = view("web.components._invoice_details")->render();
|
||||
}
|
||||
$checkout = view("web.components._checkout")->render();
|
||||
$data['shipping_price_formated'] = UserCart::getCurrentShippingPrice(3); //shipping_for === 2 promotion , 3 shop
|
||||
|
||||
return response()->json(['response' => $data, 'cart'=>$cart, 'invoice'=>$invoice, 'checkout'=>$checkout, 'status'=>$status, 'basketqty'=>Yard::instance('shopping')->count()]);
|
||||
}
|
||||
return response()->json(['response' => $data, 'html'=>$ret, 'status'=>$status]);
|
||||
}
|
||||
}
|
||||
|
||||
private function getShowProducts($category_id = false){
|
||||
$shop_products = [];
|
||||
if($category_id){
|
||||
$shop_products = Product::where('active', true)->whereJsonContains('show_on', ['8'])
|
||||
->whereHas('categories', function ($query) use ($category_id) {
|
||||
$query->where('category_id', $category_id); //->whereJsonContains('show_on', ['3']);
|
||||
})->orderBy('pos', 'ASC')->get();
|
||||
}else{
|
||||
$shop_products = Product::where('active', true)->whereJsonContains('show_on', ['8'])
|
||||
->orderBy('pos', 'ASC')->get();
|
||||
}
|
||||
return $shop_products;
|
||||
}
|
||||
}
|
||||
|
|
@ -2,22 +2,23 @@
|
|||
|
||||
namespace App\Http\Controllers;
|
||||
|
||||
use App\Mail\MailReleaseAccount;
|
||||
use App\Models\File;
|
||||
use App\Models\Product;
|
||||
use App\Models\ShoppingInstance;
|
||||
use App\Models\UserAccount;
|
||||
use App\Models\UserHistory;
|
||||
use App\Models\UserLevel;
|
||||
use App\Repositories\FileRepository;
|
||||
use App\Services\Util;
|
||||
use App\User;
|
||||
use Auth;
|
||||
use Hash;
|
||||
use Illuminate\Support\Facades\Mail;
|
||||
use Request;
|
||||
use Validator;
|
||||
use Yard;
|
||||
use Request;
|
||||
use App\User;
|
||||
use Validator;
|
||||
use App\Models\File;
|
||||
use App\Services\Util;
|
||||
use App\Models\Product;
|
||||
use App\Models\UserLevel;
|
||||
use App\Models\UserAccount;
|
||||
use App\Models\UserHistory;
|
||||
use App\Mail\MailReleaseAccount;
|
||||
use App\Models\ShoppingInstance;
|
||||
use App\Repositories\FileRepository;
|
||||
use App\Repositories\UserRepository;
|
||||
use Illuminate\Support\Facades\Mail;
|
||||
|
||||
class WizardController extends Controller
|
||||
{
|
||||
|
|
@ -95,7 +96,7 @@ class WizardController extends Controller
|
|||
$data = [
|
||||
'user' => Auth::user(),
|
||||
'step' => $step,
|
||||
'user_levels' => UserLevel::where('active', true)->get(),
|
||||
'user_levels' => UserLevel::where('active', true)->orderBy('pos', 'ASC')->get(),
|
||||
//'products' => Product::where('active', true)->whereJsonContains('show_on', ['4', '5'])->orderBy('pos', 'ASC')->get(),
|
||||
//'products_on_board' => Product::where('active', true)->whereJsonContains('show_on', '6')->orderBy('pos', 'ASC')->get(),
|
||||
|
||||
|
|
@ -149,7 +150,13 @@ class WizardController extends Controller
|
|||
if (!$user->account) {
|
||||
$user->account = new UserAccount();
|
||||
}
|
||||
|
||||
|
||||
$data = Request::all();
|
||||
if($step == 7 && Request::get('user_country_id')){
|
||||
$user->account->country_id = Request::get('user_country_id');
|
||||
$user->account->save();
|
||||
return redirect(route('wizard_register', [1]));
|
||||
}
|
||||
if ($step == 0) {
|
||||
$rules = array(
|
||||
'accepted_data_protection' => 'required',
|
||||
|
|
@ -161,7 +168,7 @@ class WizardController extends Controller
|
|||
$data = [
|
||||
'user' => Auth::user(),
|
||||
'step' => $step,
|
||||
'user_levels' => UserLevel::where('active', true)->get(),
|
||||
'user_levels' => UserLevel::where('active', true)->orderBy('pos', 'ASC')->get(),
|
||||
//'products' => Product::where('active', true)->whereJsonContains('show_on', ['4', '5'])->orderBy('pos', 'ASC')->get(),
|
||||
//'products_on_board' => Product::where('active', true)->whereJsonContains('show_on', '6')->orderBy('pos', 'ASC')->get(),,
|
||||
];
|
||||
|
|
@ -185,7 +192,23 @@ class WizardController extends Controller
|
|||
$user->save();
|
||||
return redirect(route('wizard_register'));
|
||||
}
|
||||
|
||||
if ($step == 1) {
|
||||
$data = Request::all();
|
||||
if(isset($data['action']) && $data['action'] == "reverse_charge_validate"){
|
||||
$user->wizard = 1;
|
||||
$user->save();
|
||||
$userRepo = new UserRepository($user);
|
||||
return $userRepo->reverse_charge_validate($data, $user, route('wizard_register', [1]));
|
||||
}
|
||||
|
||||
if(isset($data['action']) && $data['action'] == "reverse_charge_delete"){
|
||||
$user->wizard = 1;
|
||||
$user->save();
|
||||
$userRepo = new UserRepository($user);
|
||||
return $userRepo->reverse_charge_delete($data, $user, route('wizard_register', [1]));
|
||||
}
|
||||
|
||||
$rules = array(
|
||||
'salutation' => 'required',
|
||||
'first_name' => 'required',
|
||||
|
|
@ -198,9 +221,6 @@ class WizardController extends Controller
|
|||
'tax_number' => 'required_without:tax_identification_number',
|
||||
'tax_identification_number' => 'required_without:tax_number',
|
||||
'country_id' => 'required|integer|min:1',
|
||||
'birthday_day' => 'required',
|
||||
'birthday_month' => 'required',
|
||||
'birthday_year' => 'required'
|
||||
);
|
||||
|
||||
if (!Request::get('same_as_billing')) {
|
||||
|
|
@ -220,19 +240,26 @@ class WizardController extends Controller
|
|||
$user->save();
|
||||
return redirect(route('wizard_register', [1]))->withErrors($validator)->withInput(Request::all());
|
||||
}
|
||||
|
||||
$data = Request::all();
|
||||
$data['same_as_billing'] = Request::get('same_as_billing') == NULL ? 0 : 1;
|
||||
$data['birthday_day'] = isset($data['birthday_day']) ? $data['birthday_day'] : 1;
|
||||
$data['birthday_month'] = isset($data['birthday_month']) ? $data['birthday_month'] : 1;
|
||||
$data['birthday_year'] = isset($data['birthday_year']) ? $data['birthday_year'] : 1970;
|
||||
$data['birthday'] = $data['birthday_day'].".".$data['birthday_month'].".".$data['birthday_year'];
|
||||
$data['birthday_year'] = isset($data['birthday_year']) ? $data['birthday_year'] : 1900;
|
||||
$data['birthday'] = $data['birthday_day'].".".$data['birthday_month'].".".$data['birthday_year'];
|
||||
$data['birthday'] = $data['birthday'] == "1.1.1900" ? null : $data['birthday'];
|
||||
$user->account->fill($data)->save();
|
||||
$user->wizard = 2;
|
||||
$user->save();
|
||||
return redirect(route('wizard_register'));
|
||||
}
|
||||
|
||||
if ($step == 2) {
|
||||
/* if ($step == 2) {
|
||||
//kein Ausweis hochladen - deaktiviert
|
||||
dd("deaktiviert");
|
||||
$user->wizard = 3;
|
||||
$user->save();
|
||||
return redirect(route('wizard_register'));
|
||||
/*
|
||||
if(Request::get('submit') === 'do'){
|
||||
if(File::whereUserId($user->id)->whereIdentifier('id_card')->count() == 0){
|
||||
$validator = Validator::make(Request::all(), []);
|
||||
|
|
@ -251,8 +278,10 @@ class WizardController extends Controller
|
|||
$this->fileRepo->_set('identifier', 'id_card');
|
||||
return $this->fileRepo->uploadFile(Request::all());
|
||||
}
|
||||
*/
|
||||
|
||||
if ($step == 3) {
|
||||
if ($step == 2) {
|
||||
$data = Request::all();
|
||||
if(Request::get('submit') === 'do'){
|
||||
$data = Request::all();
|
||||
|
||||
|
|
@ -260,7 +289,7 @@ class WizardController extends Controller
|
|||
if(File::whereUserId($user->id)->whereIdentifier('business_license')->count() == 0){
|
||||
$validator = Validator::make(Request::all(), []);
|
||||
$validator->errors()->add('field', __('Kein Gewerbeschein hinterlegt, bitte erst hochladen.'));
|
||||
$user->wizard = 3;
|
||||
$user->wizard = 2;
|
||||
$user->save();
|
||||
return redirect(route('wizard_register'))->withErrors($validator)->withInput(Request::all());
|
||||
}
|
||||
|
|
@ -272,7 +301,7 @@ class WizardController extends Controller
|
|||
if(!$data['non_business_license_reason'] || $data['non_business_license_reason'] == ""){
|
||||
$validator = Validator::make(Request::all(), []);
|
||||
$validator->errors()->add('field', __('Bitte gib eine Begründung ein, warum Du keinen Gewerbeschein benötigst.'));
|
||||
$user->wizard = 3;
|
||||
$user->wizard = 2;
|
||||
$user->save();
|
||||
return redirect(route('wizard_register'))->withErrors($validator)->withInput(Request::all());
|
||||
}else{
|
||||
|
|
@ -281,7 +310,7 @@ class WizardController extends Controller
|
|||
}
|
||||
|
||||
$user->account->setNotice('business_license', $data['business_license_choose']);
|
||||
$user->wizard = 4;
|
||||
$user->wizard = 3;
|
||||
$user->save();
|
||||
|
||||
return redirect(route('wizard_register'));
|
||||
|
|
@ -293,7 +322,7 @@ class WizardController extends Controller
|
|||
return $this->fileRepo->uploadFile(Request::all());
|
||||
}
|
||||
|
||||
if ($step == 4) {
|
||||
if ($step == 3) {
|
||||
|
||||
$data = Request::all();
|
||||
|
||||
|
|
@ -397,6 +426,23 @@ class WizardController extends Controller
|
|||
return redirect(route('wizard_create', [12]));
|
||||
}
|
||||
if($step == 12){
|
||||
|
||||
$data = Request::all();
|
||||
|
||||
if(isset($data['action']) && $data['action'] == "reverse_charge_validate"){
|
||||
$user->wizard = 12;
|
||||
$user->save();
|
||||
$userRepo = new UserRepository($user);
|
||||
return $userRepo->reverse_charge_validate($data, $user, route('wizard_create', [12]));
|
||||
}
|
||||
|
||||
if(isset($data['action']) && $data['action'] == "reverse_charge_delete"){
|
||||
$user->wizard = 12;
|
||||
$user->save();
|
||||
$userRepo = new UserRepository($user);
|
||||
return $userRepo->reverse_charge_delete($data, $user, route('wizard_create', [12]));
|
||||
}
|
||||
|
||||
$rules = array(
|
||||
'salutation' => 'required',
|
||||
'first_name' => 'required',
|
||||
|
|
@ -409,9 +455,6 @@ class WizardController extends Controller
|
|||
'tax_number' => 'required_without:tax_identification_number',
|
||||
'tax_identification_number' => 'required_without:tax_number',
|
||||
'country_id' => 'required|integer|min:1',
|
||||
'birthday_day' => 'required',
|
||||
'birthday_month' => 'required',
|
||||
'birthday_year' => 'required'
|
||||
);
|
||||
|
||||
if(!Request::get('same_as_billing')){
|
||||
|
|
@ -464,6 +507,15 @@ class WizardController extends Controller
|
|||
if($product->images->count()){
|
||||
$image = $product->images->first()->slug;
|
||||
}
|
||||
/*need setGlobalTaxRate
|
||||
$cartItem = Yard::instance('shopping')->add($product->id, $product->getLang('name'), 1, $product->getPriceWith(\App\Services\UserService::getTaxFree(), false, \App\Services\UserService::$user_country), false, false, ['image' => $image, 'slug' => $product->slug, 'weight' => $product->weight, 'points' => $product->points, 'no_commission' => $product->no_commission]);
|
||||
if(\App\Services\UserService::getTaxFree()){
|
||||
Yard::setTax($cartItem->rowId, 0);
|
||||
}else{
|
||||
Yard::setTax($cartItem->rowId, $product->getTaxWith(\App\Services\UserService::$user_country));
|
||||
}
|
||||
*/
|
||||
//Keine steuer
|
||||
Yard::instance('shopping')->add($product->id, $product->getLang('name'), 1, $product->price, $product->tax, ['image' => $image, 'slug' => $product->slug, 'weight' => $product->weight]);
|
||||
Yard::instance('shopping')->setGlobalTaxRate(0);
|
||||
|
||||
|
|
@ -475,6 +527,18 @@ class WizardController extends Controller
|
|||
if($product_on_board->images->count()){
|
||||
$image = $product_on_board->images->first()->slug;
|
||||
}
|
||||
|
||||
/*
|
||||
need?
|
||||
$cartItem = Yard::instance('shopping')->add($product_on_board->id, $product_on_board->getLang('name'), 1,
|
||||
$product_on_board->getPriceWith(\App\Services\UserService::getTaxFree(), false, \App\Services\UserService::$user_country),
|
||||
false, false, ['image' => $image, 'slug' => $product_on_board->slug, 'weight' => $product_on_board->weight, 'points' => $product_on_board->points, 'no_commission' => $product_on_board->no_commission]);
|
||||
if(\App\Services\UserService::getTaxFree()){
|
||||
Yard::setTax($cartItem->rowId, 0);
|
||||
}else{
|
||||
Yard::setTax($cartItem->rowId, $product->getTaxWith(\App\Services\UserService::$user_country));
|
||||
}
|
||||
*/
|
||||
Yard::instance('shopping')->add($product_on_board->id, $product_on_board->getLang('name'), 1, $product_on_board->price, $product->tax, ['image' => $image, 'slug' => $product_on_board->slug, 'weight' => $product_on_board->weight]);
|
||||
}
|
||||
}
|
||||
|
|
@ -522,10 +586,16 @@ class WizardController extends Controller
|
|||
if($relation === 'upload'){
|
||||
$user = User::findOrFail(Auth::user()->id);
|
||||
$file = $user->files()->findOrFail($id);
|
||||
$identifier = $file->identifier;
|
||||
//remove file
|
||||
\Storage::disk('user')->delete($file->dir.$file->filename);
|
||||
$file->delete();
|
||||
\Session()->flash('alert-success', "Datei gelöscht");
|
||||
if($identifier === 'business_license'){
|
||||
$user->wizard = 2;
|
||||
$user->save();
|
||||
return redirect(route('wizard_register', [2]));
|
||||
}
|
||||
}
|
||||
return back();
|
||||
}
|
||||
|
|
|
|||
|
|
@ -15,7 +15,7 @@ class Kernel extends HttpKernel
|
|||
*/
|
||||
protected $middleware = [
|
||||
\App\Http\Middleware\TrustProxies::class,
|
||||
\Fruitcake\Cors\HandleCors::class,
|
||||
\Illuminate\Http\Middleware\HandleCors::class,
|
||||
\App\Http\Middleware\CheckForMaintenanceMode::class,
|
||||
\Illuminate\Foundation\Http\Middleware\ValidatePostSize::class,
|
||||
\App\Http\Middleware\TrimStrings::class,
|
||||
|
|
@ -54,6 +54,7 @@ class Kernel extends HttpKernel
|
|||
protected $routeMiddleware = [
|
||||
'auth' => \App\Http\Middleware\Authenticate::class,
|
||||
'auth.basic' => \Illuminate\Auth\Middleware\AuthenticateWithBasicAuth::class,
|
||||
'copyreader' => \App\Http\Middleware\CopyReader::class,
|
||||
'admin' => \App\Http\Middleware\Admin::class,
|
||||
'superadmin' => \App\Http\Middleware\SuperAdmin::class,
|
||||
'sysadmin' => \App\Http\Middleware\SysAdmin::class,
|
||||
|
|
|
|||
26
app/Http/Middleware/CopyReader.php
Normal file
26
app/Http/Middleware/CopyReader.php
Normal file
|
|
@ -0,0 +1,26 @@
|
|||
<?php
|
||||
|
||||
namespace App\Http\Middleware;
|
||||
|
||||
use Closure;
|
||||
use Auth;
|
||||
|
||||
class CopyReader
|
||||
{
|
||||
/**
|
||||
* Handle an incoming request.
|
||||
*
|
||||
* @param \Illuminate\Http\Request $request
|
||||
* @param \Closure $next
|
||||
* @return mixed
|
||||
*/
|
||||
public function handle($request, Closure $next)
|
||||
{
|
||||
if ( Auth::check() && Auth::user()->isCopyReader() )
|
||||
{
|
||||
return $next($request);
|
||||
}
|
||||
return redirect('/home');
|
||||
|
||||
}
|
||||
}
|
||||
|
|
@ -2,15 +2,15 @@
|
|||
|
||||
namespace App\Http\Middleware;
|
||||
|
||||
use Illuminate\Http\Middleware\TrustProxies as Middleware;
|
||||
use Illuminate\Http\Request;
|
||||
use Fideloper\Proxy\TrustProxies as Middleware;
|
||||
|
||||
class TrustProxies extends Middleware
|
||||
{
|
||||
/**
|
||||
* The trusted proxies for this application.
|
||||
*
|
||||
* @var array|string
|
||||
* @var array|string|null
|
||||
*/
|
||||
protected $proxies;
|
||||
|
||||
|
|
@ -19,5 +19,10 @@ class TrustProxies extends Middleware
|
|||
*
|
||||
* @var int
|
||||
*/
|
||||
protected $headers = Request::HEADER_X_FORWARDED_ALL;
|
||||
protected $headers =
|
||||
Request::HEADER_X_FORWARDED_FOR |
|
||||
Request::HEADER_X_FORWARDED_HOST |
|
||||
Request::HEADER_X_FORWARDED_PORT |
|
||||
Request::HEADER_X_FORWARDED_PROTO |
|
||||
Request::HEADER_X_FORWARDED_AWS_ELB;
|
||||
}
|
||||
|
|
|
|||
50
app/Http/Requests/Inventory/ReceiveStockEntryRequest.php
Normal file
50
app/Http/Requests/Inventory/ReceiveStockEntryRequest.php
Normal file
|
|
@ -0,0 +1,50 @@
|
|||
<?php
|
||||
|
||||
namespace App\Http\Requests\Inventory;
|
||||
|
||||
use Illuminate\Foundation\Http\FormRequest;
|
||||
use Illuminate\Validation\Validator;
|
||||
|
||||
class ReceiveStockEntryRequest extends FormRequest
|
||||
{
|
||||
public function authorize(): bool
|
||||
{
|
||||
return true;
|
||||
}
|
||||
|
||||
/**
|
||||
* @return array<string, array<int, mixed>>
|
||||
*/
|
||||
public function rules(): array
|
||||
{
|
||||
return [
|
||||
'received_at' => ['required', 'date'],
|
||||
'received_quantity' => ['required', 'numeric', 'min:0.000001'],
|
||||
'batch_number' => ['nullable', 'string', 'max:100'],
|
||||
'best_before' => ['nullable', 'date'],
|
||||
'quality_id' => ['nullable', 'integer', 'exists:material_qualities,id'],
|
||||
];
|
||||
}
|
||||
|
||||
protected function prepareForValidation(): void
|
||||
{
|
||||
$this->merge([
|
||||
'received_quantity' => reFormatNumber($this->input('received_quantity')),
|
||||
]);
|
||||
}
|
||||
|
||||
public function withValidator(Validator $validator): void
|
||||
{
|
||||
$validator->after(function (Validator $validator): void {
|
||||
$stockEntry = $this->route('stockEntry') ?? $this->route('stock_entry');
|
||||
if ($stockEntry && $stockEntry->entry_type === 'ingredient') {
|
||||
if (empty($this->input('batch_number'))) {
|
||||
$validator->errors()->add('batch_number', __('Bitte eine Chargennummer angeben.'));
|
||||
}
|
||||
if (empty($this->input('best_before'))) {
|
||||
$validator->errors()->add('best_before', __('Bitte die Mindesthaltbarkeit angeben.'));
|
||||
}
|
||||
}
|
||||
});
|
||||
}
|
||||
}
|
||||
31
app/Http/Requests/Inventory/StoreLocationRequest.php
Normal file
31
app/Http/Requests/Inventory/StoreLocationRequest.php
Normal file
|
|
@ -0,0 +1,31 @@
|
|||
<?php
|
||||
|
||||
namespace App\Http\Requests\Inventory;
|
||||
|
||||
use Illuminate\Foundation\Http\FormRequest;
|
||||
|
||||
class StoreLocationRequest extends FormRequest
|
||||
{
|
||||
public function authorize(): bool
|
||||
{
|
||||
return true;
|
||||
}
|
||||
|
||||
/**
|
||||
* @return array<string, array<int, string>>
|
||||
*/
|
||||
public function rules(): array
|
||||
{
|
||||
return [
|
||||
'name' => ['required', 'string', 'max:255'],
|
||||
'active' => ['sometimes', 'boolean'],
|
||||
];
|
||||
}
|
||||
|
||||
protected function prepareForValidation(): void
|
||||
{
|
||||
$this->merge([
|
||||
'active' => $this->boolean('active'),
|
||||
]);
|
||||
}
|
||||
}
|
||||
31
app/Http/Requests/Inventory/StoreMaterialQualityRequest.php
Normal file
31
app/Http/Requests/Inventory/StoreMaterialQualityRequest.php
Normal file
|
|
@ -0,0 +1,31 @@
|
|||
<?php
|
||||
|
||||
namespace App\Http\Requests\Inventory;
|
||||
|
||||
use Illuminate\Foundation\Http\FormRequest;
|
||||
|
||||
class StoreMaterialQualityRequest extends FormRequest
|
||||
{
|
||||
public function authorize(): bool
|
||||
{
|
||||
return true;
|
||||
}
|
||||
|
||||
/**
|
||||
* @return array<string, array<int, string>>
|
||||
*/
|
||||
public function rules(): array
|
||||
{
|
||||
return [
|
||||
'name' => ['required', 'string', 'max:255'],
|
||||
'pos' => ['nullable', 'integer', 'min:0', 'max:255'],
|
||||
];
|
||||
}
|
||||
|
||||
protected function prepareForValidation(): void
|
||||
{
|
||||
if ($this->has('pos') && $this->input('pos') === '') {
|
||||
$this->merge(['pos' => 0]);
|
||||
}
|
||||
}
|
||||
}
|
||||
47
app/Http/Requests/Inventory/StorePackagingItemRequest.php
Normal file
47
app/Http/Requests/Inventory/StorePackagingItemRequest.php
Normal file
|
|
@ -0,0 +1,47 @@
|
|||
<?php
|
||||
|
||||
namespace App\Http\Requests\Inventory;
|
||||
|
||||
use Illuminate\Foundation\Http\FormRequest;
|
||||
use Illuminate\Validation\Rule;
|
||||
|
||||
class StorePackagingItemRequest extends FormRequest
|
||||
{
|
||||
public function authorize(): bool
|
||||
{
|
||||
return true;
|
||||
}
|
||||
|
||||
/**
|
||||
* @return array<string, array<int, mixed>>
|
||||
*/
|
||||
public function rules(): array
|
||||
{
|
||||
return [
|
||||
'packaging_material_id' => ['required', 'integer', 'exists:packaging_materials,id'],
|
||||
'supplier_id' => ['nullable', 'integer', 'exists:suppliers,id'],
|
||||
'name' => ['required', 'string', 'max:255'],
|
||||
'category' => ['required', Rule::in(['packaging', 'shipping'])],
|
||||
'weight_grams' => ['nullable', 'numeric', 'min:0'],
|
||||
'min_stock_alert' => ['nullable', 'integer', 'min:0'],
|
||||
'url' => ['nullable', 'url', 'max:500'],
|
||||
'product_id' => ['nullable', 'integer', 'exists:products,id'],
|
||||
'active' => ['sometimes', 'boolean'],
|
||||
];
|
||||
}
|
||||
|
||||
protected function prepareForValidation(): void
|
||||
{
|
||||
$this->merge([
|
||||
'active' => $this->boolean('active'),
|
||||
'category' => trim((string) $this->input('category')),
|
||||
'weight_grams' => $this->filled('weight_grams') ? reFormatNumber($this->input('weight_grams')) : null,
|
||||
]);
|
||||
|
||||
foreach (['supplier_id', 'product_id', 'min_stock_alert'] as $key) {
|
||||
if ($this->input($key) === '' || $this->input($key) === null) {
|
||||
$this->merge([$key => null]);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
@ -0,0 +1,31 @@
|
|||
<?php
|
||||
|
||||
namespace App\Http\Requests\Inventory;
|
||||
|
||||
use Illuminate\Foundation\Http\FormRequest;
|
||||
|
||||
class StorePackagingMaterialRequest extends FormRequest
|
||||
{
|
||||
public function authorize(): bool
|
||||
{
|
||||
return true;
|
||||
}
|
||||
|
||||
/**
|
||||
* @return array<string, array<int, string>>
|
||||
*/
|
||||
public function rules(): array
|
||||
{
|
||||
return [
|
||||
'name' => ['required', 'string', 'max:255'],
|
||||
'pos' => ['nullable', 'integer', 'min:0', 'max:255'],
|
||||
];
|
||||
}
|
||||
|
||||
protected function prepareForValidation(): void
|
||||
{
|
||||
if ($this->has('pos') && $this->input('pos') === '') {
|
||||
$this->merge(['pos' => 0]);
|
||||
}
|
||||
}
|
||||
}
|
||||
54
app/Http/Requests/Inventory/StoreProductionRequest.php
Normal file
54
app/Http/Requests/Inventory/StoreProductionRequest.php
Normal file
|
|
@ -0,0 +1,54 @@
|
|||
<?php
|
||||
|
||||
namespace App\Http\Requests\Inventory;
|
||||
|
||||
use Illuminate\Foundation\Http\FormRequest;
|
||||
|
||||
class StoreProductionRequest extends FormRequest
|
||||
{
|
||||
public function authorize(): bool
|
||||
{
|
||||
return true;
|
||||
}
|
||||
|
||||
/**
|
||||
* @return array<string, array<int, mixed|string>>
|
||||
*/
|
||||
public function rules(): array
|
||||
{
|
||||
return [
|
||||
'product_id' => ['required', 'integer', 'exists:products,id'],
|
||||
'location_id' => ['required', 'integer', 'exists:locations,id'],
|
||||
'produced_at' => ['required', 'date'],
|
||||
'quantity' => ['required', 'integer', 'min:1'],
|
||||
'notes' => ['nullable', 'string', 'max:2000'],
|
||||
'ingredient_lines' => ['required', 'array', 'min:1'],
|
||||
'ingredient_lines.*.ingredient_id' => ['required', 'integer', 'exists:ingredients,id'],
|
||||
'ingredient_lines.*.stock_entry_id' => ['required', 'integer', 'exists:stock_entries,id'],
|
||||
'ingredient_lines.*.quantity_used' => ['required', 'string'],
|
||||
];
|
||||
}
|
||||
|
||||
/**
|
||||
* @return array<string, mixed>
|
||||
*/
|
||||
public function validatedPayload(): array
|
||||
{
|
||||
$data = $this->validated();
|
||||
|
||||
return [
|
||||
'product_id' => (int) $data['product_id'],
|
||||
'location_id' => (int) $data['location_id'],
|
||||
'produced_at' => $data['produced_at'],
|
||||
'quantity' => (int) $data['quantity'],
|
||||
'notes' => $data['notes'] ?? null,
|
||||
'ingredient_lines' => array_map(function (array $line): array {
|
||||
return [
|
||||
'ingredient_id' => (int) $line['ingredient_id'],
|
||||
'stock_entry_id' => (int) $line['stock_entry_id'],
|
||||
'quantity_used' => $line['quantity_used'],
|
||||
];
|
||||
}, $data['ingredient_lines']),
|
||||
];
|
||||
}
|
||||
}
|
||||
96
app/Http/Requests/Inventory/StoreStockEntryRequest.php
Normal file
96
app/Http/Requests/Inventory/StoreStockEntryRequest.php
Normal file
|
|
@ -0,0 +1,96 @@
|
|||
<?php
|
||||
|
||||
namespace App\Http\Requests\Inventory;
|
||||
|
||||
use Illuminate\Foundation\Http\FormRequest;
|
||||
use Illuminate\Validation\Rule;
|
||||
use Illuminate\Validation\Validator;
|
||||
|
||||
class StoreStockEntryRequest extends FormRequest
|
||||
{
|
||||
public function authorize(): bool
|
||||
{
|
||||
return true;
|
||||
}
|
||||
|
||||
/**
|
||||
* @return array<string, array<int, mixed>>
|
||||
*/
|
||||
public function rules(): array
|
||||
{
|
||||
return [
|
||||
'entry_type' => ['required', Rule::in(['ingredient', 'packaging', 'shipping'])],
|
||||
'ingredient_id' => ['nullable', 'integer', 'exists:ingredients,id'],
|
||||
'packaging_item_id' => ['nullable', 'integer', 'exists:packaging_items,id'],
|
||||
'supplier_id' => ['required', 'integer', 'exists:suppliers,id'],
|
||||
'location_id' => ['required', 'integer', 'exists:locations,id'],
|
||||
'ordered_at' => ['required', 'date'],
|
||||
'ordered_quantity' => ['required', 'numeric', 'min:0.000001'],
|
||||
'quality_id' => ['nullable', 'integer', 'exists:material_qualities,id'],
|
||||
'price_per_kg' => ['nullable', 'numeric', 'min:0'],
|
||||
'price_total' => ['nullable', 'numeric', 'min:0'],
|
||||
];
|
||||
}
|
||||
|
||||
/**
|
||||
* @return array<string, string>
|
||||
*/
|
||||
public function messages(): array
|
||||
{
|
||||
return [
|
||||
'quality_id.required' => __('Bitte eine Rohstoffqualität wählen.'),
|
||||
'price_per_kg.required' => __('Bitte den Netto-Preis pro kg angeben.'),
|
||||
'price_total.required' => __('Bitte den Gesamtpreis netto angeben.'),
|
||||
];
|
||||
}
|
||||
|
||||
protected function prepareForValidation(): void
|
||||
{
|
||||
$this->merge([
|
||||
'ordered_quantity' => reFormatNumber($this->input('ordered_quantity')),
|
||||
'price_per_kg' => $this->filled('price_per_kg') ? reFormatNumber($this->input('price_per_kg')) : null,
|
||||
'price_total' => $this->filled('price_total') ? reFormatNumber($this->input('price_total')) : null,
|
||||
]);
|
||||
}
|
||||
|
||||
public function withValidator(Validator $validator): void
|
||||
{
|
||||
$validator->after(function (Validator $validator): void {
|
||||
$type = $this->input('entry_type');
|
||||
if ($type === 'ingredient') {
|
||||
if (empty($this->input('ingredient_id'))) {
|
||||
$validator->errors()->add('ingredient_id', __('Bitte einen Inhaltsstoff wählen.'));
|
||||
}
|
||||
if (empty($this->input('quality_id'))) {
|
||||
$validator->errors()->add('quality_id', __('Bitte eine Rohstoffqualität wählen.'));
|
||||
}
|
||||
if (! is_numeric($this->input('price_per_kg')) || (float) $this->input('price_per_kg') <= 0) {
|
||||
$validator->errors()->add('price_per_kg', __('Bitte den Netto-Preis pro kg angeben.'));
|
||||
}
|
||||
} elseif (! empty($type)) {
|
||||
if (empty($this->input('packaging_item_id'))) {
|
||||
$validator->errors()->add('packaging_item_id', __('Bitte einen Verpackungsartikel wählen.'));
|
||||
}
|
||||
if (! is_numeric($this->input('price_total')) || (float) $this->input('price_total') <= 0) {
|
||||
$validator->errors()->add('price_total', __('Bitte den Gesamtpreis netto angeben.'));
|
||||
}
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
/**
|
||||
* @return array<string, mixed>
|
||||
*/
|
||||
public function validatedPayload(): array
|
||||
{
|
||||
$data = $this->validated();
|
||||
if (($data['entry_type'] ?? '') === 'ingredient') {
|
||||
$data['packaging_item_id'] = null;
|
||||
} else {
|
||||
$data['ingredient_id'] = null;
|
||||
$data['quality_id'] = null;
|
||||
}
|
||||
|
||||
return $data;
|
||||
}
|
||||
}
|
||||
31
app/Http/Requests/Inventory/StoreSupplierCategoryRequest.php
Normal file
31
app/Http/Requests/Inventory/StoreSupplierCategoryRequest.php
Normal file
|
|
@ -0,0 +1,31 @@
|
|||
<?php
|
||||
|
||||
namespace App\Http\Requests\Inventory;
|
||||
|
||||
use Illuminate\Foundation\Http\FormRequest;
|
||||
|
||||
class StoreSupplierCategoryRequest extends FormRequest
|
||||
{
|
||||
public function authorize(): bool
|
||||
{
|
||||
return true;
|
||||
}
|
||||
|
||||
/**
|
||||
* @return array<string, array<int, string>>
|
||||
*/
|
||||
public function rules(): array
|
||||
{
|
||||
return [
|
||||
'name' => ['required', 'string', 'max:255'],
|
||||
'pos' => ['nullable', 'integer', 'min:0', 'max:255'],
|
||||
];
|
||||
}
|
||||
|
||||
protected function prepareForValidation(): void
|
||||
{
|
||||
if ($this->has('pos') && $this->input('pos') === '') {
|
||||
$this->merge(['pos' => 0]);
|
||||
}
|
||||
}
|
||||
}
|
||||
39
app/Http/Requests/Inventory/StoreSupplierRequest.php
Normal file
39
app/Http/Requests/Inventory/StoreSupplierRequest.php
Normal file
|
|
@ -0,0 +1,39 @@
|
|||
<?php
|
||||
|
||||
namespace App\Http\Requests\Inventory;
|
||||
|
||||
use Illuminate\Foundation\Http\FormRequest;
|
||||
|
||||
class StoreSupplierRequest extends FormRequest
|
||||
{
|
||||
public function authorize(): bool
|
||||
{
|
||||
return true;
|
||||
}
|
||||
|
||||
/**
|
||||
* @return array<string, array<int, mixed>>
|
||||
*/
|
||||
public function rules(): array
|
||||
{
|
||||
return [
|
||||
'name' => ['required', 'string', 'max:255'],
|
||||
'url' => ['nullable', 'string', 'max:2048'],
|
||||
'contact_person' => ['nullable', 'string', 'max:255'],
|
||||
'email' => ['nullable', 'email', 'max:255'],
|
||||
'phone' => ['nullable', 'string', 'max:100'],
|
||||
'country_id' => ['required', 'integer', 'exists:countries,id'],
|
||||
'notes' => ['nullable', 'string'],
|
||||
'active' => ['sometimes', 'boolean'],
|
||||
'supplier_category_ids' => ['nullable', 'array'],
|
||||
'supplier_category_ids.*' => ['integer', 'exists:supplier_categories,id'],
|
||||
];
|
||||
}
|
||||
|
||||
protected function prepareForValidation(): void
|
||||
{
|
||||
$this->merge([
|
||||
'active' => $this->boolean('active'),
|
||||
]);
|
||||
}
|
||||
}
|
||||
31
app/Http/Requests/Inventory/UpdateLocationRequest.php
Normal file
31
app/Http/Requests/Inventory/UpdateLocationRequest.php
Normal file
|
|
@ -0,0 +1,31 @@
|
|||
<?php
|
||||
|
||||
namespace App\Http\Requests\Inventory;
|
||||
|
||||
use Illuminate\Foundation\Http\FormRequest;
|
||||
|
||||
class UpdateLocationRequest extends FormRequest
|
||||
{
|
||||
public function authorize(): bool
|
||||
{
|
||||
return true;
|
||||
}
|
||||
|
||||
/**
|
||||
* @return array<string, array<int, string>>
|
||||
*/
|
||||
public function rules(): array
|
||||
{
|
||||
return [
|
||||
'name' => ['required', 'string', 'max:255'],
|
||||
'active' => ['sometimes', 'boolean'],
|
||||
];
|
||||
}
|
||||
|
||||
protected function prepareForValidation(): void
|
||||
{
|
||||
$this->merge([
|
||||
'active' => $this->boolean('active'),
|
||||
]);
|
||||
}
|
||||
}
|
||||
31
app/Http/Requests/Inventory/UpdateMaterialQualityRequest.php
Normal file
31
app/Http/Requests/Inventory/UpdateMaterialQualityRequest.php
Normal file
|
|
@ -0,0 +1,31 @@
|
|||
<?php
|
||||
|
||||
namespace App\Http\Requests\Inventory;
|
||||
|
||||
use Illuminate\Foundation\Http\FormRequest;
|
||||
|
||||
class UpdateMaterialQualityRequest extends FormRequest
|
||||
{
|
||||
public function authorize(): bool
|
||||
{
|
||||
return true;
|
||||
}
|
||||
|
||||
/**
|
||||
* @return array<string, array<int, string>>
|
||||
*/
|
||||
public function rules(): array
|
||||
{
|
||||
return [
|
||||
'name' => ['required', 'string', 'max:255'],
|
||||
'pos' => ['nullable', 'integer', 'min:0', 'max:255'],
|
||||
];
|
||||
}
|
||||
|
||||
protected function prepareForValidation(): void
|
||||
{
|
||||
if ($this->has('pos') && $this->input('pos') === '') {
|
||||
$this->merge(['pos' => 0]);
|
||||
}
|
||||
}
|
||||
}
|
||||
47
app/Http/Requests/Inventory/UpdatePackagingItemRequest.php
Normal file
47
app/Http/Requests/Inventory/UpdatePackagingItemRequest.php
Normal file
|
|
@ -0,0 +1,47 @@
|
|||
<?php
|
||||
|
||||
namespace App\Http\Requests\Inventory;
|
||||
|
||||
use Illuminate\Foundation\Http\FormRequest;
|
||||
use Illuminate\Validation\Rule;
|
||||
|
||||
class UpdatePackagingItemRequest extends FormRequest
|
||||
{
|
||||
public function authorize(): bool
|
||||
{
|
||||
return true;
|
||||
}
|
||||
|
||||
/**
|
||||
* @return array<string, array<int, mixed>>
|
||||
*/
|
||||
public function rules(): array
|
||||
{
|
||||
return [
|
||||
'packaging_material_id' => ['required', 'integer', 'exists:packaging_materials,id'],
|
||||
'supplier_id' => ['nullable', 'integer', 'exists:suppliers,id'],
|
||||
'name' => ['required', 'string', 'max:255'],
|
||||
'category' => ['required', Rule::in(['packaging', 'shipping'])],
|
||||
'weight_grams' => ['nullable', 'numeric', 'min:0'],
|
||||
'min_stock_alert' => ['nullable', 'integer', 'min:0'],
|
||||
'url' => ['nullable', 'url', 'max:500'],
|
||||
'product_id' => ['nullable', 'integer', 'exists:products,id'],
|
||||
'active' => ['sometimes', 'boolean'],
|
||||
];
|
||||
}
|
||||
|
||||
protected function prepareForValidation(): void
|
||||
{
|
||||
$this->merge([
|
||||
'active' => $this->boolean('active'),
|
||||
'category' => trim((string) $this->input('category')),
|
||||
'weight_grams' => $this->filled('weight_grams') ? reFormatNumber($this->input('weight_grams')) : null,
|
||||
]);
|
||||
|
||||
foreach (['supplier_id', 'product_id', 'min_stock_alert'] as $key) {
|
||||
if ($this->input($key) === '' || $this->input($key) === null) {
|
||||
$this->merge([$key => null]);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
@ -0,0 +1,31 @@
|
|||
<?php
|
||||
|
||||
namespace App\Http\Requests\Inventory;
|
||||
|
||||
use Illuminate\Foundation\Http\FormRequest;
|
||||
|
||||
class UpdatePackagingMaterialRequest extends FormRequest
|
||||
{
|
||||
public function authorize(): bool
|
||||
{
|
||||
return true;
|
||||
}
|
||||
|
||||
/**
|
||||
* @return array<string, array<int, string>>
|
||||
*/
|
||||
public function rules(): array
|
||||
{
|
||||
return [
|
||||
'name' => ['required', 'string', 'max:255'],
|
||||
'pos' => ['nullable', 'integer', 'min:0', 'max:255'],
|
||||
];
|
||||
}
|
||||
|
||||
protected function prepareForValidation(): void
|
||||
{
|
||||
if ($this->has('pos') && $this->input('pos') === '') {
|
||||
$this->merge(['pos' => 0]);
|
||||
}
|
||||
}
|
||||
}
|
||||
96
app/Http/Requests/Inventory/UpdateStockEntryRequest.php
Normal file
96
app/Http/Requests/Inventory/UpdateStockEntryRequest.php
Normal file
|
|
@ -0,0 +1,96 @@
|
|||
<?php
|
||||
|
||||
namespace App\Http\Requests\Inventory;
|
||||
|
||||
use Illuminate\Foundation\Http\FormRequest;
|
||||
use Illuminate\Validation\Rule;
|
||||
use Illuminate\Validation\Validator;
|
||||
|
||||
class UpdateStockEntryRequest extends FormRequest
|
||||
{
|
||||
public function authorize(): bool
|
||||
{
|
||||
return true;
|
||||
}
|
||||
|
||||
/**
|
||||
* @return array<string, array<int, mixed>>
|
||||
*/
|
||||
public function rules(): array
|
||||
{
|
||||
return [
|
||||
'entry_type' => ['required', Rule::in(['ingredient', 'packaging', 'shipping'])],
|
||||
'ingredient_id' => ['nullable', 'integer', 'exists:ingredients,id'],
|
||||
'packaging_item_id' => ['nullable', 'integer', 'exists:packaging_items,id'],
|
||||
'supplier_id' => ['required', 'integer', 'exists:suppliers,id'],
|
||||
'location_id' => ['required', 'integer', 'exists:locations,id'],
|
||||
'ordered_at' => ['required', 'date'],
|
||||
'ordered_quantity' => ['required', 'numeric', 'min:0.000001'],
|
||||
'quality_id' => ['nullable', 'integer', 'exists:material_qualities,id'],
|
||||
'price_per_kg' => ['nullable', 'numeric', 'min:0'],
|
||||
'price_total' => ['nullable', 'numeric', 'min:0'],
|
||||
];
|
||||
}
|
||||
|
||||
/**
|
||||
* @return array<string, string>
|
||||
*/
|
||||
public function messages(): array
|
||||
{
|
||||
return [
|
||||
'quality_id.required' => __('Bitte eine Rohstoffqualität wählen.'),
|
||||
'price_per_kg.required' => __('Bitte den Netto-Preis pro kg angeben.'),
|
||||
'price_total.required' => __('Bitte den Gesamtpreis netto angeben.'),
|
||||
];
|
||||
}
|
||||
|
||||
protected function prepareForValidation(): void
|
||||
{
|
||||
$this->merge([
|
||||
'ordered_quantity' => reFormatNumber($this->input('ordered_quantity')),
|
||||
'price_per_kg' => $this->filled('price_per_kg') ? reFormatNumber($this->input('price_per_kg')) : null,
|
||||
'price_total' => $this->filled('price_total') ? reFormatNumber($this->input('price_total')) : null,
|
||||
]);
|
||||
}
|
||||
|
||||
public function withValidator(Validator $validator): void
|
||||
{
|
||||
$validator->after(function (Validator $validator): void {
|
||||
$type = $this->input('entry_type');
|
||||
if ($type === 'ingredient') {
|
||||
if (empty($this->input('ingredient_id'))) {
|
||||
$validator->errors()->add('ingredient_id', __('Bitte einen Inhaltsstoff wählen.'));
|
||||
}
|
||||
if (empty($this->input('quality_id'))) {
|
||||
$validator->errors()->add('quality_id', __('Bitte eine Rohstoffqualität wählen.'));
|
||||
}
|
||||
if (! is_numeric($this->input('price_per_kg')) || (float) $this->input('price_per_kg') <= 0) {
|
||||
$validator->errors()->add('price_per_kg', __('Bitte den Netto-Preis pro kg angeben.'));
|
||||
}
|
||||
} elseif (! empty($type)) {
|
||||
if (empty($this->input('packaging_item_id'))) {
|
||||
$validator->errors()->add('packaging_item_id', __('Bitte einen Verpackungsartikel wählen.'));
|
||||
}
|
||||
if (! is_numeric($this->input('price_total')) || (float) $this->input('price_total') <= 0) {
|
||||
$validator->errors()->add('price_total', __('Bitte den Gesamtpreis netto angeben.'));
|
||||
}
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
/**
|
||||
* @return array<string, mixed>
|
||||
*/
|
||||
public function validatedPayload(): array
|
||||
{
|
||||
$data = $this->validated();
|
||||
if (($data['entry_type'] ?? '') === 'ingredient') {
|
||||
$data['packaging_item_id'] = null;
|
||||
} else {
|
||||
$data['ingredient_id'] = null;
|
||||
$data['quality_id'] = null;
|
||||
}
|
||||
|
||||
return $data;
|
||||
}
|
||||
}
|
||||
|
|
@ -0,0 +1,31 @@
|
|||
<?php
|
||||
|
||||
namespace App\Http\Requests\Inventory;
|
||||
|
||||
use Illuminate\Foundation\Http\FormRequest;
|
||||
|
||||
class UpdateSupplierCategoryRequest extends FormRequest
|
||||
{
|
||||
public function authorize(): bool
|
||||
{
|
||||
return true;
|
||||
}
|
||||
|
||||
/**
|
||||
* @return array<string, array<int, string>>
|
||||
*/
|
||||
public function rules(): array
|
||||
{
|
||||
return [
|
||||
'name' => ['required', 'string', 'max:255'],
|
||||
'pos' => ['nullable', 'integer', 'min:0', 'max:255'],
|
||||
];
|
||||
}
|
||||
|
||||
protected function prepareForValidation(): void
|
||||
{
|
||||
if ($this->has('pos') && $this->input('pos') === '') {
|
||||
$this->merge(['pos' => 0]);
|
||||
}
|
||||
}
|
||||
}
|
||||
39
app/Http/Requests/Inventory/UpdateSupplierRequest.php
Normal file
39
app/Http/Requests/Inventory/UpdateSupplierRequest.php
Normal file
|
|
@ -0,0 +1,39 @@
|
|||
<?php
|
||||
|
||||
namespace App\Http\Requests\Inventory;
|
||||
|
||||
use Illuminate\Foundation\Http\FormRequest;
|
||||
|
||||
class UpdateSupplierRequest extends FormRequest
|
||||
{
|
||||
public function authorize(): bool
|
||||
{
|
||||
return true;
|
||||
}
|
||||
|
||||
/**
|
||||
* @return array<string, array<int, mixed>>
|
||||
*/
|
||||
public function rules(): array
|
||||
{
|
||||
return [
|
||||
'name' => ['required', 'string', 'max:255'],
|
||||
'url' => ['nullable', 'string', 'max:2048'],
|
||||
'contact_person' => ['nullable', 'string', 'max:255'],
|
||||
'email' => ['nullable', 'email', 'max:255'],
|
||||
'phone' => ['nullable', 'string', 'max:100'],
|
||||
'country_id' => ['required', 'integer', 'exists:countries,id'],
|
||||
'notes' => ['nullable', 'string'],
|
||||
'active' => ['sometimes', 'boolean'],
|
||||
'supplier_category_ids' => ['nullable', 'array'],
|
||||
'supplier_category_ids.*' => ['integer', 'exists:supplier_categories,id'],
|
||||
];
|
||||
}
|
||||
|
||||
protected function prepareForValidation(): void
|
||||
{
|
||||
$this->merge([
|
||||
'active' => $this->boolean('active'),
|
||||
]);
|
||||
}
|
||||
}
|
||||
46
app/Libraries/InvoicePDF.php
Normal file
46
app/Libraries/InvoicePDF.php
Normal file
|
|
@ -0,0 +1,46 @@
|
|||
<?php
|
||||
namespace App\Libraries;
|
||||
|
||||
use App\Libraries\CouponPDF;
|
||||
use App\Models\Coupon;
|
||||
use Storage;
|
||||
|
||||
class InvoicePDF{
|
||||
|
||||
protected $view;
|
||||
protected $pdf;
|
||||
|
||||
|
||||
public function __construct($view)
|
||||
{
|
||||
$this->view = $view;
|
||||
}
|
||||
|
||||
public function create($data, $name='test.pdf', $output='stream', $path = false){
|
||||
|
||||
header('Content-type: text/html; charset=UTF-8') ;//chrome
|
||||
//dd($data);
|
||||
|
||||
$pdf = app('dompdf.wrapper');
|
||||
$pdf->getDomPDF();
|
||||
$pdf->set_option("enable_php", true);
|
||||
$pdf->loadView($this->view, $data);
|
||||
$pdf->setPaper('A4', 'portrait');
|
||||
|
||||
if($output === 'stream'){
|
||||
return $pdf->stream($name);
|
||||
}
|
||||
if($output === 'download'){
|
||||
return $pdf->download($name);
|
||||
}
|
||||
|
||||
if($output === 'save'){
|
||||
if($path){
|
||||
$pdf->save($path.$name);
|
||||
return $path.$name;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
?>
|
||||
188
app/Libraries/MyPDFMerger.php
Normal file
188
app/Libraries/MyPDFMerger.php
Normal file
|
|
@ -0,0 +1,188 @@
|
|||
<?php
|
||||
namespace App\Libraries;
|
||||
|
||||
//use FPDI in myMerge v2
|
||||
//use FPDF;
|
||||
//use FPDI;
|
||||
|
||||
class MyPDFMerger
|
||||
{
|
||||
private $_files; //['form.pdf'] ["1,2,4, 5-19"]
|
||||
private $_fpdi;
|
||||
|
||||
|
||||
public function __construct()
|
||||
{
|
||||
/* if(!class_exists("FPDF")) {
|
||||
require_once(__DIR__.'/fpdf/fpdf.php');
|
||||
}
|
||||
if(!class_exists("FPDI")) {
|
||||
require_once(__DIR__.'/fpdi/fpdi.php');
|
||||
}*/
|
||||
}
|
||||
|
||||
public function addPDF($filepath, $pages = 'all')
|
||||
{
|
||||
if (file_exists($filepath)) {
|
||||
if (strtolower($pages) != 'all') {
|
||||
$pages = $this->_rewritepages($pages);
|
||||
}
|
||||
|
||||
$this->_files[] = array($filepath, $pages);
|
||||
} else {
|
||||
throw new \exception("Could not locate PDF on '$filepath'");
|
||||
}
|
||||
|
||||
return $this;
|
||||
}
|
||||
|
||||
|
||||
public function myMerge($outputmode = 'browser', $outputpath = 'newfile.pdf', $theme = false)
|
||||
{
|
||||
if (!isset($this->_files) || !is_array($this->_files)): throw new \exception("No PDFs to merge."); endif;
|
||||
|
||||
$fpdi = new \setasign\Fpdi\Fpdi();
|
||||
$first = 1;
|
||||
|
||||
//
|
||||
//merger operations
|
||||
foreach ($this->_files as $file) {
|
||||
$filename = $file[0];
|
||||
$filepages = $file[1];
|
||||
|
||||
|
||||
$count = $fpdi->setSourceFile($filename);
|
||||
|
||||
//add the pages
|
||||
if ($filepages == 'all') {
|
||||
for ($i = 1; $i <= $count; $i++) {
|
||||
$count = $fpdi->setSourceFile($filename);
|
||||
$template = $fpdi->importPage($i);
|
||||
$size = $fpdi->getTemplateSize($template);
|
||||
$orientation = ($size['height'] > $size['width']) ? 'P' : 'L';
|
||||
|
||||
$fpdi->AddPage($orientation, array($size['width'], $size['height']));
|
||||
if($theme){
|
||||
$fpdi->setSourceFile(__DIR__ . '/../../public/pdf/'.$theme.'-'.$first.'.pdf');
|
||||
if($first == 1){
|
||||
$first = 2;
|
||||
}
|
||||
$backId = $fpdi->importPage(1);
|
||||
$fpdi->useTemplate($backId);
|
||||
|
||||
}
|
||||
$fpdi->useTemplate($template);
|
||||
}
|
||||
} else {
|
||||
foreach ($filepages as $page) {
|
||||
$count = $fpdi->setSourceFile($filename);
|
||||
if (!$template = $fpdi->importPage($page)): throw new \exception("Could not load page '$page' in PDF '$filename'. Check that the page exists."); endif;
|
||||
$size = $fpdi->getTemplateSize($template);
|
||||
$orientation = ($size['h'] > $size['w']) ? 'P' : 'L';
|
||||
|
||||
$fpdi->AddPage($orientation, array($size['w'], $size['h']));
|
||||
if($theme){
|
||||
$fpdi->setSourceFile(__DIR__ . '/../../public/pdf/'.$theme.'-'.$first.'.pdf');
|
||||
if($first == 1){
|
||||
$first = 2;
|
||||
}
|
||||
$backId = $fpdi->importPage(1);
|
||||
$fpdi->useTemplate($backId);
|
||||
}
|
||||
|
||||
$fpdi->useTemplate($template);
|
||||
}
|
||||
}
|
||||
//after first file (invoice) on bpaper
|
||||
$slug = false;
|
||||
}
|
||||
|
||||
//output operations
|
||||
$mode = $this->_switchmode($outputmode);
|
||||
|
||||
if ($mode == 'S') {
|
||||
return $fpdi->Output($outputpath, 'S');
|
||||
} else {
|
||||
if ($fpdi->Output($outputpath, $mode) == '') {
|
||||
return true;
|
||||
} else {
|
||||
throw new \exception("Error outputting PDF to '$outputmode'.");
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
|
||||
/**
|
||||
* FPDI uses single characters for specifying the output location. Change our more descriptive string into proper format.
|
||||
* @param $mode
|
||||
* @return Character
|
||||
*/
|
||||
private function _switchmode($mode)
|
||||
{
|
||||
switch (strtolower($mode)) {
|
||||
case 'download':
|
||||
return 'D';
|
||||
break;
|
||||
case 'browser':
|
||||
return 'I';
|
||||
break;
|
||||
case 'file':
|
||||
return 'F';
|
||||
break;
|
||||
case 'string':
|
||||
return 'S';
|
||||
break;
|
||||
default:
|
||||
return 'I';
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Takes our provided pages in the form of 1,3,4,16-50 and creates an array of all pages
|
||||
* @param $pages
|
||||
* @return array
|
||||
* @throws exception
|
||||
*/
|
||||
private function _rewritepages($pages)
|
||||
{
|
||||
$pages = str_replace(' ', '', $pages);
|
||||
$part = explode(',', $pages);
|
||||
|
||||
//parse hyphens
|
||||
foreach ($part as $i) {
|
||||
$ind = explode('-', $i);
|
||||
|
||||
if (count($ind) == 2) {
|
||||
$x = $ind[0]; //start page
|
||||
$y = $ind[1]; //end page
|
||||
|
||||
if ($x > $y): throw new \exception("Starting page, '$x' is greater than ending page '$y'.");
|
||||
return false; endif;
|
||||
|
||||
//add middle pages
|
||||
while ($x <= $y): $newpages[] = (int)$x;
|
||||
$x++; endwhile;
|
||||
} else {
|
||||
$newpages[] = (int)$ind[0];
|
||||
}
|
||||
}
|
||||
|
||||
return $newpages;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
$pdf = new PDFMerger;
|
||||
|
||||
$pdf->addPDF('samplepdfs/one.pdf', '1, 3, 4')
|
||||
->addPDF('samplepdfs/two.pdf', '1-2')
|
||||
->addPDF('samplepdfs/three.pdf', 'all')
|
||||
->merge('file', 'samplepdfs/TEST2.pdf');
|
||||
|
||||
//REPLACE 'file' WITH 'browser', 'download', 'string', or 'file' for output options
|
||||
//You do not need to give a file path for browser, string, or download - just the name.
|
||||
*/
|
||||
|
|
@ -31,7 +31,11 @@ class MailCheckout extends Mailable
|
|||
$this->mode = $mode;
|
||||
|
||||
if($this->txaction === 'paid'){
|
||||
$this->subject = __('email.checkout_subject_paid')." ";
|
||||
if($this->shopping_payment->clearingtype === 'non')
|
||||
$this->subject = __('email.checkout_subject_non_paid')." ";
|
||||
else{
|
||||
$this->subject = __('email.checkout_subject_paid')." ";
|
||||
}
|
||||
}elseif($this->txaction === 'extern'){
|
||||
$this->subject = __('email.checkout_subject_extern').": ";
|
||||
$this->subject .= $shopping_order->member->account->m_first_name." ".$shopping_order->member->account->m_last_name." - ";
|
||||
|
|
@ -45,7 +49,6 @@ class MailCheckout extends Mailable
|
|||
}*/
|
||||
}
|
||||
|
||||
|
||||
public function build()
|
||||
{
|
||||
$salutation = __('email.hello').",";
|
||||
|
|
@ -64,8 +67,8 @@ class MailCheckout extends Mailable
|
|||
'greetings' => __('email.greetings'),
|
||||
'sender' => __('email.sender'),
|
||||
'send_link' => $this->send_link,
|
||||
'url' => Util::getMyMivitaUrl(),
|
||||
'button' => Util::getMyMivitaUrl(false),
|
||||
'url' => Util::getMyUrl(),
|
||||
'button' => Util::getMyUrl(false),
|
||||
'mode' => $this->mode
|
||||
]);
|
||||
}else{
|
||||
|
|
@ -82,6 +85,5 @@ class MailCheckout extends Mailable
|
|||
'mode' => $this->mode
|
||||
]);
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
63
app/Mail/MailLog.php
Normal file
63
app/Mail/MailLog.php
Normal file
|
|
@ -0,0 +1,63 @@
|
|||
<?php
|
||||
namespace App\Mail;
|
||||
|
||||
use App\User;
|
||||
use Illuminate\Bus\Queueable;
|
||||
use Illuminate\Mail\Mailable;
|
||||
use Illuminate\Queue\SerializesModels;
|
||||
use Illuminate\Contracts\Queue\ShouldQueue;
|
||||
|
||||
class MailLog extends Mailable
|
||||
{
|
||||
use Queueable, SerializesModels;
|
||||
|
||||
protected $channel;
|
||||
protected $context;
|
||||
protected $message;
|
||||
protected $data;
|
||||
|
||||
public $subject;
|
||||
|
||||
public function __construct($channel, $context, $message, $data)
|
||||
{
|
||||
$this->channel = $channel;
|
||||
$this->context = $context;
|
||||
$this->message = $message;
|
||||
$this->data = $data;
|
||||
$this->subject = 'mivita Log';
|
||||
|
||||
}
|
||||
|
||||
|
||||
public function build()
|
||||
{
|
||||
$title = 'Log: '.$this->channel.' '.$this->context;
|
||||
|
||||
//make Data readable
|
||||
$this->data = json_encode($this->data, JSON_PRETTY_PRINT);
|
||||
$content = "";
|
||||
|
||||
|
||||
$content .= "\n";
|
||||
$content .= "Channel: ".$this->channel."\n";
|
||||
$content .= "Context: ".$this->context."\n";
|
||||
if(\Auth::check()){
|
||||
$content .= "From User: ".\Auth::user()->id." | ".\Auth::user()->email."\n";
|
||||
}
|
||||
$content .= "\n";
|
||||
$content .= "Message: ".$this->message."\n";
|
||||
$content .= "\n";
|
||||
$content .= "Data: ".$this->data."\n";
|
||||
$content .= "\n";
|
||||
$content .= "\n";
|
||||
$content .= "Time: ".now()->format("d.m.Y H:i");
|
||||
$content .= "\n";
|
||||
$content .= request()->header('User-Agent');
|
||||
|
||||
|
||||
return $this->view('emails.sys')->with([
|
||||
'title' => $title,
|
||||
'content' => $content,
|
||||
]);
|
||||
}
|
||||
}
|
||||
87
app/Mail/MailLogistic.php
Normal file
87
app/Mail/MailLogistic.php
Normal file
|
|
@ -0,0 +1,87 @@
|
|||
<?php
|
||||
|
||||
namespace App\Mail;
|
||||
|
||||
use App\Models\ShoppingOrder;
|
||||
use App\Services\Invoice;
|
||||
use Illuminate\Bus\Queueable;
|
||||
use Illuminate\Mail\Mailable;
|
||||
use Illuminate\Queue\SerializesModels;
|
||||
use Storage;
|
||||
|
||||
class MailLogistic extends Mailable
|
||||
{
|
||||
use Queueable, SerializesModels;
|
||||
|
||||
protected $shopping_order;
|
||||
|
||||
public $subject;
|
||||
|
||||
public function __construct(ShoppingOrder $shopping_order)
|
||||
{
|
||||
$this->shopping_order = $shopping_order;
|
||||
$name = $shopping_order->shopping_user->billing_firstname.' '.$shopping_order->shopping_user->billing_lastname;
|
||||
$company = $shopping_order->shopping_user->billing_company ?? '';
|
||||
|
||||
$hasWhiteLabel = $shopping_order->user_white_label || $shopping_order->hasWhitelabelProducts();
|
||||
|
||||
$this->subject = 'Partner';
|
||||
if ($hasWhiteLabel) {
|
||||
// Bei allen, die ein eigenes Logo haben
|
||||
$this->subject .= ' (mit Logo)';
|
||||
} else {
|
||||
// Bei allen, die kein Tattoostudio sind
|
||||
$this->subject = ' - ';
|
||||
}
|
||||
if ($shopping_order->shopping_user->same_as_billing) {
|
||||
// Rechnungsadresse und Lieferadresse sind gleich
|
||||
$this->subject = '';
|
||||
} else {
|
||||
// hat eine andere Lieferadresse
|
||||
$this->subject = ' Lieferadresse';
|
||||
}
|
||||
$this->subject .= ' '.$company.' ('.$name.')';
|
||||
|
||||
}
|
||||
|
||||
public function build()
|
||||
{
|
||||
$title = false;
|
||||
$copy1line = false;
|
||||
|
||||
$filename = Invoice::getFilename($this->shopping_order);
|
||||
$path = Invoice::getDownloadPath($this->shopping_order);
|
||||
if (! Storage::disk('public')->exists($path)) {
|
||||
return;
|
||||
}
|
||||
$file = Storage::disk('public')->path($path);
|
||||
$mime = Storage::disk('public')->mimeType($path);
|
||||
|
||||
$mail = $this->view('emails.logistic')->with([
|
||||
'title' => $title,
|
||||
'copy1line' => $copy1line,
|
||||
])->attach($file, [
|
||||
'as' => $filename,
|
||||
'mime' => $mime,
|
||||
]);
|
||||
|
||||
// Wenn mindestens ein White-Label-Produkt enthalten ist, wird der Lieferschein (Etikett-Infos) mit angehängt
|
||||
$hasWhiteLabel = $this->shopping_order->user_white_label || $this->shopping_order->hasWhitelabelProducts();
|
||||
if ($hasWhiteLabel) {
|
||||
$filenameDelivery = Invoice::getDeliveryFilename($this->shopping_order);
|
||||
$pathDelivery = Invoice::getDownloadPathDelivery($this->shopping_order);
|
||||
if (! Storage::disk('public')->exists($pathDelivery)) {
|
||||
return;
|
||||
}
|
||||
$fileDelivery = Storage::disk('public')->path($pathDelivery);
|
||||
$mimeDelivery = Storage::disk('public')->mimeType($pathDelivery);
|
||||
|
||||
$mail->attach($fileDelivery, [
|
||||
'as' => $filenameDelivery,
|
||||
'mime' => $mimeDelivery,
|
||||
]); // attach file;
|
||||
}
|
||||
|
||||
return $mail;
|
||||
}
|
||||
}
|
||||
59
app/Mail/MailLogitic.php
Normal file
59
app/Mail/MailLogitic.php
Normal file
|
|
@ -0,0 +1,59 @@
|
|||
<?php
|
||||
namespace App\Mail;
|
||||
|
||||
use App\User;
|
||||
use App\Services\Invoice;
|
||||
use App\Models\ShoppingOrder;
|
||||
use Illuminate\Bus\Queueable;
|
||||
use Illuminate\Mail\Mailable;
|
||||
use Illuminate\Queue\SerializesModels;
|
||||
use Storage;
|
||||
use Illuminate\Contracts\Queue\ShouldQueue;
|
||||
|
||||
class MailLogistic extends Mailable
|
||||
{
|
||||
use Queueable, SerializesModels;
|
||||
|
||||
protected $shopping_order;
|
||||
|
||||
public $subject;
|
||||
|
||||
|
||||
public function __construct(ShoppingOrder $shopping_order)
|
||||
{
|
||||
$this->shopping_order = $shopping_order;
|
||||
if($shopping_order->user_white_label){
|
||||
//Bei allen, die ein eigenes Logo haben
|
||||
$this->subject = 'Partner (mit Logo) - Firma (Vorname Nachname)';
|
||||
}else{
|
||||
//Bei allen, die kein Tattoostudio sind
|
||||
$this->subject = 'Partner - Firma (Vorname Nachname)';
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
public function build()
|
||||
{
|
||||
|
||||
|
||||
$title = false;
|
||||
$copy1line = false;
|
||||
|
||||
$filename = Invoice::getFilename($this->shopping_order);
|
||||
$path = Invoice::getDownloadPath($this->shopping_order);
|
||||
if (!Storage::disk('public')->exists($path)) {
|
||||
return;
|
||||
}
|
||||
$file = Storage::disk('public')->path($path);
|
||||
$mime = Storage::disk('public')->mimeType($path);
|
||||
|
||||
|
||||
return $this->view('emails.blank')->with([
|
||||
'title' => $title,
|
||||
'copy1line' => $copy1line,
|
||||
])->attach($file,[
|
||||
'as' => $filename,
|
||||
'mime' => $mime,
|
||||
]); // attach file;
|
||||
}
|
||||
}
|
||||
|
|
@ -12,14 +12,14 @@ class MailVerifyAccount extends Mailable
|
|||
use Queueable, SerializesModels;
|
||||
|
||||
protected $confirmation_code;
|
||||
protected $user;
|
||||
protected $userObj;
|
||||
public $subject;
|
||||
|
||||
|
||||
public function __construct($confirmation_code, User $user)
|
||||
public function __construct($confirmation_code, $userObj)
|
||||
{
|
||||
$this->confirmation_code = $confirmation_code;
|
||||
$this->user = $user;
|
||||
$this->userObj = $userObj;
|
||||
$this->subject = __('email.email_verify');
|
||||
}
|
||||
|
||||
|
|
@ -27,11 +27,11 @@ class MailVerifyAccount extends Mailable
|
|||
public function build()
|
||||
{
|
||||
$salutation = __('email.salutation').",";
|
||||
if($this->user->account){
|
||||
if($this->user->account->salutation === "mr"){
|
||||
$salutation = __('email.dear_sir')." ".$this->user->account->first_name.",";
|
||||
if($this->userObj){
|
||||
if($this->userObj->salutation === "mr"){
|
||||
$salutation = __('email.dear_sir')." ".$this->userObj->first_name.",";
|
||||
}else{
|
||||
$salutation = __('email.dear_mrs')." ".$this->user->account->first_name.",";
|
||||
$salutation = __('email.dear_mrs')." ".$this->userObj->first_name.",";
|
||||
}
|
||||
}
|
||||
return $this->view('emails.auth')->with([
|
||||
|
|
|
|||
60
app/Mail/PaymentReminderEmail.php
Normal file
60
app/Mail/PaymentReminderEmail.php
Normal file
|
|
@ -0,0 +1,60 @@
|
|||
<?php
|
||||
|
||||
namespace App\Mail;
|
||||
|
||||
use Illuminate\Bus\Queueable;
|
||||
use Illuminate\Mail\Mailable;
|
||||
use Illuminate\Queue\SerializesModels;
|
||||
use Illuminate\Contracts\Queue\ShouldQueue;
|
||||
use App\Services\Util;
|
||||
|
||||
class PaymentReminderEmail extends Mailable
|
||||
{
|
||||
use Queueable, SerializesModels;
|
||||
|
||||
protected $emailSubject;
|
||||
protected $message;
|
||||
protected $order;
|
||||
|
||||
public $data;
|
||||
|
||||
/**
|
||||
* Erstellt eine neue PaymentReminderEmail Instanz
|
||||
*
|
||||
* @param string $subject
|
||||
* @param string $message
|
||||
* @param object|null $user
|
||||
* @param object|null $order
|
||||
* @param float|null $paymentAmount
|
||||
* @param string|null $dueDate
|
||||
* @param string|null $paymentUrl
|
||||
*/
|
||||
public function __construct($subject, $message, $order = null)
|
||||
{
|
||||
$this->emailSubject = $subject;
|
||||
$this->message = $message;
|
||||
$this->order = $order;
|
||||
}
|
||||
|
||||
/**
|
||||
* Baut die E-Mail
|
||||
*
|
||||
* @return $this
|
||||
*/
|
||||
public function build()
|
||||
{
|
||||
|
||||
|
||||
|
||||
$paymentUrl = route('user_myorder_detail', ['id' => $this->order->id]);
|
||||
$buttonText = __('email.my_orders') ?: 'Meine Bestellungen';
|
||||
|
||||
return $this->subject($this->emailSubject)
|
||||
->view('emails.payment_reminder')
|
||||
->with([
|
||||
'content' => $this->message,
|
||||
'url' => $paymentUrl,
|
||||
'button' => $buttonText,
|
||||
]);
|
||||
}
|
||||
}
|
||||
|
|
@ -2,6 +2,7 @@
|
|||
|
||||
namespace App\Models;
|
||||
|
||||
use App\Services\Util;
|
||||
use Illuminate\Database\Eloquent\Model;
|
||||
|
||||
/**
|
||||
|
|
@ -25,39 +26,66 @@ use Illuminate\Database\Eloquent\Model;
|
|||
* @method static \Illuminate\Database\Eloquent\Builder|\App\Models\Attribute wherePos($value)
|
||||
* @method static \Illuminate\Database\Eloquent\Builder|\App\Models\Attribute whereTransName($value)
|
||||
* @method static \Illuminate\Database\Eloquent\Builder|\App\Models\Attribute whereUpdatedAt($value)
|
||||
* @mixin \Eloquent
|
||||
* @property string|null $slug
|
||||
* @method static \Illuminate\Database\Eloquent\Builder|\App\Models\Attribute whereSlug($value)
|
||||
* @method static \Illuminate\Database\Eloquent\Builder|\App\Models\Attribute newModelQuery()
|
||||
* @method static \Illuminate\Database\Eloquent\Builder|\App\Models\Attribute newQuery()
|
||||
* @method static \Illuminate\Database\Eloquent\Builder|\App\Models\Attribute query()
|
||||
* @property-read int|null $childrens_count
|
||||
* @property int $attribute_type_id
|
||||
* @property string|null $value
|
||||
* @property-read \App\Models\AttributeType $attribute_type
|
||||
* @method static \Illuminate\Database\Eloquent\Builder|Attribute whereAttributeTypeId($value)
|
||||
* @method static \Illuminate\Database\Eloquent\Builder|Attribute whereValue($value)
|
||||
* @mixin \Eloquent
|
||||
*/
|
||||
class Attribute extends Model
|
||||
{
|
||||
protected $table = 'attributes';
|
||||
|
||||
protected $casts = ['trans_name' => 'array'];
|
||||
|
||||
protected $fillable = [
|
||||
'parent_id', 'name', 'pos', 'active',
|
||||
protected $casts = [
|
||||
'parent_id' => 'int',
|
||||
'pos' => 'int',
|
||||
'active' => 'bool',
|
||||
'trans_name' => 'array',
|
||||
];
|
||||
|
||||
|
||||
protected $fillable = [
|
||||
'parent_id',
|
||||
'attribute_type_id',
|
||||
'name',
|
||||
'value',
|
||||
'trans_name',
|
||||
'pos',
|
||||
'active',
|
||||
'slug'
|
||||
];
|
||||
|
||||
public function attribute_type()
|
||||
{
|
||||
return $this->belongsTo(AttributeType::class, 'attribute_type_id');
|
||||
}
|
||||
|
||||
public function parent()
|
||||
{
|
||||
return $this->belongsTo('App\Models\Attribute', 'parent_id');
|
||||
return $this->belongsTo(Attribute::class, 'parent_id');
|
||||
}
|
||||
|
||||
public function childrens()
|
||||
{
|
||||
return $this->hasMany('App\Models\Attribute', 'parent_id', 'id');
|
||||
return $this->hasMany(Attribute::class, 'parent_id', 'id');
|
||||
}
|
||||
|
||||
public function setPosAttribute($value){
|
||||
$this->attributes['pos'] = is_numeric($value) ? $value : null;
|
||||
|
||||
}
|
||||
|
||||
public function getFormattedValue()
|
||||
{
|
||||
// return isset($this->attributes['value']) ? Util::formatNumber($this->attributes['value']) : "";
|
||||
}
|
||||
|
||||
public function getLang($key)
|
||||
{
|
||||
$lang = \App::getLocale();
|
||||
|
|
|
|||
111
app/Models/AttributeType.php
Normal file
111
app/Models/AttributeType.php
Normal file
|
|
@ -0,0 +1,111 @@
|
|||
<?php
|
||||
|
||||
/**
|
||||
* Created by Reliese Model.
|
||||
*/
|
||||
|
||||
namespace App\Models;
|
||||
|
||||
use Carbon\Carbon;
|
||||
use Illuminate\Database\Eloquent\Collection;
|
||||
use Illuminate\Database\Eloquent\Model;
|
||||
|
||||
/**
|
||||
* Class AttributeType
|
||||
*
|
||||
* @property int $id
|
||||
* @property int|null $parent_id
|
||||
* @property string $name
|
||||
* @property string|null $trans_name
|
||||
* @property int|null $pos
|
||||
* @property bool $active
|
||||
* @property string $slug
|
||||
* @property Carbon|null $created_at
|
||||
* @property Carbon|null $updated_at
|
||||
* @property Attribute|null $attribute
|
||||
* @property Collection|Attribute[] $attributes
|
||||
* @package App\Models
|
||||
* @property string|null $description
|
||||
* @property-read Collection<int, \App\Models\Attribute> $childrens
|
||||
* @property-read int|null $childrens_count
|
||||
* @property-read \App\Models\Attribute|null $parent
|
||||
* @method static \Illuminate\Database\Eloquent\Builder|AttributeType newModelQuery()
|
||||
* @method static \Illuminate\Database\Eloquent\Builder|AttributeType newQuery()
|
||||
* @method static \Illuminate\Database\Eloquent\Builder|AttributeType query()
|
||||
* @method static \Illuminate\Database\Eloquent\Builder|AttributeType whereActive($value)
|
||||
* @method static \Illuminate\Database\Eloquent\Builder|AttributeType whereCreatedAt($value)
|
||||
* @method static \Illuminate\Database\Eloquent\Builder|AttributeType whereDescription($value)
|
||||
* @method static \Illuminate\Database\Eloquent\Builder|AttributeType whereId($value)
|
||||
* @method static \Illuminate\Database\Eloquent\Builder|AttributeType whereName($value)
|
||||
* @method static \Illuminate\Database\Eloquent\Builder|AttributeType whereParentId($value)
|
||||
* @method static \Illuminate\Database\Eloquent\Builder|AttributeType wherePos($value)
|
||||
* @method static \Illuminate\Database\Eloquent\Builder|AttributeType whereSlug($value)
|
||||
* @method static \Illuminate\Database\Eloquent\Builder|AttributeType whereTransName($value)
|
||||
* @method static \Illuminate\Database\Eloquent\Builder|AttributeType whereUpdatedAt($value)
|
||||
* @mixin \Eloquent
|
||||
*/
|
||||
class AttributeType extends Model
|
||||
{
|
||||
protected $table = 'attribute_types';
|
||||
|
||||
protected $casts = [
|
||||
'parent_id' => 'int',
|
||||
'pos' => 'int',
|
||||
'active' => 'bool',
|
||||
'trans_name' => 'array'
|
||||
];
|
||||
|
||||
protected $fillable = [
|
||||
'parent_id',
|
||||
'name',
|
||||
'description',
|
||||
'trans_name',
|
||||
'pos',
|
||||
'active',
|
||||
'slug'
|
||||
];
|
||||
|
||||
public function parent()
|
||||
{
|
||||
return $this->belongsTo(Attribute::class, 'parent_id');
|
||||
}
|
||||
|
||||
public function childrens()
|
||||
{
|
||||
return $this->hasMany(Attribute::class, 'parent_id', 'id');
|
||||
}
|
||||
|
||||
public function setPosAttribute($value){
|
||||
$this->attributes['pos'] = is_numeric($value) ? $value : null;
|
||||
}
|
||||
|
||||
public function getLang($key)
|
||||
{
|
||||
$lang = \App::getLocale();
|
||||
if ($lang == 'de') {
|
||||
return $this->{$key};
|
||||
}
|
||||
$trans = $this->getTrans($key, $lang);
|
||||
if (!$trans || $trans == '') {
|
||||
return $this->{$key};
|
||||
}
|
||||
return $trans;
|
||||
}
|
||||
|
||||
public function getTrans($key, $lang)
|
||||
{
|
||||
$key = 'trans_' . $key;
|
||||
if (!empty($this->{$key}[$lang])) {
|
||||
return $this->{$key}[$lang];
|
||||
}
|
||||
}
|
||||
|
||||
public function getTranNames()
|
||||
{
|
||||
$ret = "";
|
||||
foreach ((array) $this->trans_name as $value){
|
||||
$ret .= $value.', ';
|
||||
}
|
||||
return rtrim($ret, ', ');
|
||||
}
|
||||
}
|
||||
|
|
@ -2,6 +2,8 @@
|
|||
|
||||
namespace App\Models;
|
||||
|
||||
use App\Services\Type;
|
||||
use App\Models\Product;
|
||||
use Illuminate\Database\Eloquent\Model;
|
||||
use Cviebrock\EloquentSluggable\Sluggable;
|
||||
|
||||
|
|
@ -26,7 +28,6 @@ use Cviebrock\EloquentSluggable\Sluggable;
|
|||
* @method static \Illuminate\Database\Eloquent\Builder|\App\Models\Category wherePos($value)
|
||||
* @method static \Illuminate\Database\Eloquent\Builder|\App\Models\Category whereTransName($value)
|
||||
* @method static \Illuminate\Database\Eloquent\Builder|\App\Models\Category whereUpdatedAt($value)
|
||||
* @mixin \Eloquent
|
||||
* @property string|null $slug
|
||||
* @property-read \Illuminate\Database\Eloquent\Collection|\App\Models\ProductCategory[] $product_categories
|
||||
* @method static \Illuminate\Database\Eloquent\Builder|\App\Models\Category findSimilarSlugs($attribute, $config, $slug)
|
||||
|
|
@ -46,6 +47,9 @@ use Cviebrock\EloquentSluggable\Sluggable;
|
|||
* @property-read \App\Models\IqImage|null $iq_image
|
||||
* @property-read int|null $product_categories_count
|
||||
* @method static \Illuminate\Database\Eloquent\Builder|Category withUniqueSlugConstraints(\Illuminate\Database\Eloquent\Model $model, string $attribute, array $config, string $slug)
|
||||
* @property array|null $show_on
|
||||
* @method static \Illuminate\Database\Eloquent\Builder|Category whereShowOn($value)
|
||||
* @mixin \Eloquent
|
||||
*/
|
||||
class Category extends Model
|
||||
{
|
||||
|
|
@ -53,13 +57,13 @@ class Category extends Model
|
|||
|
||||
protected $table = 'categories';
|
||||
|
||||
protected $casts = ['trans_name' => 'array', 'trans_headline' => 'array'];
|
||||
protected $casts = ['trans_name' => 'array', 'trans_headline' => 'array', 'show_on' => 'array'];
|
||||
|
||||
protected $fillable = [
|
||||
'parent_id', 'name', 'headline', 'pos', 'active',
|
||||
'parent_id', 'name', 'headline', 'pos', 'active', 'show_on'
|
||||
];
|
||||
|
||||
public function sluggable()
|
||||
public function sluggable(): array
|
||||
{
|
||||
return [
|
||||
'slug' => [
|
||||
|
|
@ -133,4 +137,21 @@ class Category extends Model
|
|||
return rtrim($ret, ', ');
|
||||
}
|
||||
|
||||
public function getShowOnTypes($seperator = false){
|
||||
$ret = [];
|
||||
if($this->show_on && is_array($this->show_on)){
|
||||
foreach($this->show_on as $show){
|
||||
$ret[] = isset(Type::$showONs[$show]) ? Type::$showONs[$show] : '-';
|
||||
}
|
||||
}
|
||||
return $seperator ? implode($seperator, $ret) : $ret;
|
||||
}
|
||||
public function getProductsCountOn($show_on = ['8']){
|
||||
$category_id = $this->id;
|
||||
return Product::where('active', true)->whereJsonContains('show_on', $show_on)
|
||||
->whereHas('categories', function ($query) use ($category_id) {
|
||||
$query->where('category_id', $category_id); //
|
||||
})->orderBy('pos', 'ASC')->count();
|
||||
|
||||
}
|
||||
}
|
||||
|
|
|
|||
Some files were not shown because too many files have changed in this diff Show more
Loading…
Add table
Add a link
Reference in a new issue