diff --git a/app/Http/Controllers/DesignController.php b/app/Http/Controllers/DesignController.php index 088dcd277e..b9205d1776 100644 --- a/app/Http/Controllers/DesignController.php +++ b/app/Http/Controllers/DesignController.php @@ -31,7 +31,6 @@ use Illuminate\Support\Facades\Cache; /** * Class DesignController * @package App\Http\Controllers - * @covers App\Http\Controllers\DesignController */ class DesignController extends BaseController { @@ -480,15 +479,11 @@ class DesignController extends BaseController $action = request()->input('action'); $ids = request()->input('ids'); + $designs = Design::withTrashed()->find($this->transformKeys($ids)); - info($designs); - info(auth()->user()->id); - info(auth()->user()->getCompany()->id); - $designs->each(function ($design, $key) use ($action) { if (auth()->user()->can('edit', $design)) { - info("authed"); $this->design_repo->{$action}($design); } }); diff --git a/app/Http/Controllers/DocumentController.php b/app/Http/Controllers/DocumentController.php new file mode 100644 index 0000000000..3d71de8503 --- /dev/null +++ b/app/Http/Controllers/DocumentController.php @@ -0,0 +1,89 @@ +json([], 200); } + + /** + * Perform bulk actions on the list view + * + * @return Collection + * + * @OA\Post( + * path="/api/v1/group_settings/bulk", + * operationId="bulkGroupSettings", + * tags={"group_settings"}, + * summary="Performs bulk actions on an array of group_settings", + * description="", + * @OA\Parameter(ref="#/components/parameters/X-Api-Secret"), + * @OA\Parameter(ref="#/components/parameters/X-Api-Token"), + * @OA\Parameter(ref="#/components/parameters/X-Requested-With"), + * @OA\Parameter(ref="#/components/parameters/index"), + * @OA\RequestBody( + * description="An array of group_settings ids", + * required=true, + * @OA\MediaType( + * mediaType="application/json", + * @OA\Schema( + * type="array", + * @OA\Items( + * type="integer", + * description="Array of hashed IDs to be bulk 'actioned", + * example="[0,1,2,3]", + * ), + * ) + * ) + * ), + * @OA\Response( + * response=200, + * description="The Bulk Action response", + * @OA\Header(header="X-MINIMUM-CLIENT-VERSION", ref="#/components/headers/X-MINIMUM-CLIENT-VERSION"), + * @OA\Header(header="X-RateLimit-Remaining", ref="#/components/headers/X-RateLimit-Remaining"), + * @OA\Header(header="X-RateLimit-Limit", ref="#/components/headers/X-RateLimit-Limit"), + * ), + * @OA\Response( + * response=422, + * description="Validation error", + * @OA\JsonContent(ref="#/components/schemas/ValidationError"), + + * ), + * @OA\Response( + * response="default", + * description="Unexpected Error", + * @OA\JsonContent(ref="#/components/schemas/Error"), + * ), + * ) + * + */ + public function bulk() + { + + $action = request()->input('action'); + + $ids = request()->input('ids'); + + $group_settings = GroupSetting::withTrashed()->whereIn('id', $this->transformKeys($ids))->company()->get(); + + if (!$group_settings) { + return response()->json(['message' => 'No Group Settings Found']); + } + + /* + * Send the other actions to the switch + */ + $group_settings->each(function ($group, $key) use ($action) { + if (auth()->user()->can('edit', $group)) { + $this->group_setting_repo->{$action}($group); + } + }); + + /* Need to understand which permission are required for the given bulk action ie. view / edit */ + + return $this->listResponse(GroupSetting::withTrashed()->whereIn('id', $this->transformKeys($ids))->company()); + } } diff --git a/app/Http/Requests/Document/CreateDocumentRequest.php b/app/Http/Requests/Document/CreateDocumentRequest.php new file mode 100644 index 0000000000..8ced17f27f --- /dev/null +++ b/app/Http/Requests/Document/CreateDocumentRequest.php @@ -0,0 +1,29 @@ +user()->can('create', Document::class); + } +} diff --git a/app/Http/Requests/Document/DestroyDocumentRequest.php b/app/Http/Requests/Document/DestroyDocumentRequest.php new file mode 100644 index 0000000000..ace9272657 --- /dev/null +++ b/app/Http/Requests/Document/DestroyDocumentRequest.php @@ -0,0 +1,28 @@ +user()->can('edit', $this->document); + } +} diff --git a/app/Http/Requests/Document/EditDocumentRequest.php b/app/Http/Requests/Document/EditDocumentRequest.php new file mode 100644 index 0000000000..829a8965b8 --- /dev/null +++ b/app/Http/Requests/Document/EditDocumentRequest.php @@ -0,0 +1,39 @@ +user()->can('edit', $this->document); + } + + /** + * Get the validation rules that apply to the request. + * + * @return array + */ + public function rules() + { + return [ + // + ]; + } +} diff --git a/app/Http/Requests/Document/ShowDocumentRequest.php b/app/Http/Requests/Document/ShowDocumentRequest.php new file mode 100644 index 0000000000..5be9f7b248 --- /dev/null +++ b/app/Http/Requests/Document/ShowDocumentRequest.php @@ -0,0 +1,39 @@ +user()->can('view', $this->document); + } + + /** + * Get the validation rules that apply to the request. + * + * @return array + */ + public function rules() + { + return [ + // + ]; + } +} diff --git a/app/Http/Requests/Document/StoreDocumentRequest.php b/app/Http/Requests/Document/StoreDocumentRequest.php new file mode 100644 index 0000000000..daaac114c6 --- /dev/null +++ b/app/Http/Requests/Document/StoreDocumentRequest.php @@ -0,0 +1,43 @@ +user()->can('create', Document::class); + } + + public function rules() + { + return [ + ]; + } + + protected function prepareForValidation() + { + $input = $this->all(); + + + $this->replace($input); + } +} diff --git a/app/Http/Requests/Document/UpdateDocumentRequest.php b/app/Http/Requests/Document/UpdateDocumentRequest.php new file mode 100644 index 0000000000..e707791a54 --- /dev/null +++ b/app/Http/Requests/Document/UpdateDocumentRequest.php @@ -0,0 +1,44 @@ +user()->can('edit', $this->document); + } + + public function rules() + { + return []; + } + + protected function prepareForValidation() + { + $input = $this->all(); + + $this->replace($input); + } +} diff --git a/app/Models/Activity.php b/app/Models/Activity.php index b8dd595800..a2f6487cb6 100644 --- a/app/Models/Activity.php +++ b/app/Models/Activity.php @@ -25,11 +25,11 @@ class Activity extends StaticModel const ARCHIVE_INVOICE=8; const DELETE_INVOICE=9; const CREATE_PAYMENT=10; - //const UPDATE_PAYMENT=11; + const UPDATE_PAYMENT=11; const ARCHIVE_PAYMENT=12; const DELETE_PAYMENT=13; const CREATE_CREDIT=14; - //const UPDATE_CREDIT=15; + const UPDATE_CREDIT=15; const ARCHIVE_CREDIT=16; const DELETE_CREDIT=17; const CREATE_QUOTE=18; diff --git a/app/Models/Company.php b/app/Models/Company.php index 4194cd8272..8185da8693 100644 --- a/app/Models/Company.php +++ b/app/Models/Company.php @@ -72,6 +72,7 @@ class Company extends BaseModel ]; protected $fillable = [ + 'enabled_item_tax_rates', 'fill_products', 'industry_id', 'subdomain', @@ -192,7 +193,7 @@ class Company extends BaseModel public function activities() { - return $this->hasMany(Activity::class); + return $this->hasMany(Activity::class)->orderBy('id', 'DESC')->take(300); } /** diff --git a/app/PaymentDrivers/AbstractPaymentDriver.php b/app/PaymentDrivers/AbstractPaymentDriver.php index dcfb815583..8b583ad1ae 100644 --- a/app/PaymentDrivers/AbstractPaymentDriver.php +++ b/app/PaymentDrivers/AbstractPaymentDriver.php @@ -11,6 +11,8 @@ namespace App\PaymentDrivers; +use App\Models\Payment; + abstract class AbstractPaymentDriver { @@ -18,7 +20,7 @@ abstract class AbstractPaymentDriver abstract public function purchase($amount, $return_client_response = false); - abstract public function refund($amount, $transaction_reference, $return_client_response = false); + abstract public function refund(Payment $payment, $refund_amount, $return_client_response = false); abstract public function setPaymentMethod($payment_method_id); diff --git a/app/PaymentDrivers/Authorize/AuthorizeTransactions.php b/app/PaymentDrivers/Authorize/AuthorizeTransactions.php index fe2d169b77..fc18107e85 100644 --- a/app/PaymentDrivers/Authorize/AuthorizeTransactions.php +++ b/app/PaymentDrivers/Authorize/AuthorizeTransactions.php @@ -12,6 +12,7 @@ namespace App\PaymentDrivers\Authorize; +use App\PaymentDrivers\AuthorizePaymentDriver; use net\authorize\api\contract\v1\GetTransactionDetailsRequest; use net\authorize\api\controller\GetTransactionDetailsController; @@ -50,15 +51,15 @@ class AuthorizeTransactions if (($response != null) && ($response->getMessages()->getResultCode() == "Ok")) { - echo "SUCCESS: Transaction Status:" . $response->getTransaction()->getTransactionStatus() . "\n"; - echo " Auth Amount:" . $response->getTransaction()->getAuthAmount() . "\n"; - echo " Trans ID:" . $response->getTransaction()->getTransId() . "\n"; + info( "SUCCESS: Transaction Status:" . $response->getTransaction()->getTransactionStatus() ); + info( " Auth Amount:" . $response->getTransaction()->getAuthAmount() ); + info( " Trans ID:" . $response->getTransaction()->getTransId() ); } else { - echo "ERROR : Invalid response\n"; + info( "ERROR : Invalid response\n"); $errorMessages = $response->getMessages()->getMessage(); - echo "Response : " . $errorMessages[0]->getCode() . " " .$errorMessages[0]->getText() . "\n"; + info( "Response : " . $errorMessages[0]->getCode() . " " .$errorMessages[0]->getText() ); } return $response; diff --git a/app/PaymentDrivers/Authorize/RefundTransaction.php b/app/PaymentDrivers/Authorize/RefundTransaction.php index 1b0772bdf2..e7b7362c35 100644 --- a/app/PaymentDrivers/Authorize/RefundTransaction.php +++ b/app/PaymentDrivers/Authorize/RefundTransaction.php @@ -12,7 +12,9 @@ namespace App\PaymentDrivers\Authorize; +use App\Models\Payment; use App\PaymentDrivers\AuthorizePaymentDriver; +use App\PaymentDrivers\Authorize\AuthorizeTransactions; use net\authorize\api\contract\v1\CreateTransactionRequest; use net\authorize\api\contract\v1\CustomerProfilePaymentType; use net\authorize\api\contract\v1\PaymentProfileType; @@ -26,14 +28,22 @@ use net\authorize\api\controller\CreateTransactionController; */ class RefundTransaction { + public $authorize; + + public $authorize_transaction; public function __construct(AuthorizePaymentDriver $authorize) { $this->authorize = $authorize; + $this->authorize_transaction = new AuthorizeTransactions($this->authorize); } - function refundTransaction($transaction_reference, $amount, $payment_profile_id, $profile_id) + function refundTransaction(Payment $payment, $amount) { + error_reporting (E_ALL & ~E_DEPRECATED); + + $transaction_details = $this->authorize_transaction->getTransactionDetails($payment->transaction_reference); + $this->authorize->init(); @@ -41,11 +51,11 @@ class RefundTransaction $refId = 'ref' . time(); $paymentProfile = new PaymentProfileType(); - $paymentProfile->setPaymentProfileId( $payment_profile_id ); + $paymentProfile->setPaymentProfileId( $transaction_details->getTransaction()->getProfile()->getCustomerPaymentProfileId() ); // set customer profile $customerProfile = new CustomerProfilePaymentType(); - $customerProfile->setCustomerProfileId( $profile_id ); + $customerProfile->setCustomerProfileId( $transaction_details->getTransaction()->getProfile()->getCustomerProfileId() ); $customerProfile->setPaymentProfile( $paymentProfile ); //create a transaction @@ -53,7 +63,7 @@ class RefundTransaction $transactionRequest->setTransactionType("refundTransaction"); $transactionRequest->setAmount($amount); $transactionRequest->setProfile($customerProfile); - $transactionRequest->setRefTransId($transaction_reference); + $transactionRequest->setRefTransId($payment->transaction_reference); $request = new CreateTransactionRequest(); $request->setMerchantAuthentication($this->authorize->merchant_authentication); @@ -68,20 +78,32 @@ class RefundTransaction { $tresponse = $response->getTransactionResponse(); - if ($tresponse != null && $tresponse->getMessages() != null) + if ($tresponse != null && $tresponse->getMessages() != null) { - echo " Transaction Response code : " . $tresponse->getResponseCode() . "\n"; - echo "Refund SUCCESS: " . $tresponse->getTransId() . "\n"; - echo " Code : " . $tresponse->getMessages()[0]->getCode() . "\n"; - echo " Description : " . $tresponse->getMessages()[0]->getDescription() . "\n"; + + return [ + 'transaction_reference' => $tresponse->getTransId(), + 'success' => true, + 'description' => $tresponse->getMessages()[0]->getDescription(), + 'code' => $tresponse->getMessages()[0]->getCode(), + 'transaction_response' => $tresponse->getResponseCode() + ]; + } else { - echo "Transaction Failed \n"; + if($tresponse->getErrors() != null) { - echo " Error code : " . $tresponse->getErrors()[0]->getErrorCode() . "\n"; - echo " Error message : " . $tresponse->getErrors()[0]->getErrorText() . "\n"; + + return [ + 'transaction_reference' => '', + 'transaction_response' => '', + 'success' => false, + 'description' => $tresponse->getErrors()[0]->getErrorText(), + 'code' => $tresponse->getErrors()[0]->getErrorCode(), + ]; + } } } @@ -91,22 +113,50 @@ class RefundTransaction $tresponse = $response->getTransactionResponse(); if($tresponse != null && $tresponse->getErrors() != null) { - echo " Error code : " . $tresponse->getErrors()[0]->getErrorCode() . "\n"; - echo " Error message : " . $tresponse->getErrors()[0]->getErrorText() . "\n"; + + return [ + 'transaction_reference' => '', + 'transaction_response' => '', + 'success' => false, + 'description' => $tresponse->getErrors()[0]->getErrorText(), + 'code' => $tresponse->getErrors()[0]->getErrorCode(), + ]; + } else { - echo " Error code : " . $response->getMessages()->getMessage()[0]->getCode() . "\n"; - echo " Error message : " . $response->getMessages()->getMessage()[0]->getText() . "\n"; + + return [ + 'transaction_reference' => '', + 'transaction_response' => '', + 'success' => false, + 'description' => $response->getMessages()->getMessage()[0]->getText(), + 'code' => $response->getMessages()->getMessage()[0]->getCode(), + ]; + } } } else { - echo "No response returned \n"; + + return [ + 'transaction_reference' => '', + 'transaction_response' => '', + 'success' => false, + 'description' => 'No response returned', + 'code' => 'No response returned', + ]; + } - return $response; + return [ + 'transaction_reference' => '', + 'transaction_response' => '', + 'success' => false, + 'description' => 'No response returned', + 'code' => 'No response returned', + ]; } diff --git a/app/PaymentDrivers/AuthorizePaymentDriver.php b/app/PaymentDrivers/AuthorizePaymentDriver.php index 163dd63084..bc83570df4 100644 --- a/app/PaymentDrivers/AuthorizePaymentDriver.php +++ b/app/PaymentDrivers/AuthorizePaymentDriver.php @@ -14,8 +14,10 @@ namespace App\PaymentDrivers; use App\Models\ClientGatewayToken; use App\Models\GatewayType; +use App\Models\Payment; use App\PaymentDrivers\Authorize\AuthorizeCreditCard; use App\PaymentDrivers\Authorize\AuthorizePaymentMethod; +use App\PaymentDrivers\Authorize\RefundTransaction; use net\authorize\api\constants\ANetEnvironment; use net\authorize\api\contract\v1\CreateTransactionRequest; use net\authorize\api\contract\v1\GetMerchantDetailsRequest; @@ -110,16 +112,12 @@ class AuthorizePaymentDriver extends BaseDriver public function processPaymentView($data) { - return $this->payment_method->processPaymentView($data); - } public function processPaymentResponse($request) { - return $this->payment_method->processPaymentResponse($request); - } public function purchase($amount, $return_client_response = false) @@ -127,9 +125,9 @@ class AuthorizePaymentDriver extends BaseDriver return false; } - public function refund($amount, $transaction_reference, $return_client_response = false) + public function refund(Payment $payment, $refund_amount, $return_client_response = false) { - + return (new RefundTransaction($this))->refundTransaction($payment, $refund_amount); } public function findClientGatewayRecord() :?ClientGatewayToken diff --git a/app/PaymentDrivers/BaseDriver.php b/app/PaymentDrivers/BaseDriver.php index bc6aeabc64..eaa32f860f 100644 --- a/app/PaymentDrivers/BaseDriver.php +++ b/app/PaymentDrivers/BaseDriver.php @@ -82,12 +82,12 @@ class BaseDriver extends AbstractPaymentDriver /** * Executes a refund attempt for a given amount with a transaction_reference * + * @param Payment $payment The Payment Object * @param float $amount The amount to be refunded - * @param string $transaction_reference The transaction reference * @param boolean $return_client_response Whether the method needs to return a response (otherwise we assume an unattended payment) * @return mixed */ - public function refund($amount, $transaction_reference, $return_client_response = false) {} + public function refund(Payment $payment, $amount, $return_client_response = false) {} /** * Set the inbound request payment method type for access. diff --git a/app/Policies/DocumentPolicy.php b/app/Policies/DocumentPolicy.php new file mode 100644 index 0000000000..5ac01f5146 --- /dev/null +++ b/app/Policies/DocumentPolicy.php @@ -0,0 +1,16 @@ +isAdmin() || $user->hasPermission('create_all'); + } +} diff --git a/app/Providers/AuthServiceProvider.php b/app/Providers/AuthServiceProvider.php index 256a3daa91..5996bae848 100644 --- a/app/Providers/AuthServiceProvider.php +++ b/app/Providers/AuthServiceProvider.php @@ -18,6 +18,7 @@ use App\Models\CompanyGateway; use App\Models\CompanyToken; use App\Models\Credit; use App\Models\Design; +use App\Models\Document; use App\Models\Expense; use App\Models\GroupSetting; use App\Models\Invoice; @@ -38,6 +39,7 @@ use App\Policies\CompanyPolicy; use App\Policies\CompanyTokenPolicy; use App\Policies\CreditPolicy; use App\Policies\DesignPolicy; +use App\Policies\DocumentPolicy; use App\Policies\ExpensePolicy; use App\Policies\GroupSettingPolicy; use App\Policies\InvoicePolicy; @@ -70,6 +72,7 @@ class AuthServiceProvider extends ServiceProvider CompanyGateway::class => CompanyGatewayPolicy::class, Credit::class => CreditPolicy::class, Design::class => DesignPolicy::class, + Document::class => DocumentPolicy::class, Expense::class => ExpensePolicy::class, GroupSetting::class => GroupSettingPolicy::class, Invoice::class => InvoicePolicy::class, diff --git a/app/Repositories/GroupSettingRepository.php b/app/Repositories/GroupSettingRepository.php index db847878ad..cd1a14b627 100644 --- a/app/Repositories/GroupSettingRepository.php +++ b/app/Repositories/GroupSettingRepository.php @@ -14,7 +14,7 @@ namespace App\Repositories; use App\Models\GroupSetting; use App\Utils\Traits\MakesHash; -class GroupSettingRepository +class GroupSettingRepository extends BaseRepository { use MakesHash; /** diff --git a/app/Services/Ledger/LedgerService.php b/app/Services/Ledger/LedgerService.php index 906566441a..be81a88541 100644 --- a/app/Services/Ledger/LedgerService.php +++ b/app/Services/Ledger/LedgerService.php @@ -12,6 +12,7 @@ namespace App\Services\Ledger; use App\Factory\CompanyLedgerFactory; +use App\Models\Activity; use App\Models\CompanyLedger; class LedgerService @@ -38,6 +39,7 @@ class LedgerService $company_ledger->adjustment = $adjustment; $company_ledger->notes = $notes; $company_ledger->balance = $balance + $adjustment; + $company_ledger->activity_id = Activity::UPDATE_INVOICE; $company_ledger->save(); $this->entity->company_ledger()->save($company_ledger); @@ -60,6 +62,7 @@ class LedgerService $company_ledger->client_id = $this->entity->client_id; $company_ledger->adjustment = $adjustment; $company_ledger->balance = $balance + $adjustment; + $company_ledger->activity_id = Activity::UPDATE_PAYMENT; $company_ledger->save(); $this->entity->company_ledger()->save($company_ledger); @@ -80,6 +83,7 @@ class LedgerService $company_ledger->adjustment = $adjustment; $company_ledger->notes = $notes; $company_ledger->balance = $balance + $adjustment; + $company_ledger->activity_id = Activity::UPDATE_CREDIT; $company_ledger->save(); $this->entity->company_ledger()->save($company_ledger); diff --git a/app/Services/Payment/RefundPayment.php b/app/Services/Payment/RefundPayment.php index 822eaadbfb..677df382d8 100644 --- a/app/Services/Payment/RefundPayment.php +++ b/app/Services/Payment/RefundPayment.php @@ -57,7 +57,7 @@ class RefundPayment if ($this->refund_data['gateway_refund'] !== false && $this->total_refund > 0) { - $gateway = CompanyGateway::find($this->company_gateway_id); + $gateway = CompanyGateway::find($this->payment->company_gateway_id); if ($gateway) { $response = $gateway->driver($this->payment->client)->refund($this->payment, $this->total_refund); @@ -65,7 +65,7 @@ class RefundPayment if (!$response) { throw new PaymentRefundFailed(); } - + info(print_r($response,1)); //todo //need to check the gateway response has successfully be transacted. @@ -290,127 +290,3 @@ class RefundPayment return $this->payment; } } - - - - - -/* - - private function refundPaymentWithNoInvoices(array $data) - { - - $this->createActivity($data, $credit_note->id); - - //determine if we need to refund via gateway - if ($data['gateway_refund'] !== false) { - //todo process gateway refund, on success, reduce the credit note balance to 0 - } - - $this->save(); - - //$this->client->paid_to_date -= $data['amount']; - $this->client->save(); - - return $this->fresh(); - } - - - private function refundPaymentWithInvoices($data) - { - - if ($data['gateway_refund'] !== false && $this->total_refund > 0) { - $gateway = CompanyGateway::find($this->company_gateway_id); - - if ($gateway) { - $response = $gateway->driver($this->client)->refund($this, $this->total_refund); - - if (!$response) { - throw new PaymentRefundFailed(); - } - } - } - - if ($this->total_refund > 0) { - $this->refunded += $this->total_refund; - } - - $this->save(); - - $client_balance_adjustment = $this->adjustInvoices($data); - - $credit_note->ledger()->updateCreditBalance($client_balance_adjustment, $ledger_string); - - $this->client->paid_to_date -= $data['amount']; - $this->client->save(); - - - return $this; - } - - private function createActivity(array $data, int $credit_id) - { - $fields = new \stdClass; - $activity_repo = new ActivityRepository(); - - $fields->payment_id = $this->id; - $fields->user_id = $this->user_id; - $fields->company_id = $this->company_id; - $fields->activity_type_id = Activity::REFUNDED_PAYMENT; - $fields->credit_id = $credit_id; - - if (isset($data['invoices'])) { - foreach ($data['invoices'] as $invoice) { - $fields->invoice_id = $invoice->id; - - $activity_repo->save($fields, $this); - } - } else { - $activity_repo->save($fields, $this); - } - } - - - private function buildCreditNote(array $data) :?Credit - { - $credit_note = CreditFactory::create($this->company_id, $this->user_id); - $credit_note->assigned_user_id = isset($this->assigned_user_id) ?: null; - $credit_note->date = $data['date']; - $credit_note->status_id = Credit::STATUS_SENT; - $credit_note->client_id = $this->client->id; - $credit_note->amount = $data['amount']; - $credit_note->balance = $data['amount']; - - return $credit_note; - } - - private function adjustInvoices(array $data) - { - $adjustment_amount = 0; - - foreach ($data['invoices'] as $refunded_invoice) { - $invoice = Invoice::find($refunded_invoice['invoice_id']); - - $invoice->service()->updateBalance($refunded_invoice['amount'])->save(); - - if ($invoice->amount == $invoice->balance) { - $invoice->service()->setStatus(Invoice::STATUS_SENT); - } else { - $invoice->service()->setStatus(Invoice::STATUS_PARTIAL); - } - - $client = $invoice->client; - - $adjustment_amount += $refunded_invoice['amount']; - $client->balance += $refunded_invoice['amount']; - - $client->save(); - - //todo adjust ledger balance here? or after and reference the credit and its total - } - - return $adjustment_amount; - } -} - - */ \ No newline at end of file diff --git a/app/Transformers/CompanyLedgerTransformer.php b/app/Transformers/CompanyLedgerTransformer.php index 9b10f54212..a9137e1706 100644 --- a/app/Transformers/CompanyLedgerTransformer.php +++ b/app/Transformers/CompanyLedgerTransformer.php @@ -35,6 +35,7 @@ class CompanyLedgerTransformer extends EntityTransformer 'notes' => (string)$company_ledger->notes ?: '', 'balance' => (float) $company_ledger->balance, 'adjustment' => (float) $company_ledger->adjustment, + 'activity_id' => (int)$company_ledger->activity_id, 'created_at' => (int)$company_ledger->created_at, 'updated_at' => (int)$company_ledger->updated_at, 'archived_at' => (int)$company_ledger->deleted_at, diff --git a/app/Transformers/PaymentTransformer.php b/app/Transformers/PaymentTransformer.php index 1347a760cf..a2f574dabf 100644 --- a/app/Transformers/PaymentTransformer.php +++ b/app/Transformers/PaymentTransformer.php @@ -12,9 +12,11 @@ namespace App\Transformers; use App\Models\Client; +use App\Models\Document; use App\Models\Invoice; use App\Models\Payment; use App\Models\Paymentable; +use App\Transformers\DocumentTransformer; use App\Utils\Traits\MakesHash; class PaymentTransformer extends EntityTransformer @@ -28,7 +30,8 @@ class PaymentTransformer extends EntityTransformer protected $availableIncludes = [ 'client', 'invoices', - 'paymentables' + 'paymentables', + 'documents' ]; public function __construct($serializer = null) @@ -59,6 +62,11 @@ class PaymentTransformer extends EntityTransformer return $this->includeCollection($payment->paymentables, $transformer, Paymentable::class); } + public function includeDocuments(Payment $payment) + { + $transformer = new DocumentTransformer($this->serializer); + return $this->includeCollection($payment->documents, $transformer, Document::class); + } public function transform(Payment $payment) { diff --git a/app/Transformers/ProductTransformer.php b/app/Transformers/ProductTransformer.php index 65f4ba9661..8c907a6cfb 100644 --- a/app/Transformers/ProductTransformer.php +++ b/app/Transformers/ProductTransformer.php @@ -12,8 +12,10 @@ namespace App\Transformers; use App\Models\Company; +use App\Models\Document; use App\Models\Product; use App\Models\User; +use App\Transformers\DocumentTransformer; use App\Utils\Traits\MakesHash; class ProductTransformer extends EntityTransformer @@ -28,7 +30,8 @@ class ProductTransformer extends EntityTransformer */ protected $availableIncludes = [ 'company', - 'user' + 'user', + 'documents', ]; @@ -56,6 +59,12 @@ class ProductTransformer extends EntityTransformer return $this->includeItem($product->company, $transformer, Company::class); } + public function includeDocuments(Product $product) + { + $transformer = new DocumentTransformer($this->serializer); + return $this->includeCollection($product->documents, $transformer, Document::class); + } + public function transform(Product $product) { return [ diff --git a/database/migrations/2014_10_13_000000_create_users_table.php b/database/migrations/2014_10_13_000000_create_users_table.php index f4a0462f04..8baaaf6000 100644 --- a/database/migrations/2014_10_13_000000_create_users_table.php +++ b/database/migrations/2014_10_13_000000_create_users_table.php @@ -1120,6 +1120,7 @@ class CreateUsersTable extends Migration $table->unsignedInteger('company_id'); $table->unsignedInteger('client_id')->nullable(); $table->unsignedInteger('user_id')->nullable(); + $table->unsignedInteger('activity_id')->nullable(); $table->decimal('adjustment', 16, 4)->nullable(); $table->decimal('balance', 16, 4)->nullable(); //this is the clients balance carried forward @@ -1167,6 +1168,7 @@ class CreateUsersTable extends Migration $table->unsignedInteger('user_id')->nullable(); $table->string('name')->nullable(); $table->mediumText('settings')->nullable(); + $table->boolean('is_default')->default(0); $table->softDeletes('deleted_at', 6); $table->timestamps(6); diff --git a/resources/views/index/index.blade.php b/resources/views/index/index.blade.php index 1e63b29e16..47d528baef 100644 --- a/resources/views/index/index.blade.php +++ b/resources/views/index/index.blade.php @@ -6,6 +6,7 @@ + diff --git a/routes/api.php b/routes/api.php index 5d9d7b016d..48dff4be83 100644 --- a/routes/api.php +++ b/routes/api.php @@ -69,6 +69,10 @@ Route::group(['middleware' => ['api_db', 'token_auth', 'locale'], 'prefix' => 'a Route::post('vendors/bulk', 'VendorController@bulk')->name('vendors.bulk'); + Route::resource('documents', 'DocumentController');// name = (documents. index / create / show / update / destroy / edit + + Route::post('documents/bulk', 'DocumentController@bulk')->name('documents.bulk'); + Route::resource('client_statement', 'ClientStatementController@statement');// name = (client_statement. index / create / show / update / destroy / edit Route::resource('payment_terms', 'PaymentTermController');// name = (payments. index / create / show / update / destroy / edit @@ -108,6 +112,7 @@ Route::group(['middleware' => ['api_db', 'token_auth', 'locale'], 'prefix' => 'a Route::put('company_users/{user}', 'CompanyUserController@update'); Route::resource('group_settings', 'GroupSettingController'); + Route::post('group_settings/bulk', 'GroupSettingController@bulk'); Route::resource('tax_rates', 'TaxRateController');// name = (tasks. index / create / show / update / destroy / edit diff --git a/routes/client.php b/routes/client.php index 5c5e22fc69..5be6c2ad86 100644 --- a/routes/client.php +++ b/routes/client.php @@ -49,7 +49,9 @@ Route::group(['middleware' => ['auth:contact','locale'], 'prefix' => 'client', ' Route::resource('payment_methods', 'ClientPortal\PaymentMethodController');// name = (payment_methods. index / create / show / update / destroy / edit Route::match(['GET', 'POST'], 'quotes/approve', 'ClientPortal\QuoteController@bulk')->name('quotes.bulk'); - Route::resource('quotes', 'ClientPortal\QuoteController')->only('index', 'show'); + Route::get('quotes', 'ClientPortal\QuoteController@index')->name('quotes.index')->middleware('portal_enabled'); + Route::get('quotes/{quote}', 'ClientPortal\QuoteController@show')->name('quote.show'); + Route::get('quotes/{quote_invitation}', 'ClientPortal\QuoteController@show')->name('quote.show_invitation'); Route::resource('credits', 'ClientPortal\CreditController')->only('index', 'show'); diff --git a/tests/Feature/DesignApiTest.php b/tests/Feature/DesignApiTest.php index aba65c4f3b..d1701e6152 100644 --- a/tests/Feature/DesignApiTest.php +++ b/tests/Feature/DesignApiTest.php @@ -132,4 +132,80 @@ class DesignApiTest extends TestCase $this->assertTrue((bool)$design->is_deleted); $this->assertGreaterThan(0, $design->deleted_at); } + + + public function testDesignArchive() + { + $design = [ + 'body' => 'body', + 'includes' => 'includes', + 'product' => 'product', + 'task' => 'task', + 'footer' => 'footer', + 'header' => 'header' + ]; + + $data = [ + 'name' => $this->faker->firstName, + 'design' => $design + ]; + + $response = $this->withHeaders([ + 'X-API-SECRET' => config('ninja.api_secret'), + 'X-API-TOKEN' => $this->token + ])->post('/api/v1/designs', $data); + + $response->assertStatus(200); + + $arr = $response->json(); + + $this->id = $arr['data']['id']; + + $data['ids'][] = $arr['data']['id']; + + $response = $this->withHeaders([ + 'X-API-SECRET' => config('ninja.api_secret'), + 'X-API-TOKEN' => $this->token + ])->post('/api/v1/designs/bulk?action=archive', $data); + + $response->assertStatus(200); + + $design = Design::where('id', $this->decodePrimaryKey($arr['data']['id']))->withTrashed()->first(); + + $this->assertNotNull($design->deleted_at); + + $response = $this->withHeaders([ + 'X-API-SECRET' => config('ninja.api_secret'), + 'X-API-TOKEN' => $this->token + ])->post('/api/v1/designs/bulk?action=restore', $data); + + $response->assertStatus(200); + + $design = Design::where('id', $this->decodePrimaryKey($arr['data']['id']))->withTrashed()->first(); + + $this->assertNull($design->deleted_at); + + $response = $this->withHeaders([ + 'X-API-SECRET' => config('ninja.api_secret'), + 'X-API-TOKEN' => $this->token + ])->post('/api/v1/designs/bulk?action=delete', $data); + + $response->assertStatus(200); + + $design = Design::where('id', $this->decodePrimaryKey($arr['data']['id']))->withTrashed()->first(); + + $this->assertTrue((bool)$design->is_deleted); + + $response = $this->withHeaders([ + 'X-API-SECRET' => config('ninja.api_secret'), + 'X-API-TOKEN' => $this->token + ])->post('/api/v1/designs/bulk?action=restore', $data); + + $response->assertStatus(200); + + $design = Design::where('id', $this->decodePrimaryKey($arr['data']['id']))->withTrashed()->first(); + + $this->assertFalse((bool)$design->is_deleted); + $this->assertNull($design->deleted_at); + } } diff --git a/tests/Integration/PaymentDrivers/AuthorizeTest.php b/tests/Integration/PaymentDrivers/AuthorizeTest.php index 71a3d6dbba..2dd85be485 100644 --- a/tests/Integration/PaymentDrivers/AuthorizeTest.php +++ b/tests/Integration/PaymentDrivers/AuthorizeTest.php @@ -2,6 +2,10 @@ namespace Tests\Integration\PaymentDrivers; +use App\Factory\PaymentFactory; +use App\Models\CompanyGateway; +use App\PaymentDrivers\AuthorizePaymentDriver; +use Tests\MockAccountData; use Tests\TestCase; use net\authorize\api\constants\ANetEnvironment; use net\authorize\api\contract\v1 as AnetAPI; @@ -31,10 +35,11 @@ use net\authorize\api\controller\GetMerchantDetailsController; */ class AuthorizeTest extends TestCase { + use MockAccountData; - public $customer_profile_id = 1512191314; + public $customer_profile_id = 1512373273; - public $customer_payment_profile = 1512219932; + public $customer_payment_profile = 1512424103; public function setUp() :void { @@ -43,7 +48,8 @@ class AuthorizeTest extends TestCase if (! config('ninja.testvars.authorize')) { $this->markTestSkipped('authorize.net not configured'); } - + + $this->makeTestData(); } public function testUnpackingVars() @@ -148,15 +154,7 @@ class AuthorizeTest extends TestCase // Create an array of any shipping addresses $shippingProfiles[] = $customerShippingAddress; $refId = 'ref' . time(); - $email = "test@gmail.com"; - - // // Create a new CustomerPaymentProfile object - // $paymentProfile = new AnetAPI\CustomerPaymentProfileType(); - // $paymentProfile->setCustomerType('individual'); - // $paymentProfile->setBillTo($billTo); - // $paymentProfile->setPayment($paymentCreditCard); - // $paymentProfiles[] = $paymentProfile; - + $email = "test12@gmail.com"; // Create a new CustomerProfileType and add the payment profile object $customerProfile = new CustomerProfileType(); @@ -188,6 +186,8 @@ class AuthorizeTest extends TestCase $errorMessages = $response->getMessages()->getMessage(); info("Response : " . $errorMessages[0]->getCode() . " " .$errorMessages[0]->getText() . "\n"); } + + info("the new customer profile id = ". $response->getCustomerProfileId()); $this->assertNotNull($response); @@ -241,16 +241,16 @@ class AuthorizeTest extends TestCase // Set credit card information for payment profile $creditCard = new CreditCardType(); - $creditCard->setCardNumber("4007000000027"); - $creditCard->setExpirationDate("2038-12"); - $creditCard->setCardCode("142"); + $creditCard->setCardNumber("4111111111111111"); + $creditCard->setExpirationDate("2024-01"); + $creditCard->setCardCode("100"); $paymentCreditCard = new PaymentType(); $paymentCreditCard->setCreditCard($creditCard); // Create the Bill To info for new payment type $billto = new CustomerAddressType(); - $billto->setFirstName("Ellen"); - $billto->setLastName("Johnson"); + $billto->setFirstName("Elas"); + $billto->setLastName("Joson"); $billto->setCompany("Souveniropolis"); $billto->setAddress("14 Main Street"); $billto->setCity("Pecan Springs"); @@ -315,7 +315,7 @@ class AuthorizeTest extends TestCase $transactionRequestType = new TransactionRequestType(); $transactionRequestType->setTransactionType( "authCaptureTransaction"); - $transactionRequestType->setAmount(400); + $transactionRequestType->setAmount(350); $transactionRequestType->setProfile($profileToCharge); $request = new CreateTransactionRequest(); @@ -372,6 +372,31 @@ class AuthorizeTest extends TestCase } $this->assertNotNull($response); + + $this->assertNotNull($tresponse); + + /* Testing refunds - need to research more as payments are in a pending state so cannot be 'refunded'*/ + + // info("transaction reference = " . $tresponse->getTransId()); + + // $payment = PaymentFactory::create($this->company->id, $this->user->id); + // $payment->amount = 400; + // $payment->client_id = $this->client->id; + // $payment->date = now(); + // $payment->transaction_reference = $tresponse->getTransId(); + // $payment->company_gateway_id = 1; + + // $payment->save(); + + // $company_gateway = CompanyGateway::where('gateway_key', '3b6621f970ab18887c4f6dca78d3f8bb')->first(); + + // $authorize_payment_driver = new AuthorizePaymentDriver($company_gateway, $this->client); + // $response = $authorize_payment_driver->refund($payment, 350); + + // info(print_r($response,1)); + + // $this->assertTrue(is_array($response)); + } }