Major incomplete Change
@@ -10,7 +10,7 @@ class ListWarehouses
|
||||
public function execute(?bool $pagination = false) {
|
||||
|
||||
// Get warehouses
|
||||
$warehouses = $pagination ? Warehouse::all() : Warehouse::orderBy('created_at')->paginate(6) ;
|
||||
$warehouses = $pagination ? Warehouse::all() : Warehouse::orderBy('created_at')->paginate(10) ;
|
||||
|
||||
// Return collection of warehouses as a resource
|
||||
return WarehouseResource::collection($warehouses);
|
||||
|
||||
@@ -0,0 +1,21 @@
|
||||
<?php
|
||||
|
||||
namespace App\Classes\Exceptions\Common;
|
||||
|
||||
use Exception;
|
||||
|
||||
class ErrorException extends Exception {
|
||||
/** @var bool */
|
||||
protected $writeExceptionToLog = true;
|
||||
|
||||
/**
|
||||
* ErrorException constructor.
|
||||
*
|
||||
* @param string $message
|
||||
* @param int $code
|
||||
*/
|
||||
public function __construct(string $message, int $code = 0) {
|
||||
parent::__construct($message, $code);
|
||||
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,14 @@
|
||||
<?php
|
||||
|
||||
namespace App\Classes\Exceptions\Common;
|
||||
|
||||
use App\Models\AbstractModel;
|
||||
use App\Traits\HandlesPrimaryKeysAsArrays;
|
||||
|
||||
class ServiceException extends ErrorException {
|
||||
use HandlesPrimaryKeysAsArrays;
|
||||
|
||||
public function __construct(string $message) {
|
||||
parent::__construct($message, class_basename($this));
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,44 @@
|
||||
<?php
|
||||
|
||||
namespace App\Classes\Modules\Accounts\DataTransferObjects;
|
||||
|
||||
|
||||
class UserInvitationObject
|
||||
{
|
||||
|
||||
/** @var integer */
|
||||
private $role;
|
||||
|
||||
/** @var string */
|
||||
private $inviteeEmail;
|
||||
|
||||
|
||||
/**
|
||||
* UserInvitationObject constructor.
|
||||
* @param int $role
|
||||
* @param string $inviteeEmail
|
||||
*/
|
||||
public function __construct(int $role, string $inviteeEmail)
|
||||
{
|
||||
$this->role = $role;
|
||||
$this->inviteeEmail = $inviteeEmail;
|
||||
}
|
||||
|
||||
/**
|
||||
* @return int
|
||||
*/
|
||||
public function getRole(): int
|
||||
{
|
||||
return $this->role;
|
||||
}
|
||||
|
||||
/**
|
||||
* @return string
|
||||
*/
|
||||
public function getInviteeEmail(): string
|
||||
{
|
||||
return $this->inviteeEmail;
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
@@ -0,0 +1,76 @@
|
||||
<?php
|
||||
|
||||
namespace App\Classes\Modules\Accounts\DataTransferObjects;
|
||||
|
||||
final class UserObject {
|
||||
/** @var string */
|
||||
private $firstName;
|
||||
|
||||
/** @var string */
|
||||
private $lastName;
|
||||
|
||||
/** @var string */
|
||||
private $email;
|
||||
|
||||
/** @var string */
|
||||
private $password;
|
||||
|
||||
/** @var bool */
|
||||
private $isVerified;
|
||||
|
||||
/**
|
||||
* @param string $firstName
|
||||
* @param string $lastName
|
||||
* @param string $email
|
||||
* @param string $password
|
||||
* @param bool $isVerified
|
||||
*/
|
||||
public function __construct(
|
||||
string $firstName,
|
||||
string $lastName,
|
||||
string $email,
|
||||
string $password,
|
||||
bool $isVerified = false
|
||||
) {
|
||||
$this->firstName = $firstName;
|
||||
$this->lastName = $lastName;
|
||||
$this->email = $email;
|
||||
$this->password = $password;
|
||||
$this->isVerified = $isVerified;
|
||||
}
|
||||
|
||||
/**
|
||||
* @return string
|
||||
*/
|
||||
public function getFirstName(): string {
|
||||
return $this->firstName;
|
||||
}
|
||||
|
||||
/**
|
||||
* @return string
|
||||
*/
|
||||
public function getLastName(): string {
|
||||
return $this->lastName;
|
||||
}
|
||||
|
||||
/**
|
||||
* @return string
|
||||
*/
|
||||
public function getEmail(): string {
|
||||
return $this->email;
|
||||
}
|
||||
|
||||
/**
|
||||
* @return string
|
||||
*/
|
||||
public function getPassword(): string {
|
||||
return $this->password;
|
||||
}
|
||||
|
||||
/**
|
||||
* @return bool
|
||||
*/
|
||||
public function isVerified(): bool {
|
||||
return $this->isVerified;
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,14 @@
|
||||
<?php
|
||||
|
||||
namespace App\Classes\Modules\Accounts\Exceptions;
|
||||
|
||||
use App\Classes\Exceptions\Common\ErrorException;
|
||||
|
||||
final class CannotCreateUserException extends ErrorException {
|
||||
/**
|
||||
* @param string $message
|
||||
*/
|
||||
public function __construct(string $message) {
|
||||
parent::__construct($message, __CLASS__);
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,63 @@
|
||||
<?php
|
||||
|
||||
namespace App\Classes\Modules\Accounts\Services;
|
||||
|
||||
use App\Classes\Exceptions\Common\ServiceException;
|
||||
use App\Models\UserEmailVerification;
|
||||
use Carbon\Carbon;
|
||||
use Illuminate\Database\Eloquent\MassAssignmentException;
|
||||
use Illuminate\Database\Eloquent\Model;
|
||||
|
||||
class CreatesEmailVerificationAttempt {
|
||||
private const EMAIL_VERIFICATION_PREFIX = 'EMAIL';
|
||||
|
||||
/** @var UserEmailVerification */
|
||||
private $repository;
|
||||
|
||||
/**
|
||||
* CreatesEmailVerificationForCustomer constructor.
|
||||
*
|
||||
* @param UserEmailVerification $repository
|
||||
*/
|
||||
public function __construct(UserEmailVerification $repository) {
|
||||
$this->repository = $repository;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param string $emailAddress
|
||||
*
|
||||
* @throws ServiceException
|
||||
*
|
||||
* @return UserEmailVerification|Model
|
||||
*/
|
||||
public function execute(string $emailAddress): UserEmailVerification {
|
||||
|
||||
// verify if the email address already has a pending verification
|
||||
$attempts = $this->repository->where('email', $emailAddress)
|
||||
->where('is_active', true)
|
||||
->where('is_complete', false);
|
||||
|
||||
|
||||
$attemptExists = count($attempts->get()) > 0 ? true : false;
|
||||
|
||||
try {
|
||||
// if a previous attempt exists, then disable any previous attempts
|
||||
if ($attemptExists === true) {
|
||||
$attempts->update(['is_active' => false, 'is_complete' => false]);
|
||||
}
|
||||
|
||||
// generate a token
|
||||
$token = md5(uniqid(self::EMAIL_VERIFICATION_PREFIX, true) . Carbon::now()->timestamp);
|
||||
|
||||
// create the email verification for the customer
|
||||
return $this->repository->create([
|
||||
'email' => $emailAddress,
|
||||
'token' => $token,
|
||||
'is_complete' => false,
|
||||
'is_active' => true,
|
||||
]);
|
||||
} catch (MassAssignmentException $exception) {
|
||||
throw new ServiceException($exception->getMessage());
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,67 @@
|
||||
<?php
|
||||
|
||||
namespace App\Classes\Modules\Accounts\Services;
|
||||
|
||||
use App\Classes\Modules\Accounts\DataTransferObjects\UserObject;
|
||||
use App\Classes\Modules\Accounts\Exceptions\CannotCreateUserException;
|
||||
use App\Classes\Modules\ControllerLogic\Exceptions\ResourceConflictException;
|
||||
use App\Models\User;
|
||||
use App\Traits\DeterminesIfUserPasswordMatchesRequirements;
|
||||
use Illuminate\Support\Facades\Hash;
|
||||
|
||||
class CreatesUserAccount {
|
||||
use DeterminesIfUserPasswordMatchesRequirements;
|
||||
|
||||
/** @var User */
|
||||
private $repository;
|
||||
|
||||
/** @var CreatesEmailVerificationAttempt */
|
||||
private $service;
|
||||
|
||||
/**
|
||||
* @param User $repository
|
||||
* @param CreatesEmailVerificationAttempt $service
|
||||
*/
|
||||
public function __construct(
|
||||
User $repository,
|
||||
CreatesEmailVerificationAttempt $service
|
||||
) {
|
||||
$this->repository = $repository;
|
||||
$this->service = $service;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param UserObject $object
|
||||
*
|
||||
* @return User
|
||||
* @throws CannotCreateUserException
|
||||
*/
|
||||
public function execute(UserObject $object): ?User {
|
||||
|
||||
try {
|
||||
|
||||
// verify if the email already exists in the database
|
||||
if($this->repository->where('email', $object->getEmail())->get()->count()){
|
||||
throw new ResourceConflictException();
|
||||
}
|
||||
|
||||
/** @var User $user */
|
||||
$user = $this->repository->create([
|
||||
'first_name' => $object->getFirstName(),
|
||||
'last_name' => $object->getLastName(),
|
||||
'email' => $object->getEmail(),
|
||||
'password' => Hash::make($object->getPassword())
|
||||
]);
|
||||
|
||||
// create an email verification attempt if needed
|
||||
if ($object->isVerified() === false) {
|
||||
$this->service->execute($object->getEmail());
|
||||
}
|
||||
|
||||
return $user;
|
||||
|
||||
} catch (\Exception $exception) {
|
||||
throw new CannotCreateUserException($exception->getMessage());
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,55 @@
|
||||
<?php
|
||||
|
||||
namespace App\Classes\Modules\Accounts\Services;
|
||||
|
||||
|
||||
use App\Classes\common;
|
||||
use App\Classes\Modules\Accounts\DataTransferObjects\UserInvitationObject;
|
||||
use App\Classes\Modules\Accounts\Exceptions\InvitationAlreadyExistsException;
|
||||
use App\Classes\Modules\ControllerLogic\Exceptions\ResourceConflictException;
|
||||
use App\Models\User;
|
||||
use App\Models\UserInvitation;
|
||||
|
||||
final class CreatesUserInvitation
|
||||
{
|
||||
|
||||
/** @var UserInvitation */
|
||||
private $repository;
|
||||
|
||||
/** @var User */
|
||||
private $user;
|
||||
|
||||
/**
|
||||
* @param UserInvitation $repository
|
||||
* @param User $user
|
||||
*/
|
||||
public function __construct(UserInvitation $repository, User $user) {
|
||||
$this->repository = $repository;
|
||||
$this->user = $user;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param UserInvitationObject $object
|
||||
* @return UserInvitation|null
|
||||
* @throws ResourceConflictException
|
||||
*/
|
||||
public function execute(UserInvitationObject $object): ?UserInvitation {
|
||||
// ensure that there is not already an invitation for the email
|
||||
$existingInvitations = $this->repository->where('email', $object->getInviteeEmail())->get();
|
||||
if ($existingInvitations->count() !== 0) {
|
||||
throw new ResourceConflictException("An existing invitation already exists for the email {$object->getInviteeEmail()}");
|
||||
}
|
||||
|
||||
$model = $this->repository->create([
|
||||
'email' => $object->getInviteeEmail(),
|
||||
'hash' => Common::generateRandomHash(50),
|
||||
'role_id' => $object->getRole(),
|
||||
'sender_id' => 1,//$this->user->getAuthIdentifier(),
|
||||
'is_complete' => false,
|
||||
]);
|
||||
|
||||
return $model;
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
@@ -0,0 +1,73 @@
|
||||
<?php
|
||||
|
||||
namespace App\Classes\Modules\ControllersLogic\Account;
|
||||
|
||||
|
||||
use App\Classes\Modules\Accounts\DataTransferObjects\UserObject;
|
||||
use App\Classes\Modules\Accounts\Exceptions\CannotCreateUserException;
|
||||
use App\Classes\Modules\Accounts\Services\CreatesUserAccount;
|
||||
use App\Classes\Modules\ControllerLogic\Exceptions\InternalServerErrorException;
|
||||
use App\Classes\Modules\ControllerLogic\Exceptions\MalformedRequestException;
|
||||
use App\Classes\ValueObjects\Constants\HttpStatus;
|
||||
use App\Events\Accounts\UserHasRegistered;
|
||||
use App\Models\User;
|
||||
use App\Traits\DeterminesIfUserPasswordMatchesRequirements;
|
||||
use Illuminate\Http\JsonResponse;
|
||||
use Illuminate\Http\Request;
|
||||
|
||||
class RegisterAccountLogic
|
||||
{
|
||||
|
||||
use DeterminesIfUserPasswordMatchesRequirements;
|
||||
|
||||
/** @var User */
|
||||
private $repository;
|
||||
|
||||
/** @var CreatesUserAccount */
|
||||
private $createsUserAccount;
|
||||
|
||||
/**
|
||||
* RegisterAccountLogic constructor.
|
||||
*
|
||||
* @param User $repository
|
||||
* @param CreatesUserAccount $createsUserAccount
|
||||
*/
|
||||
public function __construct(
|
||||
User $repository,
|
||||
CreatesUserAccount $createsUserAccount
|
||||
) {
|
||||
$this->repository = $repository;
|
||||
$this->createsUserAccount = $createsUserAccount;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param Request $request
|
||||
* @return JsonResponse
|
||||
* @throws InternalServerErrorException
|
||||
* @throws MalformedRequestException
|
||||
*/
|
||||
public function execute(Request $request) {
|
||||
|
||||
// throws malformed request exception if the password is invalid
|
||||
if ($this->checkPasswordAndThrowIfInvalid($request->get('password')) === false) {
|
||||
throw new MalformedRequestException('Password strength is insufficient');
|
||||
}
|
||||
|
||||
try {
|
||||
|
||||
// the email doesn't exist in the database, so create the user
|
||||
$object = new UserObject($request->get('first_name'), $request->get('last_name'),
|
||||
$request->get('email'), $request->get('password'), false);
|
||||
|
||||
$user = $this->createsUserAccount->execute($object);
|
||||
|
||||
// dispatch event for user registered
|
||||
event(new UserHasRegistered($user));
|
||||
|
||||
return new JsonResponse(null, HttpStatus::RESOURCE_CREATED);
|
||||
|
||||
} catch (CannotCreateUserException $exception) {
|
||||
throw new InternalServerErrorException("Failed to create user because {$exception->getMessage()}");
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,61 @@
|
||||
<?php
|
||||
|
||||
namespace App\Classes\Modules\ControllersLogic\Account;
|
||||
|
||||
|
||||
use App\Classes\Modules\Accounts\DataTransferObjects\UserInvitationObject;
|
||||
use App\Classes\Modules\Accounts\Services\CreatesUserInvitation;
|
||||
use App\Classes\Modules\ControllerLogic\Exceptions\InternalServerErrorException;
|
||||
use App\Classes\Modules\ControllerLogic\Exceptions\ResourceConflictException;
|
||||
use App\Classes\ValueObjects\Constants\HttpStatus;
|
||||
use App\Events\Accounts\UserInvited;
|
||||
use App\Models\UserInvitation;
|
||||
use Illuminate\Http\JsonResponse;
|
||||
use Illuminate\Http\Request;
|
||||
|
||||
class RegistrationInvitationLogic
|
||||
{
|
||||
|
||||
/** @var UserInvitation */
|
||||
private $repository;
|
||||
|
||||
/** @var CreatesUserInvitation */
|
||||
private $createUserInvitation;
|
||||
|
||||
/**
|
||||
* RegistrationInvitationLogic constructor.
|
||||
* @param UserInvitation $repository
|
||||
* @param CreatesUserInvitation $createUserInvitation
|
||||
*/
|
||||
public function __construct(
|
||||
UserInvitation $repository,
|
||||
CreatesUserInvitation $createUserInvitation
|
||||
) {
|
||||
$this->repository = $repository;
|
||||
$this->createUserInvitation = $createUserInvitation;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param Request $request
|
||||
* @return JsonResponse
|
||||
* @throws InternalServerErrorException
|
||||
*/
|
||||
public function execute(Request $request) {
|
||||
|
||||
try {
|
||||
|
||||
// the email doesn't exist in the database, so create the user
|
||||
$object = new UserInvitationObject($request->get('role_id'), $request->get('email'));
|
||||
|
||||
$invitation = $this->createUserInvitation->execute($object);
|
||||
|
||||
// dispatch event for user invited
|
||||
event(new UserInvited($invitation));
|
||||
|
||||
return new JsonResponse(null, HttpStatus::RESOURCE_CREATED);
|
||||
|
||||
} catch (ResourceConflictException $exception) {
|
||||
throw new InternalServerErrorException("Failed to send user invitation because {$exception->getMessage()}");
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,23 @@
|
||||
<?php
|
||||
|
||||
namespace App\Classes\ControllersLogic\Companies\AddressBook;
|
||||
|
||||
use App\Models\Company;
|
||||
use App\Http\Resources\AddressBook as AddressBookResource;
|
||||
|
||||
class DefaultAddress
|
||||
{
|
||||
public function execute( string $companyId, string $id) {
|
||||
|
||||
Company::findOrfail($companyId)->addressBook()->update(['default' => 0]);
|
||||
|
||||
$address = Company::findOrfail($companyId)->addressBook()->findOrFail($id);
|
||||
|
||||
$address->default = 1;
|
||||
|
||||
if($address->save()){
|
||||
return new AddressBookResource($address);
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,24 @@
|
||||
<?php
|
||||
|
||||
namespace App\Classes\ControllersLogic\Companies\AddressBook;
|
||||
|
||||
use App\Models\Company;
|
||||
use App\Http\Resources\AddressBook as AddressBookResource;
|
||||
|
||||
class DeleteAddress
|
||||
{
|
||||
public function execute(string $companyId, string $id) {
|
||||
|
||||
// Get address
|
||||
$address = Company::findOrfail($companyId)->addressBook()->findOrFail($id);
|
||||
|
||||
|
||||
if($address->delete()){
|
||||
|
||||
// Return single address as a resource
|
||||
return new AddressBookResource($address);
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,19 @@
|
||||
<?php
|
||||
|
||||
namespace App\Classes\ControllersLogic\Companies\AddressBook;
|
||||
|
||||
use App\Models\Company;
|
||||
use App\Http\Resources\AddressBook as AddressBookResource;
|
||||
|
||||
class ListAddresses
|
||||
{
|
||||
public function execute(string $companyId) {
|
||||
|
||||
// Get addresses
|
||||
$addresses = Company::findOrfail($companyId)->addressBook()->orderBy('created_at')->paginate(5);
|
||||
|
||||
// Return collection of addresses as a resource
|
||||
return AddressBookResource::collection($addresses);
|
||||
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,30 @@
|
||||
<?php
|
||||
|
||||
namespace App\Classes\ControllersLogic\Companies\AddressBook;
|
||||
|
||||
use App\Classes\Objects\AddressObject;
|
||||
use App\Models\AddressBook;
|
||||
use App\Models\Company;
|
||||
use App\Http\Resources\AddressBook as AddressBookResource;
|
||||
|
||||
class UpdateAddress
|
||||
{
|
||||
public function execute(AddressObject $addressObject) {
|
||||
$address = $addressObject->getId() !== null ? Company::findOrfail($addressObject->getCompanyId())->addressBook()->findOrFail($addressObject->getId()) : new AddressBook;
|
||||
|
||||
$address->company_id = $addressObject->getCompanyId();
|
||||
$address->reference = $addressObject->getReference();
|
||||
$address->contact = $addressObject->getContact();
|
||||
$address->street_one = $addressObject->getStreetOne();
|
||||
$address->street_two = $addressObject->getStreetTwo();
|
||||
$address->city = $addressObject->getCity();
|
||||
$address->state = $addressObject->getState();
|
||||
$address->post_code = $addressObject->getPostCode();
|
||||
$address->country = $addressObject->getCountry();
|
||||
|
||||
if($address->save()){
|
||||
return new AddressBookResource($address);
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,19 @@
|
||||
<?php
|
||||
|
||||
namespace App\Classes\ControllersLogic\Companies;
|
||||
|
||||
use App\Models\Company;
|
||||
use App\Http\Resources\Company as CompanyResource;
|
||||
|
||||
class CompanyProfile
|
||||
{
|
||||
public function execute(string $id) {
|
||||
|
||||
// Get company
|
||||
$company = Company::findOrFail($id);
|
||||
|
||||
// Return single company as a resource
|
||||
return new CompanyResource($company);
|
||||
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,31 @@
|
||||
<?php
|
||||
|
||||
namespace App\Classes\ControllersLogic\Companies;
|
||||
|
||||
use App\Classes\Modules\Documents\DeleteAllDocuments;
|
||||
use App\Models\Company;
|
||||
use App\Http\Resources\Company as CompanyResource;
|
||||
use App\Classes\Constants;
|
||||
|
||||
class DeleteCompany
|
||||
{
|
||||
|
||||
public function execute(string $id) {
|
||||
|
||||
// Get company
|
||||
$company = Company::findOrFail($id);
|
||||
|
||||
|
||||
foreach (Constants::COMPANY_DOCUMENTS as $documentType) {
|
||||
(new DeleteAllDocuments(Constants::MODULE_TYPES['company'], $id, $documentType))->execute();
|
||||
}
|
||||
|
||||
if($company->delete()){
|
||||
|
||||
// Return single compnay as a resource
|
||||
return new CompanyResource($company);
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,19 @@
|
||||
<?php
|
||||
|
||||
namespace App\Classes\ControllersLogic\Companies;
|
||||
|
||||
use App\Models\Company;
|
||||
use App\Http\Resources\Company as CompanyResource;
|
||||
|
||||
class ListCompanies
|
||||
{
|
||||
public function execute() {
|
||||
|
||||
// Get company
|
||||
$companies = Company::orderBy('created_at')->paginate(10);
|
||||
|
||||
// Return collection of companies as a resource
|
||||
return CompanyResource::collection($companies);
|
||||
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,45 @@
|
||||
<?php
|
||||
|
||||
namespace App\Classes\ControllersLogic\Companies;
|
||||
|
||||
use App\Classes\ControllersLogic\Companies\AddressBook\UpdateAddress;
|
||||
use App\Classes\Modules\Documents\UpdateDocuments;
|
||||
use App\Models\Company;
|
||||
use App\Http\Resources\Company as CompanyResource;
|
||||
use Illuminate\Http\Request;
|
||||
use App\Classes\Constants;
|
||||
|
||||
class UpdateCompany
|
||||
{
|
||||
public function execute(Request $request) {
|
||||
$company = $request->method() === 'PUT' ? Company::findOrFail($request->input('id')) : new company;
|
||||
$company->fill($request->except(array_merge(Constants::COMPANY_DOCUMENTS, Constants::ADDRESS_FIELDS)));
|
||||
|
||||
if($company->save()){
|
||||
|
||||
foreach (Constants::COMPANY_DOCUMENTS as $documentType){
|
||||
|
||||
$documents = $request->input($documentType);
|
||||
|
||||
if($documents !== null){
|
||||
|
||||
(new updateDocuments(
|
||||
Constants::MODULE_TYPES['company'],
|
||||
$company->id,
|
||||
$documentType))->execute($documents);
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
(new UpdateAddress())->execute($request, $company->id, false, true);
|
||||
|
||||
return new CompanyResource($company);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
public function updateDocuments(){
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
@@ -0,0 +1,24 @@
|
||||
<?php
|
||||
|
||||
namespace App\Classes\ControllersLogic\Contacts;
|
||||
|
||||
use App\Models\Contact;
|
||||
use App\Http\Resources\Contact as ContactResource;
|
||||
|
||||
class DeleteContact
|
||||
{
|
||||
public function execute(string $id) {
|
||||
|
||||
// Get address
|
||||
$contact= Contact::findOrFail($id);
|
||||
|
||||
|
||||
if($contact->delete()){
|
||||
|
||||
// Return single address as a resource
|
||||
return new ContactResource($contact);
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,19 @@
|
||||
<?php
|
||||
|
||||
namespace App\Classes\ControllersLogic\Contacts;
|
||||
|
||||
use App\Models\Contact;
|
||||
use App\Http\Resources\Contact as ContactResource;
|
||||
|
||||
class ListContacts
|
||||
{
|
||||
public function execute(int $type, string $reference) {
|
||||
|
||||
// Get contacts
|
||||
$contacts = Contact::where('type', $type)->where('reference_id', $reference)->orderBy('created_at')->paginate(5);
|
||||
|
||||
// Return collection of contacts as a resource
|
||||
return ContactResource::collection($contacts);
|
||||
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,27 @@
|
||||
<?php
|
||||
|
||||
namespace App\Classes\ControllersLogic\Contacts;
|
||||
|
||||
use App\Models\Contact;
|
||||
use App\Http\Resources\Contact as ContactResource;
|
||||
use Illuminate\Http\Request;
|
||||
|
||||
class UpdateContact
|
||||
{
|
||||
public function execute(Request $request, int $type, string $reference) {
|
||||
|
||||
$contact = $request->method() === 'PUT' ? Contact::findOrFail($request->input('id')) : new Contact;
|
||||
|
||||
$contact->type = $type;
|
||||
$contact->reference_id = $reference;
|
||||
$contact->name = $request->input('name');
|
||||
$contact->designation = $request->input('designation');
|
||||
$contact->contact = $request->input('contact');
|
||||
$contact->email = $request->input('email');
|
||||
|
||||
if($contact->save()){
|
||||
return new ContactResource($contact);
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,12 @@
|
||||
<?php
|
||||
|
||||
namespace App\Classes\Modules\ControllerLogic\Exceptions;
|
||||
|
||||
use App\Classes\ValueObjects\Constants\HttpStatus;
|
||||
|
||||
final class AccessForbiddenException extends ServiceApiException {
|
||||
public function __construct(?string $message = null) {
|
||||
parent::__construct($message ?? 'A forbidden attempt to access protected resources was detected',
|
||||
HttpStatus::ACCESS_FORBIDDEN);
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,12 @@
|
||||
<?php
|
||||
|
||||
namespace App\Classes\Modules\ControllerLogic\Exceptions;
|
||||
|
||||
use App\Classes\ValueObjects\Constants\HttpStatus;
|
||||
|
||||
final class AccessUnauthorisedException extends ServiceApiException {
|
||||
public function __construct(?string $message = null) {
|
||||
parent::__construct($message ?? 'An unauthorised attempt to access protected resources was detected',
|
||||
HttpStatus::ACCESS_UNAUTHORISED);
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,12 @@
|
||||
<?php
|
||||
|
||||
namespace App\Classes\Modules\ControllerLogic\Exceptions;
|
||||
|
||||
use App\Classes\ValueObjects\Constants\HttpStatus;
|
||||
|
||||
final class InternalServerErrorException extends ServiceApiException {
|
||||
public function __construct(?string $message = null) {
|
||||
parent::__construct($message ?? 'An internal server error has occurred. Please check application logs for more information.',
|
||||
HttpStatus::SERVER_ERROR);
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,11 @@
|
||||
<?php
|
||||
|
||||
namespace App\Classes\Modules\ControllerLogic\Exceptions;
|
||||
|
||||
use App\Classes\ValueObjects\Constants\HttpStatus;
|
||||
|
||||
final class MalformedRequestException extends ServiceApiException {
|
||||
public function __construct(?string $message = null) {
|
||||
parent::__construct($message ?? 'Unable to process the request as it is malformed', HttpStatus::BAD_REQUEST);
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,12 @@
|
||||
<?php
|
||||
|
||||
namespace App\Classes\Modules\ControllerLogic\Exceptions;
|
||||
|
||||
use App\Classes\ValueObjects\Constants\HttpStatus;
|
||||
|
||||
final class ResourceConflictException extends ServiceApiException {
|
||||
public function __construct(?string $message = null) {
|
||||
parent::__construct($message ?? 'Unable to create the requested resource as it already exists',
|
||||
HttpStatus::RESOURCE_ALREADY_EXISTS);
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,11 @@
|
||||
<?php
|
||||
|
||||
namespace App\Classes\Modules\ControllerLogic\Exceptions;
|
||||
|
||||
use App\Classes\ValueObjects\Constants\HttpStatus;
|
||||
|
||||
final class ResourceNotFoundException extends ServiceApiException {
|
||||
public function __construct(?string $message = null) {
|
||||
parent::__construct($message ?? 'Unable to find the requested resource', HttpStatus::RESOURCE_NOT_FOUND);
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,22 @@
|
||||
<?php
|
||||
|
||||
namespace App\Classes\Modules\ControllerLogic\Exceptions;
|
||||
|
||||
use App\Classes\Exceptions\Common\ErrorException;
|
||||
|
||||
abstract class ServiceApiException extends ErrorException {
|
||||
/** @var int */
|
||||
private $httpStatusCode;
|
||||
|
||||
public function __construct(string $message, int $httpStatusCode = 500) {
|
||||
parent::__construct($message, $httpStatusCode);
|
||||
$this->httpStatusCode = $httpStatusCode;
|
||||
}
|
||||
|
||||
/**
|
||||
* @return int
|
||||
*/
|
||||
public function getHttpStatusCode(): int {
|
||||
return $this->httpStatusCode;
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,36 @@
|
||||
<?php
|
||||
|
||||
namespace App\Classes\ControllersLogic\Orders;
|
||||
|
||||
|
||||
use App\Classes\Constants;
|
||||
use App\Classes\Modules\Orders\Steps\GenerateOrderSteps;
|
||||
use App\Classes\Modules\Steps\ModularStep;
|
||||
use App\Models\Order;
|
||||
use Illuminate\Http\Request;
|
||||
|
||||
class CreateOrder
|
||||
{
|
||||
public function execute(String $companyId, Request $request){
|
||||
$order = new Order;
|
||||
|
||||
$order->company_id = $companyId;
|
||||
$order->warehouse_id = $request->input('warehouse_id');
|
||||
$order->marking = $request->input('marking');
|
||||
$order->current_step = Constants::ORDER_PROCESSING_STEP;
|
||||
|
||||
if($order->save()){
|
||||
// Generate Order Steps
|
||||
$modularStep = new ModularStep();
|
||||
$orderSteps = (new GenerateOrderSteps([$modularStep->warehouseModule($order->warehouse_id !== null)]))->getSteps()->toArray();
|
||||
$order->orderSteps()->createMany($orderSteps);
|
||||
|
||||
// confirm order
|
||||
return (new UpdateOrderStep())->execute($order->id, $request);
|
||||
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
}
|
||||
@@ -0,0 +1,15 @@
|
||||
<?php
|
||||
|
||||
namespace App\Classes\ControllersLogic\Orders;
|
||||
|
||||
|
||||
use App\Classes\Modules\Orders\Steps\OrderStepUpdate;
|
||||
use Illuminate\Http\Request;
|
||||
|
||||
class UpdateOrderStep
|
||||
{
|
||||
public function execute(String $orderId, Request $request){
|
||||
return (new OrderStepUpdate($orderId))->execute($request);
|
||||
}
|
||||
|
||||
}
|
||||
@@ -0,0 +1,24 @@
|
||||
<?php
|
||||
|
||||
namespace App\Classes\ControllersLogic\Warehouses;
|
||||
|
||||
use App\Models\Warehouse;
|
||||
use App\Http\Resources\Warehouse as WarehouseResource;
|
||||
|
||||
class DeleteWarehouse
|
||||
{
|
||||
public function execute(string $id) {
|
||||
|
||||
// Get warehouse
|
||||
$warehouse = Warehouse::findOrFail($id);
|
||||
|
||||
|
||||
if($warehouse->delete()){
|
||||
|
||||
// Return single warehouse as a resource
|
||||
return new WarehouseResource($warehouse);
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,19 @@
|
||||
<?php
|
||||
|
||||
namespace App\Classes\ControllersLogic\Warehouses;
|
||||
|
||||
use App\Models\Warehouse;
|
||||
use App\Http\Resources\Warehouse as WarehouseResource;
|
||||
|
||||
class ListWarehouses
|
||||
{
|
||||
public function execute(?bool $pagination = false) {
|
||||
|
||||
// Get warehouses
|
||||
$warehouses = $pagination ? Warehouse::all() : Warehouse::orderBy('created_at')->paginate(6) ;
|
||||
|
||||
// Return collection of warehouses as a resource
|
||||
return WarehouseResource::collection($warehouses);
|
||||
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,22 @@
|
||||
<?php
|
||||
|
||||
namespace App\Classes\ControllersLogic\Warehouses;
|
||||
|
||||
use App\Models\Warehouse;
|
||||
use App\Http\Resources\Warehouse as WarehouseResource;
|
||||
use Illuminate\Http\Request;
|
||||
|
||||
class UpdateWarehouse
|
||||
{
|
||||
public function execute(Request $request) {
|
||||
$warehouse = $request->method() === 'PUT' ? Warehouse::findOrFail($request->input('id')) : new Warehouse;
|
||||
|
||||
$warehouse->fill($request->except('id'));
|
||||
|
||||
if($warehouse->save()){
|
||||
return new WarehouseResource($warehouse);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
@@ -0,0 +1,19 @@
|
||||
<?php
|
||||
|
||||
namespace App\Classes\ControllersLogic\Warehouses;
|
||||
|
||||
use App\Models\Warehouse;
|
||||
use App\Http\Resources\Warehouse as WarehouseResource;
|
||||
|
||||
class WarehouseProfile
|
||||
{
|
||||
public function execute(string $id) {
|
||||
|
||||
// Get warehouse
|
||||
$warehouse = Warehouse::findOrFail($id);
|
||||
|
||||
// Return single warehouse as a resource
|
||||
return new WarehouseResource($warehouse);
|
||||
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,29 @@
|
||||
<?php
|
||||
|
||||
namespace App\Classes\ValueObjects\Constants;
|
||||
|
||||
final class HttpStatus {
|
||||
public const OK_WITH_MESSAGE = 200;
|
||||
|
||||
public const RESOURCE_CREATED = 201;
|
||||
|
||||
public const REQUEST_ACCEPTED = 202;
|
||||
|
||||
public const OK = 204;
|
||||
|
||||
public const BAD_REQUEST = 400;
|
||||
|
||||
public const ACCESS_UNAUTHORISED = 401;
|
||||
|
||||
public const ACCESS_FORBIDDEN = 403;
|
||||
|
||||
public const RESOURCE_NOT_FOUND = 404;
|
||||
|
||||
public const METHOD_NOT_FOUND = 405;
|
||||
|
||||
public const RESOURCE_ALREADY_EXISTS = 409;
|
||||
|
||||
public const VALIDATION_FAILED = 422;
|
||||
|
||||
public const SERVER_ERROR = 500;
|
||||
}
|
||||
@@ -0,0 +1,20 @@
|
||||
<?php
|
||||
|
||||
namespace App\Classes\ValueObjects\Constants;
|
||||
|
||||
final class UserRoles {
|
||||
|
||||
public const SUPER_ADMIN = 0;
|
||||
|
||||
public const ADMIN = 1;
|
||||
|
||||
public const IMPORTER = 2;
|
||||
|
||||
public const WAREHOUSE = 3;
|
||||
|
||||
public const SUPPLIER = 4;
|
||||
|
||||
|
||||
|
||||
|
||||
}
|
||||
@@ -0,0 +1,16 @@
|
||||
<?php
|
||||
|
||||
namespace App\Classes;
|
||||
|
||||
|
||||
final class common
|
||||
{
|
||||
|
||||
/**
|
||||
* @param int $length
|
||||
* @return string
|
||||
*/
|
||||
public static function generateRandomHash(int $length = 10): string {
|
||||
return substr(bin2hex(ceil($length / 2)), 0, $length);
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,6 @@
|
||||
<?php
|
||||
|
||||
namespace App\Events\Accounts;
|
||||
|
||||
interface UserEvent {
|
||||
}
|
||||
@@ -0,0 +1,27 @@
|
||||
<?php
|
||||
|
||||
namespace App\Events\Accounts;
|
||||
|
||||
use App\Models\User;
|
||||
use Illuminate\Queue\SerializesModels;
|
||||
|
||||
class UserHasRegistered implements UserEvent {
|
||||
use SerializesModels;
|
||||
|
||||
/** @var User */
|
||||
private $user;
|
||||
|
||||
/**
|
||||
* @param User $user
|
||||
*/
|
||||
public function __construct(User $user) {
|
||||
$this->user = $user;
|
||||
}
|
||||
|
||||
/**
|
||||
* @return User
|
||||
*/
|
||||
public function getUser(): User {
|
||||
return $this->user;
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,29 @@
|
||||
<?php
|
||||
|
||||
namespace App\Events\Accounts;
|
||||
|
||||
use App\Models\UserInvitation;
|
||||
use Illuminate\Queue\SerializesModels;
|
||||
|
||||
class UserInvited implements UserEvent {
|
||||
use SerializesModels;
|
||||
|
||||
/** @var UserInvitation */
|
||||
private $invitation;
|
||||
|
||||
/**
|
||||
* @param UserInvitation $invitation
|
||||
*/
|
||||
public function __construct(UserInvitation $invitation) {
|
||||
$this->invitation = $invitation;
|
||||
}
|
||||
|
||||
/**
|
||||
* @return UserInvitation
|
||||
*/
|
||||
public function getInvitation(): UserInvitation
|
||||
{
|
||||
return $this->invitation;
|
||||
}
|
||||
|
||||
}
|
||||
@@ -1,31 +0,0 @@
|
||||
<?php
|
||||
|
||||
namespace App\Http\Controllers\Account;
|
||||
|
||||
use App\Classes\Modules\ControllerLogic\Account\RetrieveUserProfileLogic;
|
||||
use App\Classes\Modules\ControllerLogic\Account\UpdateUserProfileLogic;
|
||||
use App\Http\Controllers\Controller;
|
||||
use Illuminate\Http\Request;
|
||||
|
||||
class AccountController extends Controller
|
||||
{
|
||||
/**
|
||||
* @param int|null $id
|
||||
*
|
||||
* @return \Illuminate\Contracts\View\Factory|\Illuminate\Http\RedirectResponse|\Illuminate\View\View
|
||||
*/
|
||||
public function index(?int $id = null){
|
||||
return (new RetrieveUserProfileLogic($id))->execute();
|
||||
}
|
||||
|
||||
/**
|
||||
* @param Request $request
|
||||
*
|
||||
* @return int
|
||||
* @internal param int|null $id
|
||||
*
|
||||
*/
|
||||
public function update(Request $request): int {
|
||||
return (new UpdateUserProfileLogic($request->get('id') ?: null))->execute($request->except('id'));
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,15 @@
|
||||
<?php
|
||||
|
||||
namespace App\Http\Controllers\Account;
|
||||
|
||||
use App\Classes\Modules\ControllersLogic\Account\RegistrationInvitationLogic;
|
||||
use App\Http\Controllers\Controller;
|
||||
use Illuminate\Http\JsonResponse;
|
||||
use Illuminate\Http\Request;
|
||||
|
||||
class InviteUserController extends Controller
|
||||
{
|
||||
public function invite(Request $request, RegistrationInvitationLogic $logic): JsonResponse {
|
||||
return $logic->execute($request);
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,22 @@
|
||||
<?php
|
||||
|
||||
namespace App\Http\Controllers\Account;
|
||||
|
||||
use App\Classes\Modules\ControllersLogic\Account\RegisterAccountLogic;
|
||||
use App\Http\Controllers\Controller;
|
||||
use Illuminate\Http\JsonResponse;
|
||||
use Illuminate\Http\Request;
|
||||
|
||||
class RegisterAccountController extends Controller
|
||||
{
|
||||
/**
|
||||
* @param Request $request
|
||||
* @param RegisterAccountLogic $logic
|
||||
* @return JsonResponse
|
||||
* @throws \App\Classes\Modules\ControllerLogic\Exceptions\InternalServerErrorException
|
||||
* @throws \App\Classes\Modules\ControllerLogic\Exceptions\MalformedRequestException
|
||||
*/
|
||||
public function register(Request $request, RegisterAccountLogic $logic): JsonResponse {
|
||||
return $logic->execute($request);
|
||||
}
|
||||
}
|
||||
@@ -6,11 +6,6 @@ use Closure;
|
||||
use Illuminate\Foundation\Application;
|
||||
use Illuminate\Support\Facades\Artisan;
|
||||
|
||||
/**
|
||||
* @copyright Copyright (C) 2018 IP ServerOne Solutions Sdn. Bhd. All rights reserved.
|
||||
* @author Zhe Yang, Lee <zylee@ipserverone.com>
|
||||
* @license Proprietary
|
||||
*/
|
||||
class ClearCache {
|
||||
/** @var Application */
|
||||
private $application;
|
||||
|
||||
@@ -0,0 +1,34 @@
|
||||
<?php
|
||||
|
||||
namespace App\Listeners\Accounts;
|
||||
|
||||
use App\Events\Accounts\UserEvent;
|
||||
use App\Events\Accounts\UserHasRegistered;
|
||||
use App\Events\Accounts\UserInvited;
|
||||
use App\Models\UserEmailVerification;
|
||||
use App\Notifications\InvitationEmail;
|
||||
use App\Notifications\VerifyEmail;
|
||||
|
||||
class UserEventHandler {
|
||||
|
||||
/**
|
||||
* @param UserEvent $event
|
||||
*/
|
||||
public function handle(UserEvent $event): void {
|
||||
|
||||
if ($event instanceof UserHasRegistered) {
|
||||
$attempts = UserEmailVerification::where('email', $event->getUser()->email);
|
||||
|
||||
if ($attempts !== null && !$event->getUser()->hasVerifiedEmail()) {
|
||||
$event->getUser()->notify(new VerifyEmail($attempts->first()));
|
||||
$attempts->first()->update(['is_sent' => true]);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
if ($event instanceof UserInvited) {
|
||||
$event->getInvitation()->notify(new InvitationEmail($event));
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,11 @@
|
||||
<?php
|
||||
|
||||
namespace App\Models;
|
||||
|
||||
use Illuminate\Database\Eloquent\Model;
|
||||
use Spatie\Activitylog\Traits\LogsActivity;
|
||||
|
||||
abstract class AbstractModel extends Model {
|
||||
use LogsActivity;
|
||||
protected static $logFillable = true;
|
||||
}
|
||||
@@ -0,0 +1,11 @@
|
||||
<?php
|
||||
|
||||
namespace App\Models;
|
||||
|
||||
use Illuminate\Foundation\Auth\User as Authenticatable;
|
||||
use Spatie\Activitylog\Traits\LogsActivity;
|
||||
|
||||
abstract class AbstractUserModel extends Authenticatable {
|
||||
use LogsActivity;
|
||||
protected static $logFillable = true;
|
||||
}
|
||||
@@ -2,21 +2,14 @@
|
||||
|
||||
namespace App\models;
|
||||
|
||||
use Illuminate\Database\Eloquent\Model;
|
||||
use Spatie\Activitylog\Traits\LogsActivity;
|
||||
|
||||
class AddressBook extends Model
|
||||
class AddressBook extends AbstractModel
|
||||
{
|
||||
use LogsActivity;
|
||||
|
||||
protected $table = 'address_book';
|
||||
|
||||
protected $fillable = [
|
||||
'company_id', 'reference', 'contact', 'street_one', 'street_two', 'city', 'state', 'post_code', 'country', 'default'
|
||||
];
|
||||
|
||||
protected static $logFillable = true;
|
||||
|
||||
public function company()
|
||||
{
|
||||
return $this->belongsTo('App\Models\Company');
|
||||
|
||||
@@ -2,22 +2,15 @@
|
||||
|
||||
namespace App\Models;
|
||||
|
||||
use Illuminate\Database\Eloquent\Model;
|
||||
use Spatie\Activitylog\Traits\LogsActivity;
|
||||
|
||||
class Company extends Model
|
||||
class Company extends AbstractModel
|
||||
{
|
||||
|
||||
use LogsActivity;
|
||||
|
||||
protected $table = 'companies';
|
||||
|
||||
protected $fillable = [
|
||||
'marking', 'name', 'email', 'registration_no', 'tax_no'
|
||||
];
|
||||
|
||||
protected static $logFillable = true;
|
||||
|
||||
public function addressBook()
|
||||
{
|
||||
return $this->hasMany('App\Models\AddressBook');
|
||||
|
||||
@@ -2,13 +2,10 @@
|
||||
|
||||
namespace App\Models;
|
||||
|
||||
use Illuminate\Database\Eloquent\Model;
|
||||
use App\Classes\Constants;
|
||||
use Spatie\Activitylog\Traits\LogsActivity;
|
||||
|
||||
class Contact extends Model
|
||||
class Contact extends AbstractModel
|
||||
{
|
||||
use LogsActivity;
|
||||
|
||||
protected $table = 'contacts';
|
||||
|
||||
@@ -16,8 +13,6 @@ class Contact extends Model
|
||||
'type', 'reference_id', 'name', 'designation', 'contact', 'email'
|
||||
];
|
||||
|
||||
protected static $logFillable = true;
|
||||
|
||||
public function companyContacts($query)
|
||||
{
|
||||
return $query->where('type', Constants::MODULE_TYPES['company']);
|
||||
|
||||
@@ -2,22 +2,15 @@
|
||||
|
||||
namespace App\Models;
|
||||
|
||||
use Illuminate\Database\Eloquent\Model;
|
||||
use Spatie\Activitylog\Traits\LogsActivity;
|
||||
|
||||
class CustomIssues extends Model
|
||||
class CustomIssues extends AbstractModel
|
||||
{
|
||||
|
||||
use LogsActivity;
|
||||
|
||||
protected $table = 'custom_issues';
|
||||
|
||||
protected $fillable = [
|
||||
'schedule_id', 'remark'
|
||||
];
|
||||
|
||||
protected static $logFillable = true;
|
||||
|
||||
public function shippingSchedule()
|
||||
{
|
||||
return $this->belongsTo(ShippingSchedule::class, 'schedule_id');
|
||||
|
||||
@@ -2,19 +2,13 @@
|
||||
|
||||
namespace App\Models;
|
||||
|
||||
use Illuminate\Database\Eloquent\Model;
|
||||
use Spatie\Activitylog\Traits\LogsActivity;
|
||||
|
||||
class Document extends Model
|
||||
class Document extends AbstractModel
|
||||
{
|
||||
|
||||
use LogsActivity;
|
||||
|
||||
protected $table = 'documents';
|
||||
|
||||
protected $fillable = [
|
||||
'type', 'reference_id', 'document_type', 'name', 'primary'
|
||||
];
|
||||
|
||||
protected static $logFillable = true;
|
||||
}
|
||||
|
||||
@@ -2,21 +2,14 @@
|
||||
|
||||
namespace App\Models;
|
||||
|
||||
use Illuminate\Database\Eloquent\Model;
|
||||
use Spatie\Activitylog\Traits\LogsActivity;
|
||||
|
||||
class Order extends Model
|
||||
class Order extends AbstractModel
|
||||
{
|
||||
use LogsActivity;
|
||||
|
||||
protected $table = 'orders';
|
||||
|
||||
protected $fillable = [
|
||||
'company_id', 'marking', 'forwarder_id', 'supplier_id', 'warehouse_id', 'current_step', 'complete'
|
||||
];
|
||||
|
||||
protected static $logFillable = true;
|
||||
|
||||
public function orderSteps()
|
||||
{
|
||||
return $this->hasMany(OrderStep::class, 'order_id');
|
||||
|
||||
@@ -2,22 +2,15 @@
|
||||
|
||||
namespace App\Models;
|
||||
|
||||
use Illuminate\Database\Eloquent\Model;
|
||||
use Spatie\Activitylog\Traits\LogsActivity;
|
||||
|
||||
class OrderStep extends Model
|
||||
class OrderStep extends AbstractModel
|
||||
{
|
||||
|
||||
use LogsActivity;
|
||||
|
||||
protected $table = 'order_steps';
|
||||
|
||||
protected $fillable = [
|
||||
'order_id', 'reference_id', 'primary', 'sequence', 'complete'
|
||||
];
|
||||
|
||||
protected static $logFillable = true;
|
||||
|
||||
public function order()
|
||||
{
|
||||
return $this->belongsTo(Order::class, 'order_id');
|
||||
|
||||
@@ -2,22 +2,15 @@
|
||||
|
||||
namespace App\Models;
|
||||
|
||||
use Illuminate\Database\Eloquent\Model;
|
||||
use Spatie\Activitylog\Traits\LogsActivity;
|
||||
|
||||
class Package extends Model
|
||||
class Package extends AbstractModel
|
||||
{
|
||||
|
||||
use LogsActivity;
|
||||
|
||||
protected $table = 'packages';
|
||||
|
||||
protected $fillable = [
|
||||
'list_id', 'description', 'width', 'length', 'height', 'quantity'
|
||||
];
|
||||
|
||||
protected static $logFillable = true;
|
||||
|
||||
public function packingList()
|
||||
{
|
||||
return $this->belongsTo(PackingList::class, 'list_id');
|
||||
|
||||
@@ -2,22 +2,16 @@
|
||||
|
||||
namespace App\Models;
|
||||
|
||||
use Illuminate\Database\Eloquent\Model;
|
||||
use Spatie\Activitylog\Traits\LogsActivity;
|
||||
|
||||
class PackingList extends Model
|
||||
class PackingList extends AbstractModel
|
||||
{
|
||||
|
||||
use LogsActivity;
|
||||
|
||||
protected $table = 'packing_lists';
|
||||
|
||||
protected $fillable = [
|
||||
'order_id', 'reference_no', 'confirmed'
|
||||
];
|
||||
|
||||
protected static $logFillable = true;
|
||||
|
||||
public function packages()
|
||||
{
|
||||
return $this->hasMany(Package::class, 'list_id');
|
||||
|
||||
@@ -3,21 +3,16 @@
|
||||
namespace App\Models;
|
||||
|
||||
use Illuminate\Database\Eloquent\Model;
|
||||
use Spatie\Activitylog\Traits\LogsActivity;
|
||||
|
||||
class ReceiveNote extends Model
|
||||
{
|
||||
|
||||
use LogsActivity;
|
||||
|
||||
protected $table = 'receive_notes';
|
||||
|
||||
protected $fillable = [
|
||||
'order_id', 'tracking_no', 'receive_date'
|
||||
];
|
||||
|
||||
protected static $logFillable = true;
|
||||
|
||||
public function order()
|
||||
{
|
||||
return $this->belongsTo(Order::class, 'order_id');
|
||||
|
||||
@@ -2,22 +2,15 @@
|
||||
|
||||
namespace App\Models;
|
||||
|
||||
use Illuminate\Database\Eloquent\Model;
|
||||
use Spatie\Activitylog\Traits\LogsActivity;
|
||||
|
||||
class ShippingArrangement extends Model
|
||||
class ShippingArrangement extends AbstractModel
|
||||
{
|
||||
|
||||
use LogsActivity;
|
||||
|
||||
protected $table = 'shipping_arrangements';
|
||||
|
||||
protected $fillable = [
|
||||
'order_id', 'container_no', 'seal_no'
|
||||
];
|
||||
|
||||
protected static $logFillable = true;
|
||||
|
||||
public function shippingSchedule()
|
||||
{
|
||||
return $this->hasMany(ShippingSchedule::class, 'arrangement_id');
|
||||
|
||||
@@ -2,22 +2,16 @@
|
||||
|
||||
namespace App\Models;
|
||||
|
||||
use Illuminate\Database\Eloquent\Model;
|
||||
use Spatie\Activitylog\Traits\LogsActivity;
|
||||
|
||||
class ShippingSchedule extends Model
|
||||
class ShippingSchedule extends AbstractModel
|
||||
{
|
||||
|
||||
use LogsActivity;
|
||||
|
||||
protected $table = 'shipping_schedules';
|
||||
|
||||
protected $fillable = [
|
||||
'arrangement_id', 'ETD', 'ETA', 'status'
|
||||
];
|
||||
|
||||
protected static $logFillable = true;
|
||||
|
||||
public function shippingArrangement()
|
||||
{
|
||||
return $this->belongsTo(ShippingArrangement::class, 'arrangement_id');
|
||||
|
||||
@@ -2,15 +2,12 @@
|
||||
|
||||
namespace App\Models;
|
||||
|
||||
use Illuminate\Database\Eloquent\Relations\HasMany;
|
||||
use Illuminate\Notifications\Notifiable;
|
||||
use Illuminate\Contracts\Auth\MustVerifyEmail;
|
||||
use Illuminate\Foundation\Auth\User as Authenticatable;
|
||||
use Spatie\Activitylog\Traits\LogsActivity;
|
||||
|
||||
class User extends Authenticatable
|
||||
class User extends AbstractUserModel
|
||||
{
|
||||
use Notifiable;
|
||||
// use LogsActivity;
|
||||
|
||||
/**
|
||||
* The attributes that are mass assignable.
|
||||
@@ -18,11 +15,9 @@ class User extends Authenticatable
|
||||
* @var array
|
||||
*/
|
||||
protected $fillable = [
|
||||
'first_name', 'last_name', 'email', 'password', 'verified',
|
||||
'first_name', 'last_name', 'email', 'password', 'verified', 'role'
|
||||
];
|
||||
|
||||
// protected static $logFillable = true;
|
||||
|
||||
/**
|
||||
* The attributes that should be hidden for arrays.
|
||||
*
|
||||
@@ -31,4 +26,13 @@ class User extends Authenticatable
|
||||
protected $hidden = [
|
||||
'password', 'remember_token',
|
||||
];
|
||||
|
||||
/**
|
||||
* @return HasMany
|
||||
*/
|
||||
public function pendingEmailVerifications(): HasMany {
|
||||
return $this->hasMany(UserEmailVerification::class, 'email')
|
||||
->where('is_active', true)
|
||||
->where('is_complete', false);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -0,0 +1,31 @@
|
||||
<?php
|
||||
|
||||
namespace App\Models;
|
||||
|
||||
use Illuminate\Database\Eloquent\Relations\BelongsTo;
|
||||
|
||||
/**
|
||||
* @copyright Copyright (C) 2018 IP ServerOne Solutions Sdn. Bhd. All rights reserved.
|
||||
* @author Zhe Yang, Lee <zylee@ipserverone.com>
|
||||
* @license Proprietary
|
||||
*/
|
||||
final class UserEmailVerification extends AbstractModel {
|
||||
public $incrementing = true;
|
||||
|
||||
protected $table = 'user_email_verification';
|
||||
|
||||
protected $fillable = [
|
||||
'email',
|
||||
'token',
|
||||
'is_complete',
|
||||
'is_active',
|
||||
'is_sent'
|
||||
];
|
||||
|
||||
/**
|
||||
* @return BelongsTo
|
||||
*/
|
||||
public function user(): BelongsTo {
|
||||
return $this->belongsTo(user::class, 'email');
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,27 @@
|
||||
<?php
|
||||
|
||||
namespace App\Models;
|
||||
|
||||
|
||||
use Illuminate\Database\Eloquent\Relations\BelongsTo;
|
||||
use Illuminate\Notifications\Notifiable;
|
||||
|
||||
class UserInvitation extends AbstractModel
|
||||
{
|
||||
use Notifiable;
|
||||
|
||||
public $incrementing = true;
|
||||
|
||||
protected $table = 'user_invitation';
|
||||
|
||||
protected $fillable = [
|
||||
'email',
|
||||
'hash',
|
||||
'role_id',
|
||||
'sender_id',
|
||||
'is_complete',
|
||||
];
|
||||
|
||||
public function sender() {
|
||||
return $this->belongsTo(user::class, 'sender_id');
|
||||
}}
|
||||
@@ -2,19 +2,13 @@
|
||||
|
||||
namespace App\Models;
|
||||
|
||||
use Illuminate\Database\Eloquent\Model;
|
||||
use Spatie\Activitylog\Traits\LogsActivity;
|
||||
|
||||
class Warehouse extends Model
|
||||
class Warehouse extends AbstractModel
|
||||
{
|
||||
|
||||
use LogsActivity;
|
||||
|
||||
protected $table = 'warehouses';
|
||||
|
||||
protected $fillable = [
|
||||
'name', 'email', 'street_one', 'street_two', 'city', 'state', 'post_code', 'country'
|
||||
];
|
||||
|
||||
protected static $logFillable = true;
|
||||
}
|
||||
|
||||
@@ -0,0 +1,15 @@
|
||||
<?php
|
||||
|
||||
namespace App\Notifications;
|
||||
|
||||
use Illuminate\Notifications\Notification;
|
||||
|
||||
class AbstractEmail extends Notification
|
||||
{
|
||||
|
||||
public function via()
|
||||
{
|
||||
return 'mail';
|
||||
}
|
||||
|
||||
}
|
||||
@@ -0,0 +1,40 @@
|
||||
<?php
|
||||
|
||||
namespace App\Notifications;
|
||||
|
||||
|
||||
use App\Events\Accounts\UserInvited;
|
||||
use Illuminate\Notifications\Messages\MailMessage;
|
||||
|
||||
class InvitationEmail extends AbstractEmail
|
||||
{
|
||||
|
||||
/** @var UserInvited */
|
||||
private $invitation;
|
||||
|
||||
/**
|
||||
* InvitationEmail constructor.
|
||||
* @param UserInvited $invitationt
|
||||
*/
|
||||
public function __construct(UserInvited $invitation) {
|
||||
$this->invitation = $invitation;
|
||||
}
|
||||
|
||||
public function toMail()
|
||||
{
|
||||
return (new MailMessage)
|
||||
->subject('Registration Invite')
|
||||
->line($this->senderName().' has sent you an invitation to create an account with us.')
|
||||
->action('Create Account', $this->invitationUrl());
|
||||
}
|
||||
|
||||
private function invitationUrl(){
|
||||
return url(route('auth.registration', ['hash' => $this->invitation->getInvitation()->hash]));
|
||||
}
|
||||
|
||||
private function senderName(){
|
||||
$sender = $this->invitation->getInvitation()->sender;
|
||||
return $sender->first_name.' '.$sender->last_name;
|
||||
}
|
||||
|
||||
}
|
||||
@@ -0,0 +1,38 @@
|
||||
<?php
|
||||
|
||||
namespace App\Notifications;
|
||||
|
||||
|
||||
use App\Models\UserEmailVerification;
|
||||
use Illuminate\Notifications\Messages\MailMessage;
|
||||
|
||||
class VerifyEmail extends AbstractEmail
|
||||
{
|
||||
|
||||
/** @var UserEmailVerification */
|
||||
private $attempt;
|
||||
|
||||
/**
|
||||
* EmailVerificationRequest constructor.
|
||||
*
|
||||
* @param UserEmailVerification $attempt
|
||||
*/
|
||||
public function __construct(UserEmailVerification $attempt) {
|
||||
$this->attempt = $attempt;
|
||||
}
|
||||
|
||||
public function toMail()
|
||||
{
|
||||
return (new MailMessage)
|
||||
->subject('Email Verification Required')
|
||||
->line('Please click the button below to verify your email address.')
|
||||
->action('Verify Email Address', $this->verificationUrl()
|
||||
)
|
||||
->line('If you did not create an account, no further action is required.');
|
||||
}
|
||||
|
||||
private function verificationUrl(){
|
||||
return $this->attempt->token;
|
||||
}
|
||||
|
||||
}
|
||||
@@ -2,33 +2,14 @@
|
||||
|
||||
namespace App\Providers;
|
||||
|
||||
use Illuminate\Support\Facades\Event;
|
||||
use Illuminate\Auth\Events\Registered;
|
||||
use Illuminate\Auth\Listeners\SendEmailVerificationNotification;
|
||||
use App\Events\Accounts\UserEvent;
|
||||
use App\Listeners\Accounts\UserEventHandler;
|
||||
use Illuminate\Foundation\Support\Providers\EventServiceProvider as ServiceProvider;
|
||||
|
||||
class EventServiceProvider extends ServiceProvider
|
||||
{
|
||||
/**
|
||||
* The event listener mappings for the application.
|
||||
*
|
||||
* @var array
|
||||
*/
|
||||
/** @var array */
|
||||
protected $listen = [
|
||||
Registered::class => [
|
||||
SendEmailVerificationNotification::class,
|
||||
],
|
||||
UserEvent::class => [UserEventHandler::class]
|
||||
];
|
||||
|
||||
/**
|
||||
* Register any events for your application.
|
||||
*
|
||||
* @return void
|
||||
*/
|
||||
public function boot()
|
||||
{
|
||||
parent::boot();
|
||||
|
||||
//
|
||||
}
|
||||
}
|
||||
|
||||
@@ -0,0 +1,27 @@
|
||||
<?php
|
||||
|
||||
namespace App\Traits;
|
||||
|
||||
trait DeterminesIfUserPasswordMatchesRequirements {
|
||||
/**
|
||||
* @param string $password
|
||||
*
|
||||
* @return bool
|
||||
*/
|
||||
private function doesPasswordMeetRequirements(string $password): bool {
|
||||
$matches = [];
|
||||
|
||||
preg_match('/^.*(?=.{3,})(?=.*[a-z])(?=.*[A-Z])(?=.*[\d]).*$/', $password, $matches);
|
||||
|
||||
return count($matches) > 0;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param string $password
|
||||
*
|
||||
* @return bool
|
||||
*/
|
||||
private function checkPasswordAndThrowIfInvalid(string $password): bool {
|
||||
return $this->doesPasswordMeetRequirements($password) === true;
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,27 @@
|
||||
<?php
|
||||
|
||||
namespace App\Traits;
|
||||
|
||||
use Illuminate\Database\Eloquent\Model;
|
||||
|
||||
trait HandlesPrimaryKeysAsArrays {
|
||||
/**
|
||||
* @param Model $model
|
||||
*
|
||||
* @return array
|
||||
*/
|
||||
private function getPrimaryKeys(Model $model): array {
|
||||
return (array) $model->getKeyName();
|
||||
}
|
||||
|
||||
/**
|
||||
* @param Model $model
|
||||
*
|
||||
* @return string
|
||||
*/
|
||||
private function getPrimaryKeyValuesAsString(Model $model): string {
|
||||
return implode(', ', array_map(function ($keyName) use ($model) {
|
||||
return $model->getAttribute($keyName);
|
||||
}, $this->getPrimaryKeys($model)));
|
||||
}
|
||||
}
|
||||
@@ -8,11 +8,6 @@ $factory->define(App\Models\Company::class, function (Faker $faker) {
|
||||
'marking' => 'CIEF/'.$faker->numerify('###').$faker->regexify('[A-Z]{3}'),
|
||||
'email' => $faker->companyEmail,
|
||||
'registration_no' => $faker->numerify('######-W'),
|
||||
'tax_no' => $faker->numerify('KMTAX####'),
|
||||
'street_one' => $faker->streetAddress,
|
||||
'city' => $faker->city,
|
||||
'state' => $faker->city,
|
||||
'post_code' => $faker->postcode,
|
||||
'country' => $faker->country
|
||||
'tax_no' => $faker->numerify('KMTAX####')
|
||||
];
|
||||
});
|
||||
|
||||
@@ -1,5 +1,6 @@
|
||||
<?php
|
||||
|
||||
use App\Classes\ValueObjects\Constants\UserRoles;
|
||||
use Illuminate\Support\Facades\DB;
|
||||
use Illuminate\Support\Facades\Hash;
|
||||
use Illuminate\Support\Facades\Schema;
|
||||
@@ -24,17 +25,29 @@ class CreateUserTable extends Migration
|
||||
$table->string('email')->unique();
|
||||
$table->string('password');
|
||||
$table->integer('verified')->nullable()->default(0);
|
||||
$table->integer('role_id');
|
||||
$table->rememberToken();
|
||||
$table->timestamps();
|
||||
});
|
||||
|
||||
DB::table('users')->insert(
|
||||
[
|
||||
'first_name' => $faker->firstName,
|
||||
'last_name' => $faker->lastName,
|
||||
'email' => env('EMAIL_DEVELOPMENT', 'admin@cief.com'),
|
||||
'first_name' => 'Omair',
|
||||
'last_name' => 'Saleh',
|
||||
'email' => env('EMAIL_DEVELOPMENT', 'omair@izyim.com'),
|
||||
'password' => Hash::make('123456abcabc'),
|
||||
'verified' => 1,
|
||||
'role_id' => UserRoles::SUPER_ADMIN,
|
||||
'created_at' => \Carbon\Carbon::now(),
|
||||
'updated_at' => \Carbon\Carbon::now()
|
||||
],
|
||||
[
|
||||
'first_name' => 'Development',
|
||||
'last_name' => 'User',
|
||||
'email' => env('EMAIL_DEVELOPMENT', 'dev@izyim.com'),
|
||||
'password' => Hash::make('123456abcabc'),
|
||||
'verified' => 1,
|
||||
'role_id' => UserRoles::ADMIN,
|
||||
'created_at' => \Carbon\Carbon::now(),
|
||||
'updated_at' => \Carbon\Carbon::now()
|
||||
]
|
||||
|
||||
@@ -0,0 +1,38 @@
|
||||
<?php
|
||||
|
||||
use Illuminate\Support\Facades\Schema;
|
||||
use Illuminate\Database\Schema\Blueprint;
|
||||
use Illuminate\Database\Migrations\Migration;
|
||||
|
||||
class CreateUserEmailVerificationTable extends Migration
|
||||
{
|
||||
/**
|
||||
* Run the migrations.
|
||||
*
|
||||
* @return void
|
||||
*/
|
||||
public function up()
|
||||
{
|
||||
Schema::create('user_email_verification', function (Blueprint $table) {
|
||||
$table->increments('id');
|
||||
$table->string('email', 100);
|
||||
$table->string('token', 32);
|
||||
$table->boolean('is_complete')->default(false);
|
||||
$table->boolean('is_active');
|
||||
$table->boolean('is_sent')->default(false);
|
||||
$table->timestamps();
|
||||
|
||||
$table->foreign('email')->references('email')->on('users');
|
||||
});
|
||||
}
|
||||
|
||||
/**
|
||||
* Reverse the migrations.
|
||||
*
|
||||
* @return void
|
||||
*/
|
||||
public function down()
|
||||
{
|
||||
Schema::dropIfExists('user_email_verification');
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,38 @@
|
||||
<?php
|
||||
|
||||
use Illuminate\Support\Facades\Schema;
|
||||
use Illuminate\Database\Schema\Blueprint;
|
||||
use Illuminate\Database\Migrations\Migration;
|
||||
|
||||
class CreateUserInvitationTable extends Migration
|
||||
{
|
||||
/**
|
||||
* Run the migrations.
|
||||
*
|
||||
* @return void
|
||||
*/
|
||||
public function up()
|
||||
{
|
||||
Schema::create('user_invitation', function (Blueprint $table) {
|
||||
$table->increments('id');
|
||||
$table->string('email', 100)->unique();
|
||||
$table->string('hash', 50);
|
||||
$table->integer('role_id');
|
||||
$table->integer('sender_id')->unsigned()->index();
|
||||
$table->boolean('is_complete')->default(false);
|
||||
$table->timestamps();
|
||||
|
||||
$table->foreign('sender_id')->references('id')->on('users');
|
||||
});
|
||||
}
|
||||
|
||||
/**
|
||||
* Reverse the migrations.
|
||||
*
|
||||
* @return void
|
||||
*/
|
||||
public function down()
|
||||
{
|
||||
Schema::dropIfExists('user_invitation');
|
||||
}
|
||||
}
|
||||
@@ -11,10 +11,10 @@ class DatabaseSeeder extends Seeder
|
||||
*/
|
||||
public function run(): void {
|
||||
if(app()->environment() !== "production"){
|
||||
//$this->call(CompaniesTableSeeder::class);
|
||||
//$this->call(AddressBookTableSeeder::class);
|
||||
//$this->call(ContactsTableSeeder::class);
|
||||
//$this->call(WarehousesTableSeeder::class);
|
||||
$this->call(CompaniesTableSeeder::class);
|
||||
$this->call(AddressBookTableSeeder::class);
|
||||
$this->call(ContactsTableSeeder::class);
|
||||
$this->call(WarehousesTableSeeder::class);
|
||||
}
|
||||
|
||||
$this->call(PrimaryStepsTableSeeder::class);
|
||||
|
||||
@@ -20,7 +20,6 @@
|
||||
"desandro-classie": "^1.0.1",
|
||||
"dialog-fx": "^0.0.2",
|
||||
"epic-spinners": "^1.0.3",
|
||||
"feather-icons": "^4.5.0",
|
||||
"font-awesome": "^4.7.0",
|
||||
"gulp-cli": "^2.0.1",
|
||||
"imagesloaded": "^4.1.4",
|
||||
@@ -39,7 +38,6 @@
|
||||
"select2": "^4.0.6-rc.1",
|
||||
"sweetalert": "^2.1.0",
|
||||
"switchery-npm": "^0.8.2",
|
||||
"tether": "^1.4.3",
|
||||
"trumbowyg": "^2.9.4",
|
||||
"twitter-bootstrap-wizard": "^1.2.0",
|
||||
"typeahead.js": "^0.11.1",
|
||||
@@ -88,8 +86,6 @@
|
||||
"vendorJs": [
|
||||
"./node_modules/jquery/dist/jquery.min.js",
|
||||
"./node_modules/jquery-ui-dist/jquery-ui.min.js",
|
||||
"./node_modules/feather-icons/dist/feather.min.js",
|
||||
"./node_modules/tether/dist/js/tether.min.js",
|
||||
"./node_modules/popper.js/dist/umd/popper.min.js",
|
||||
"./node_modules/bootstrap/dist/js/bootstrap.min.js",
|
||||
"./node_modules/jquery-unveil/jquery.unveil.js",
|
||||
|
||||
|
Before Width: | Height: | Size: 434 KiB |
|
Before Width: | Height: | Size: 89 KiB |
|
Before Width: | Height: | Size: 85 KiB |
|
Before Width: | Height: | Size: 7.7 KiB |
|
Before Width: | Height: | Size: 63 KiB |
|
Before Width: | Height: | Size: 2.9 MiB |
|
Before Width: | Height: | Size: 29 KiB |
|
Before Width: | Height: | Size: 29 KiB |
|
Before Width: | Height: | Size: 6.8 KiB |
|
Before Width: | Height: | Size: 6.9 KiB |