diff --git a/app/Console/Commands/CheckData.php b/app/Console/Commands/CheckData.php index 839f7f562e36..6de85578a4e2 100644 --- a/app/Console/Commands/CheckData.php +++ b/app/Console/Commands/CheckData.php @@ -83,6 +83,8 @@ class CheckData extends Command $this->checkInvoiceBalances(); $this->checkClientBalances(); $this->checkContacts(); + $this->checkCompanyData(); + //$this->checkLogoFiles(); if (! $this->option('client_id')) { @@ -388,4 +390,67 @@ class CheckData extends Command ['database', null, InputOption::VALUE_OPTIONAL, 'Database', null], ]; } + + + private function checkCompanyData() + { + $tables = [ + 'activities' => [ + 'invoice', + 'client', + 'client_contact', + 'payment', + ], + 'invoices' => [ + 'client', + ], + 'payments' => [ + 'client', + ], + 'products' => [ + + ], + ]; + + foreach ($tables as $table => $entityTypes) { + foreach ($entityTypes as $entityType) { + $tableName = $this->pluralizeEntityType($entityType); + $field = $entityType; + if ($table == 'companies') { + $company_id = 'id'; + } else { + $company_id = 'company_id'; + } + $records = \DB::table($table) + ->join($tableName, "{$tableName}.id", '=', "{$table}.{$field}_id") + ->where("{$table}.{$company_id}", '!=', \DB::raw("{$tableName}.company_id")) + ->get(["{$table}.id"]); + + if ($records->count()) { + $this->isValid = false; + $this->logMessage($records->count() . " {$table} records with incorrect {$entityType} company id"); + + } + } + } + + + // foreach(User::cursor() as $user) { + + // $records = Company::where('account_id',) + + // } + + } + + public function pluralizeEntityType($type) + { + + if ($type === 'company') { + return 'companies'; + } + + return $type . 's'; + + } } diff --git a/app/DataMapper/CompanySettings.php b/app/DataMapper/CompanySettings.php index a5009b4a76fc..478798134ebe 100644 --- a/app/DataMapper/CompanySettings.php +++ b/app/DataMapper/CompanySettings.php @@ -232,12 +232,12 @@ class CompanySettings extends BaseSettings public $portal_custom_js = ''; public $client_can_register = false; - public $client_signup_terms = ''; - public $client_signup_privacy_policy = ''; + public $client_portal_terms = ''; + public $client_portal_privacy_policy = ''; public static $casts = [ - 'client_signup_terms' => 'string', - 'client_signup_privacy_policy' => 'string', + 'client_portal_terms' => 'string', + 'client_portal_privacy_policy' => 'string', 'client_can_register' => 'bool', 'portal_design_id' => 'string', 'late_fee_endless_percent' => 'float', diff --git a/app/Http/Middleware/ContactRegister.php b/app/Http/Middleware/ContactRegister.php index e29456c90d41..bbe584cbfaaa 100644 --- a/app/Http/Middleware/ContactRegister.php +++ b/app/Http/Middleware/ContactRegister.php @@ -37,7 +37,7 @@ class ContactRegister $company = Company::where('company_key', $request->company_key)->firstOrFail(); - abort_unless($company->getSetting('client_can_register'), 404); + abort_unless($company->client_can_register, 404); return $next($request); } diff --git a/app/Http/Requests/User/StoreUserRequest.php b/app/Http/Requests/User/StoreUserRequest.php index ce8b5c9d6dae..c362839509ac 100644 --- a/app/Http/Requests/User/StoreUserRequest.php +++ b/app/Http/Requests/User/StoreUserRequest.php @@ -28,7 +28,7 @@ class StoreUserRequest extends Request */ public function authorize() : bool - { + { return auth()->user()->isAdmin(); } @@ -43,8 +43,9 @@ class StoreUserRequest extends Request $rules['email'] = new ValidUserForCompany(); } - if(auth()->user()->company()->account->isFreeHostedClient()) + if(auth()->user()->company()->account->isFreeHostedClient()){ $rules['hosted_users'] = new CanAddUserRule(auth()->user()->company()->account); + } return $rules; } diff --git a/app/Models/Credit.php b/app/Models/Credit.php index e817c7aa75ce..78261cacae42 100644 --- a/app/Models/Credit.php +++ b/app/Models/Credit.php @@ -66,7 +66,7 @@ class Credit extends BaseModel 'client_id', 'footer', 'design_id', - + 'exchange_rate', ]; protected $casts = [ diff --git a/app/Models/Invoice.php b/app/Models/Invoice.php index 5db78dba1812..9500cbf62986 100644 --- a/app/Models/Invoice.php +++ b/app/Models/Invoice.php @@ -100,6 +100,7 @@ class Invoice extends BaseModel 'custom_surcharge_tax4', 'design_id', 'assigned_user_id', + 'exchange_rate' ]; protected $casts = [ diff --git a/app/Models/Payment.php b/app/Models/Payment.php index 36df31e76e8c..ef94c316da3e 100644 --- a/app/Models/Payment.php +++ b/app/Models/Payment.php @@ -261,6 +261,12 @@ class Payment extends BaseModel return $this->status_id == self::STATUS_REFUNDED; } + public function setStatus($status) + { + $this->status_id = $status; + $this->save(); + } + public function markVoided() { if ($this->isVoided() || $this->isPartiallyRefunded() || $this->isRefunded()) { diff --git a/app/Models/Quote.php b/app/Models/Quote.php index debd2e8058bb..5f64ce2a9795 100644 --- a/app/Models/Quote.php +++ b/app/Models/Quote.php @@ -70,6 +70,7 @@ class Quote extends BaseModel 'client_id', 'footer', 'design_id', + 'exchange_rate' ]; protected $casts = [ diff --git a/app/Models/User.php b/app/Models/User.php index 73c14a4adedf..55e8550e1310 100644 --- a/app/Models/User.php +++ b/app/Models/User.php @@ -196,9 +196,21 @@ class User extends Authenticatable implements MustVerifyEmail $this->id = auth()->user()->id; } - return $this->hasOneThrough(CompanyUser::class, CompanyToken::class, 'user_id', 'company_id', 'id', 'company_id') - ->where('company_user.user_id', $this->id) - ->withTrashed(); + return $this->hasOneThrough(CompanyUser::class, CompanyToken::class, 'user_id', 'company_id', 'id', 'company_id') + ->where('company_user.user_id', $this->id) + ->withTrashed(); + + // if(request()->header('X-API-TOKEN')){ + // return $this->hasOneThrough(CompanyUser::class, CompanyToken::class, 'user_id', 'company_id', 'id', 'company_id') + // ->where('company_tokens.token', request()->header('X-API-TOKEN')) + // ->withTrashed(); + // } + // else { + + // return $this->hasOneThrough(CompanyUser::class, CompanyToken::class, 'user_id', 'company_id', 'id', 'company_id') + // ->where('company_user.user_id', $this->id) + // ->withTrashed(); + // } } /** diff --git a/app/PaymentDrivers/Authorize/AuthorizeCreditCard.php b/app/PaymentDrivers/Authorize/AuthorizeCreditCard.php index 160790415bac..1eeb7b5cabaf 100644 --- a/app/PaymentDrivers/Authorize/AuthorizeCreditCard.php +++ b/app/PaymentDrivers/Authorize/AuthorizeCreditCard.php @@ -120,7 +120,7 @@ class AuthorizeCreditCard $payment->client_id = $this->authorize->client->id; $payment->company_gateway_id = $this->authorize->company_gateway->id; $payment->status_id = Payment::STATUS_COMPLETED; - $payment->gateway_type_id = $this->authorize->payment_method; + $payment->gateway_type_id = GatewayType::CREDIT_CARD; $payment->type_id = PaymentType::CREDIT_CARD_OTHER; $payment->currency_id = $this->authorize->client->getSetting('currency_id'); $payment->date = Carbon::now(); diff --git a/app/Repositories/PaymentRepository.php b/app/Repositories/PaymentRepository.php index 245c02795a96..dd4f48b68c6b 100644 --- a/app/Repositories/PaymentRepository.php +++ b/app/Repositories/PaymentRepository.php @@ -193,4 +193,25 @@ class PaymentRepository extends BaseRepository return $payment; } + + public function delete($payment) + { + //cannot double delete a payment + if($payment->is_deleted) + return; + + $payment->service()->deletePayment(); + + return parent::delete($payment); + + } + + public function restore($payment) + { + //we cannot restore a deleted payment. + if($payment->is_deleted) + return; + + return parent::restore($payment); + } } diff --git a/app/Services/Payment/DeletePayment.php b/app/Services/Payment/DeletePayment.php new file mode 100644 index 000000000000..67a982ac95ab --- /dev/null +++ b/app/Services/Payment/DeletePayment.php @@ -0,0 +1,118 @@ +payment = $payment; + + $this->activity_repository = new ActivityRepository(); + } + + public function run() + { + + return $this->setStatus(Payment::STATUS_VOIDED) //sets status of payment + ->updateCreditables() //return the credits first + ->adjustInvoices() + ->updateClient() + ->save(); + } + + + + //reverse paymentables->invoices + + //reverse paymentables->credits + + //set refunded to amount + + //set applied amount to 0 + + private function updateClient() + { + $this->payment->client->service()->updatePaidToDate(-1*$this->payment->amount)->save(); + + return $this; + } + + private function adjustInvoices() + { + if ($this->payment->invoices()->exists()) + { + + $this->payment->invoices()->each(function ($paymentable_invoice){ + + $paymentable_invoice->service()->updateBalance($paymentable_invoice->pivot->amount)->save(); + $paymentable_invoice->ledger()->updateInvoiceBalance($paymentable_invoice->pivot->amount)->save(); + + if(floatval($paymentable_invoice->balance) == 0) + $paymentable_invoice->service()->setStatus(Invoice::STATUS_SENT)->save(); + else + $paymentable_invoice->service()->setStatus(Invoice::STATUS_PARTIAL)->save(); + + //fire event for this credit + // + }); + + } + + + return $this; + } + + private function updateCreditables() + { + if ($this->payment->credits()->exists()) + { + + $this->payment->credits()->each(function ($paymentable_credit){ + + $paymentable_credit->balance += $paymentable_credit->pivot->amount; + $paymentable_credit->setStatus(Credit::STATUS_SENT); + //fire event for this credit + // + }); + + + } + + return $this; + } + + private function setStatus($status) + { + $this->payment->status_id = Payment::STATUS_VOIDED; + + return $this; + } + /** + * Saves the payment + * + * @return Payment $payment + */ + private function save() + { + $this->payment->save(); + + return $this->payment; + } + + +} diff --git a/app/Services/Payment/PaymentService.php b/app/Services/Payment/PaymentService.php index 615a9400d849..bd7337c8033d 100644 --- a/app/Services/Payment/PaymentService.php +++ b/app/Services/Payment/PaymentService.php @@ -14,6 +14,7 @@ namespace App\Services\Payment; use App\Factory\PaymentFactory; use App\Models\Invoice; use App\Models\Payment; +use App\Services\Payment\DeletePayment; use App\Services\Payment\RefundPayment; use App\Services\Payment\UpdateInvoicePayment; @@ -77,6 +78,11 @@ class PaymentService return ((new RefundPayment($this->payment, $data)))->run(); } + public function deletePayment() :?Payment + { + return (new DeletePayment($this->payment))->run(); + } + public function updateInvoicePayment() :?Payment { return ((new UpdateInvoicePayment($this->payment)))->run(); diff --git a/app/Services/Payment/RefundPayment.php b/app/Services/Payment/RefundPayment.php index 9f3b7644a3bc..f683580624e5 100644 --- a/app/Services/Payment/RefundPayment.php +++ b/app/Services/Payment/RefundPayment.php @@ -248,12 +248,10 @@ class RefundPayment // $ledger_string = "Refund for Invoice {$invoice->number} for amount " . $refunded_invoice['amount']; //todo // $this->credit_note->ledger()->updateCreditBalance($adjustment_amount, $ledger_string); - - - + $client = $this->payment->client->fresh(); - $client->paid_to_date -= $this->total_refund; - $client->save(); + $client->service()->updatePaidToDate(-1*$this->total_refund)->save(); + } return $this; 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 5109954e312f..cee12a11992f 100644 --- a/database/migrations/2014_10_13_000000_create_users_table.php +++ b/database/migrations/2014_10_13_000000_create_users_table.php @@ -149,6 +149,7 @@ class CreateUsersTable extends Migration $table->boolean('fill_products')->default(true); $table->boolean('update_products')->default(true); $table->boolean('show_product_details')->default(true); + $table->boolean('client_can_register')->default(false); $table->boolean('custom_surcharge_taxes1')->default(false); $table->boolean('custom_surcharge_taxes2')->default(false); @@ -489,6 +490,7 @@ class CreateUsersTable extends Migration $t->boolean('custom_surcharge_tax3')->default(false); $t->boolean('custom_surcharge_tax4')->default(false); + $t->decimal('exchange_rate', 16, 4); $t->decimal('amount', 16, 4); $t->decimal('balance', 16, 4); $t->decimal('partial', 16, 4)->nullable(); @@ -566,6 +568,7 @@ class CreateUsersTable extends Migration $t->boolean('custom_surcharge_tax3')->default(false); $t->boolean('custom_surcharge_tax4')->default(false); + $t->decimal('exchange_rate', 16, 4); $t->decimal('amount', 16, 4); $t->decimal('balance', 16, 4); $t->decimal('partial', 16, 4)->nullable(); @@ -809,6 +812,7 @@ class CreateUsersTable extends Migration $t->boolean('custom_surcharge_tax3')->default(false); $t->boolean('custom_surcharge_tax4')->default(false); + $t->decimal('exchange_rate', 16, 4); $t->decimal('amount', 16, 4); $t->decimal('balance', 16, 4); $t->decimal('partial', 16, 4)->nullable(); diff --git a/resources/views/portal/ninja2020/auth/register.blade.php b/resources/views/portal/ninja2020/auth/register.blade.php index ca01fccdf310..5e0faed9f286 100644 --- a/resources/views/portal/ninja2020/auth/register.blade.php +++ b/resources/views/portal/ninja2020/auth/register.blade.php @@ -24,15 +24,15 @@
- @if(!empty($company->settings->client_signup_terms) || !empty($company->settings->client_signup_privacy_policy)) + @if(!empty($company->settings->client_portal_terms) || !empty($company->settings->client_portal_privacy_policy)) {{ ctrans('texts.i_agree') }} @endif - @includeWhen(!empty($company->settings->client_signup_terms), 'portal.ninja2020.auth.includes.register.popup', ['property' => 'terms_of_service', 'title' => ctrans('texts.terms_of_service'), 'content' => $company->settings->client_signup_terms]) - @includeWhen(!empty($company->settings->client_signup_privacy_policy), 'portal.ninja2020.auth.includes.register.popup', ['property' => 'privacy_policy', 'title' => ctrans('texts.privacy_policy'), 'content' => $company->settings->client_signup_privacy_policy]) + @includeWhen(!empty($company->settings->client_portal_terms), 'portal.ninja2020.auth.includes.register.popup', ['property' => 'terms_of_service', 'title' => ctrans('texts.terms_of_service'), 'content' => $company->settings->client_portal_terms]) + @includeWhen(!empty($company->settings->client_portal_privacy_policy), 'portal.ninja2020.auth.includes.register.popup', ['property' => 'privacy_policy', 'title' => ctrans('texts.privacy_policy'), 'content' => $company->settings->client_portal_privacy_policy]) diff --git a/resources/views/portal/ninja2020/components/general/footer.blade.php b/resources/views/portal/ninja2020/components/general/footer.blade.php index 9b96d6e78a3e..f9933daa30fb 100644 --- a/resources/views/portal/ninja2020/components/general/footer.blade.php +++ b/resources/views/portal/ninja2020/components/general/footer.blade.php @@ -1,6 +1,6 @@