diff --git a/.env.example b/.env.example index a9c2da28c840..2d5ec6c28f81 100644 --- a/.env.example +++ b/.env.example @@ -43,6 +43,7 @@ MAIL_FROM_ADDRESS='user@example.com' MAIL_FROM_NAME='Self Hosted User' POSTMARK_API_TOKEN= +REQUIRE_HTTPS=true GOOGLE_MAPS_API_KEY= API_SECRET=superdoopersecrethere diff --git a/app/Console/Kernel.php b/app/Console/Kernel.php index aba759f78e22..c6f9ab71ff2a 100644 --- a/app/Console/Kernel.php +++ b/app/Console/Kernel.php @@ -49,8 +49,6 @@ class Kernel extends ConsoleKernel $schedule->job(new UpdateExchangeRates)->daily(); - $schedule->job(new CheckDbStatus())->everyFiveMinutes(); - /* Run hosted specific jobs */ if(Ninja::isHosted()) { $schedule->job(new AdjustEmailQuota())->daily(); diff --git a/app/DataMapper/CompanySettings.php b/app/DataMapper/CompanySettings.php index babe17df191e..7df564862163 100644 --- a/app/DataMapper/CompanySettings.php +++ b/app/DataMapper/CompanySettings.php @@ -33,7 +33,7 @@ class CompanySettings extends BaseSettings public $enable_client_portal_dashboard = true; //implemented public $signature_on_pdf = false; public $document_email_attachment = false; - public $send_portal_password = false; + //public $send_portal_password = false; public $portal_design_id = '1'; @@ -113,7 +113,7 @@ class CompanySettings extends BaseSettings public $invoice_terms = ''; public $quote_terms = ''; public $invoice_taxes = 0; - public $enabled_item_tax_rates = 0; + // public $enabled_item_tax_rates = 0; public $invoice_design_id = 'VolejRejNm'; public $quote_design_id = 'VolejRejNm'; public $credit_design_id = 'VolejRejNm'; @@ -274,7 +274,7 @@ class CompanySettings extends BaseSettings 'email_template_statement' => 'string', 'email_subject_statement' => 'string', 'signature_on_pdf' => 'bool', - 'send_portal_password' => 'bool', + // 'send_portal_password' => 'bool', 'quote_footer' => 'string', 'page_size' => 'string', 'font_size' => 'int', @@ -344,7 +344,7 @@ class CompanySettings extends BaseSettings 'invoice_design_id' => 'string', 'invoice_fields' => 'string', 'invoice_taxes' => 'int', - 'enabled_item_tax_rates' => 'int', + //'enabled_item_tax_rates' => 'int', 'invoice_footer' => 'string', 'invoice_labels' => 'string', 'invoice_terms' => 'string', diff --git a/app/DataMapper/FreeCompanySettings.php b/app/DataMapper/FreeCompanySettings.php index 4ec96c7bb276..9f18d759972c 100644 --- a/app/DataMapper/FreeCompanySettings.php +++ b/app/DataMapper/FreeCompanySettings.php @@ -33,7 +33,7 @@ class FreeCompanySettings extends BaseSettings public $custom_value3 = ''; public $custom_value4 = ''; public $date_format_id = ''; - public $enabled_item_tax_rates = 0; +// public $enabled_item_tax_rates = 0; public $expense_number_pattern = ''; public $expense_number_counter = 1; public $inclusive_taxes = false; diff --git a/app/Helpers/Invoice/InvoiceItemSum.php b/app/Helpers/Invoice/InvoiceItemSum.php index 693cc4b4d722..b3f3312ae049 100644 --- a/app/Helpers/Invoice/InvoiceItemSum.php +++ b/app/Helpers/Invoice/InvoiceItemSum.php @@ -91,7 +91,7 @@ class InvoiceItemSum } private function sumLineItem() - { + { //todo need to support quantities less than the precision amount $this->setLineTotal($this->formatValue($this->item->cost, $this->currency->precision) * $this->formatValue($this->item->quantity, $this->currency->precision)); return $this; } diff --git a/app/Http/Controllers/BaseController.php b/app/Http/Controllers/BaseController.php index 5c3473f15eac..e25d0a24c6de 100644 --- a/app/Http/Controllers/BaseController.php +++ b/app/Http/Controllers/BaseController.php @@ -265,8 +265,8 @@ class BaseController extends Controller 'company.payments.paymentables', 'company.quotes.invitations.contact', 'company.quotes.invitations.company', - 'company.credits', - 'company.payment_terms', + 'company.credits.invitations.company', + 'company.payment_terms.company', //'company.credits.invitations.contact', //'company.credits.invitations.company', 'company.vendors.contacts', @@ -291,7 +291,7 @@ class BaseController extends Controller * Thresholds for displaying large account on first load */ if (request()->has('first_load') && request()->input('first_load') == 'true') { - if (auth()->user()->getCompany()->invoices->count() > 1000 || auth()->user()->getCompany()->products->count() > 1000) { + if (auth()->user()->getCompany()->invoices->count() > 1000 || auth()->user()->getCompany()->products->count() > 1000 || auth()->user()->getCompany()->clients->count() > 1000) { $data = $mini_load; } else { $data = $first_load; diff --git a/app/Http/Controllers/ClientPortal/PaymentController.php b/app/Http/Controllers/ClientPortal/PaymentController.php index 497f96d0c487..315157b8c1b9 100644 --- a/app/Http/Controllers/ClientPortal/PaymentController.php +++ b/app/Http/Controllers/ClientPortal/PaymentController.php @@ -120,7 +120,7 @@ class PaymentController extends Controller return $gateway ->driver(auth()->user()->client) - ->setPaymentMethod('App\\PaymentDrivers\\Stripe\\Alipay') + ->setPaymentMethod($payment_method_id) ->processPaymentView($data); } diff --git a/app/Http/Controllers/OpenAPI/CompanySettingsSchema.php b/app/Http/Controllers/OpenAPI/CompanySettingsSchema.php index f6a27f9374b2..893c6cb7454d 100644 --- a/app/Http/Controllers/OpenAPI/CompanySettingsSchema.php +++ b/app/Http/Controllers/OpenAPI/CompanySettingsSchema.php @@ -66,7 +66,6 @@ * @OA\Property(property="invoice_terms", type="string", example="Invoice Terms are...", description="The default invoice terms"), * @OA\Property(property="quote_terms", type="string", example="Quote Terms are...", description="The default quote terms"), * @OA\Property(property="invoice_taxes", type="number", example="1", description="Taxes can be applied to the invoice"), - * @OA\Property(property="enabled_item_tax_rates", type="number", example="1", description="Taxes can be applied to the invoice items"), * @OA\Property(property="invoice_design_id", type="string", example="1", description="The default design id (invoice, quote etc)"), * @OA\Property(property="quote_design_id", type="string", example="1", description="The default design id (invoice, quote etc)"), * @OA\Property(property="invoice_footer", type="string", example="1", description="The default invoice footer"), @@ -130,7 +129,6 @@ * @OA\Property(property="email_template_statement", type="string", example="template matter", description="____________"), * @OA\Property(property="email_subject_statement", type="string", example="subject matter", description="____________"), * @OA\Property(property="signature_on_pdf", type="boolean", example=false, description="____________"), - * @OA\Property(property="send_portal_password", type="boolean", example=false, description="____________"), * @OA\Property(property="quote_footer", type="string", example="the quote footer", description="____________"), * @OA\Property(property="email_subject_custom1", type="string", example="Custom Subject 1", description="____________"), * @OA\Property(property="email_subject_custom2", type="string", example="Custom Subject 2", description="____________"), diff --git a/app/Http/Middleware/Cors.php b/app/Http/Middleware/Cors.php index 4b5ec937503b..f1ca85bf62f7 100644 --- a/app/Http/Middleware/Cors.php +++ b/app/Http/Middleware/Cors.php @@ -37,6 +37,7 @@ class Cors $response->headers->set('Access-Control-Allow-Origin', '*'); $response->headers->set('Access-Control-Allow-Methods', 'GET, POST, PUT, DELETE, OPTIONS'); $response->headers->set('Access-Control-Allow-Headers', 'X-API-SECRET,X-API-TOKEN,X-API-PASSWORD,DNT,User-Agent,X-Requested-With,If-Modified-Since,Cache-Control,Content-Type,Range'); + $response->headers->set('Access-Control-Expose-Headers', 'X-APP-VERSION'); $response->headers->set('X-APP-VERSION', config('ninja.app_version')); $response->headers->set('X-API-VERSION', config('ninja.api_version')); diff --git a/app/Http/Middleware/QueryLogging.php b/app/Http/Middleware/QueryLogging.php index 93d49b446a26..ead6379ced75 100644 --- a/app/Http/Middleware/QueryLogging.php +++ b/app/Http/Middleware/QueryLogging.php @@ -50,8 +50,8 @@ class QueryLogging Log::info($request->method() . ' - ' . $request->url() . ": $count queries - " . $time); - // if($count > 50) - // Log::info($queries); + if($count > 50) + Log::info($queries); } } diff --git a/app/Jobs/Ninja/CheckDbStatus.php b/app/Jobs/Ninja/CheckDbStatus.php index fb159a00e9e7..fb51c56bac76 100644 --- a/app/Jobs/Ninja/CheckDbStatus.php +++ b/app/Jobs/Ninja/CheckDbStatus.php @@ -44,11 +44,9 @@ class CheckDbStatus implements ShouldQueue */ public function handle() { - - info("checking db status"); - DbStatus::dispatch('db-ninja-01', 'db.status.db-ninja-01'); - DbStatus::dispatch('db-ninja-02', 'db.status.db-ninja-02'); + DbStatus::dispatchNow('db-ninja-01', 'db.status.db-ninja-01'); + DbStatus::dispatchNow('db-ninja-02', 'db.status.db-ninja-02'); } diff --git a/app/Jobs/Util/UploadAvatar.php b/app/Jobs/Util/UploadAvatar.php index 033907df6bbe..144c50240232 100644 --- a/app/Jobs/Util/UploadAvatar.php +++ b/app/Jobs/Util/UploadAvatar.php @@ -47,6 +47,9 @@ class UploadAvatar implements ShouldQueue $path = Storage::putFile('public/' . $this->directory, new File(sys_get_temp_dir().'/'.$tmp_file)); +info($path); +info($tmp_file); + $url = Storage::url($path); //return file path diff --git a/app/Models/Credit.php b/app/Models/Credit.php index a07a422dc0d1..abb776c12e1d 100644 --- a/app/Models/Credit.php +++ b/app/Models/Credit.php @@ -70,6 +70,7 @@ class Credit extends BaseModel protected $casts = [ 'line_items' => 'object', + 'backup' => 'object', 'updated_at' => 'timestamp', 'created_at' => 'timestamp', 'deleted_at' => 'timestamp', diff --git a/app/Models/Currency.php b/app/Models/Currency.php index 9f945906a887..0f5e931e56c3 100644 --- a/app/Models/Currency.php +++ b/app/Models/Currency.php @@ -25,5 +25,7 @@ class Currency extends StaticModel 'updated_at' => 'timestamp', 'created_at' => 'timestamp', 'deleted_at' => 'timestamp', + //'precision' => 'string', + 'precision' => 'integer', ]; } diff --git a/app/Models/Invoice.php b/app/Models/Invoice.php index ab3e1babfbf2..edf9766bb51f 100644 --- a/app/Models/Invoice.php +++ b/app/Models/Invoice.php @@ -103,6 +103,7 @@ class Invoice extends BaseModel protected $casts = [ 'line_items' => 'object', + 'backup' => 'object', 'updated_at' => 'timestamp', 'created_at' => 'timestamp', 'deleted_at' => 'timestamp', diff --git a/app/Models/Quote.php b/app/Models/Quote.php index c8146faa27e5..362829eefede 100644 --- a/app/Models/Quote.php +++ b/app/Models/Quote.php @@ -76,6 +76,7 @@ class Quote extends BaseModel 'due_date' => 'date:Y-m-d', 'partial_due_date' => 'date:Y-m-d', 'line_items' => 'object', + 'backup' => 'object', 'updated_at' => 'timestamp', 'created_at' => 'timestamp', 'deleted_at' => 'timestamp', diff --git a/app/Models/RecurringInvoice.php b/app/Models/RecurringInvoice.php index 5c4abe763209..8d16415ca94f 100644 --- a/app/Models/RecurringInvoice.php +++ b/app/Models/RecurringInvoice.php @@ -101,6 +101,7 @@ class RecurringInvoice extends BaseModel protected $casts = [ 'settings' => 'object', 'line_items' => 'object', + 'backup' => 'object', 'updated_at' => 'timestamp', 'created_at' => 'timestamp', 'deleted_at' => 'timestamp', diff --git a/app/Models/RecurringQuote.php b/app/Models/RecurringQuote.php index 60310b0e8dd6..7d3fd0c87363 100644 --- a/app/Models/RecurringQuote.php +++ b/app/Models/RecurringQuote.php @@ -83,6 +83,7 @@ class RecurringQuote extends BaseModel protected $casts = [ 'line_items' => 'object', + 'backup' => 'object', 'settings' => 'object', 'updated_at' => 'timestamp', 'created_at' => 'timestamp', diff --git a/app/PaymentDrivers/AbstractPaymentDriver.php b/app/PaymentDrivers/AbstractPaymentDriver.php index 432b50af9de6..fa9393843ae1 100644 --- a/app/PaymentDrivers/AbstractPaymentDriver.php +++ b/app/PaymentDrivers/AbstractPaymentDriver.php @@ -16,8 +16,8 @@ abstract class AbstractPaymentDriver abstract public function authorize($payment_method); - abstract public function purchase(); + abstract public function purchase($amount, $return_client_response = false); - abstract public function refund(); + abstract public function refund($amount, $transaction_reference, $return_client_response = false); } \ No newline at end of file diff --git a/app/PaymentDrivers/Authorize/ChargePaymentProfile.php b/app/PaymentDrivers/Authorize/ChargePaymentProfile.php new file mode 100644 index 000000000000..8701e078ac20 --- /dev/null +++ b/app/PaymentDrivers/Authorize/ChargePaymentProfile.php @@ -0,0 +1,104 @@ +authorize = $authorize; + } + + + function chargeCustomerProfile($profile_id, $payment_profile_id, $amount) + { + + $this->authorize->init(); + + // Set the transaction's refId + $refId = 'ref' . time(); + + $profileToCharge = new CustomerProfilePaymentType(); + $profileToCharge->setCustomerProfileId($profile_id); + $paymentProfile = new PaymentProfileType(); + $paymentProfile->setPaymentProfileId($payment_profile_id); + $profileToCharge->setPaymentProfile($paymentProfile); + + $transactionRequestType = new TransactionRequestType(); + $transactionRequestType->setTransactionType("authCaptureTransaction"); + $transactionRequestType->setAmount($amount); + $transactionRequestType->setProfile($profileToCharge); + + $request = new CreateTransactionRequest(); + $request->setMerchantAuthentication($this->authorize->merchant_authentication); + $request->setRefId( $refId); + $request->setTransactionRequest( $transactionRequestType); + $controller = new CreateTransactionController($request); + $response = $controller->executeWithApiResponse($this->authorize->mode()); + + + if($response != null &&$response->getMessages()->getResultCode() == "Ok") + { + $tresponse = $response->getTransactionResponse(); + + if ($tresponse != null && $tresponse->getMessages() != null) + { + echo " Transaction Response code : " . $tresponse->getResponseCode() . "\n"; + echo "Charge Customer Profile APPROVED :" . "\n"; + echo " Charge Customer Profile AUTH CODE : " . $tresponse->getAuthCode() . "\n"; + echo " Charge Customer Profile TRANS ID : " . $tresponse->getTransId() . "\n"; + echo " Code : " . $tresponse->getMessages()[0]->getCode() . "\n"; + echo " Description : " . $tresponse->getMessages()[0]->getDescription() . "\n"; + } + 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"; + } + } + } + else + { + echo "Transaction Failed \n"; + $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"; + } + else + { + echo " Error code : " . $response->getMessages()->getMessage()[0]->getCode() . "\n"; + echo " Error message : " . $response->getMessages()->getMessage()[0]->getText() . "\n"; + } + } + } + + } \ No newline at end of file diff --git a/app/PaymentDrivers/Authorize/RefundTransaction.php b/app/PaymentDrivers/Authorize/RefundTransaction.php new file mode 100644 index 000000000000..1b0772bdf2e7 --- /dev/null +++ b/app/PaymentDrivers/Authorize/RefundTransaction.php @@ -0,0 +1,113 @@ +authorize = $authorize; + } + + function refundTransaction($transaction_reference, $amount, $payment_profile_id, $profile_id) + { + + $this->authorize->init(); + + // Set the transaction's refId + $refId = 'ref' . time(); + + $paymentProfile = new PaymentProfileType(); + $paymentProfile->setPaymentProfileId( $payment_profile_id ); + + // set customer profile + $customerProfile = new CustomerProfilePaymentType(); + $customerProfile->setCustomerProfileId( $profile_id ); + $customerProfile->setPaymentProfile( $paymentProfile ); + + //create a transaction + $transactionRequest = new TransactionRequestType(); + $transactionRequest->setTransactionType("refundTransaction"); + $transactionRequest->setAmount($amount); + $transactionRequest->setProfile($customerProfile); + $transactionRequest->setRefTransId($transaction_reference); + + $request = new CreateTransactionRequest(); + $request->setMerchantAuthentication($this->authorize->merchant_authentication); + $request->setRefId($refId); + $request->setTransactionRequest($transactionRequest); + $controller = new CreateTransactionController($request); + $response = $controller->executeWithApiResponse($this->authorize->mode()); + + if ($response != null) + { + if($response->getMessages()->getResultCode() == "Ok") + { + $tresponse = $response->getTransactionResponse(); + + 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"; + } + 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"; + } + } + } + else + { + echo "Transaction Failed \n"; + $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"; + } + else + { + echo " Error code : " . $response->getMessages()->getMessage()[0]->getCode() . "\n"; + echo " Error message : " . $response->getMessages()->getMessage()[0]->getText() . "\n"; + } + } + } + else + { + echo "No response returned \n"; + } + + return $response; + } + + +} \ No newline at end of file diff --git a/app/PaymentDrivers/AuthorizePaymentDriver.php b/app/PaymentDrivers/AuthorizePaymentDriver.php index af585d035b37..62560e07804d 100644 --- a/app/PaymentDrivers/AuthorizePaymentDriver.php +++ b/app/PaymentDrivers/AuthorizePaymentDriver.php @@ -86,23 +86,30 @@ class AuthorizePaymentDriver extends BaseDriver public function authorizeResponseView(array $data) { - return (new AuthorizePaymentMethod($this))->authorizeResponseView($data['gateway_type_id'], $data); - } - public function authorize($payment_method) { - + return $this->authorizeView($payment_method); } - public function purchase() + public function processPaymentView($data) { } - public function refund() + public function processPaymentResponse($request) + { + + } + + public function purchase($amount, $return_client_response = false) + { + return false; + } + + public function refund($amount, $transaction_reference, $return_client_response = false) { } diff --git a/app/PaymentDrivers/BaseDriver.php b/app/PaymentDrivers/BaseDriver.php index 43cf26c9ab58..4c003978742b 100644 --- a/app/PaymentDrivers/BaseDriver.php +++ b/app/PaymentDrivers/BaseDriver.php @@ -17,7 +17,6 @@ use App\Models\CompanyGateway; use App\PaymentDrivers\AbstractPaymentDriver; use App\Utils\Traits\MakesHash; use App\Utils\Traits\SystemLogTrait; -use Omnipay\Omnipay; /** * Class BaseDriver @@ -33,17 +32,21 @@ class BaseDriver extends AbstractPaymentDriver public $company_gateway; /* The Invitation */ - protected $invitation; + public $invitation; /* Gateway capabilities */ - protected $refundable = false; + public $refundable = false; /* Token billing */ - protected $token_billing = false; + public $token_billing = false; /* Authorise payment methods */ - protected $can_authorise_credit_card = false; + public $can_authorise_credit_card = false; + /* The client */ + public $client; + + public $payment_method; public function __construct(CompanyGateway $company_gateway, Client $client = null, $invitation = false) { @@ -54,10 +57,52 @@ class BaseDriver extends AbstractPaymentDriver $this->client = $client; } - + /** + * Authorize a payment method. + * + * Returns a reusable token for storage for future payments + * @param const $payment_method the GatewayType::constant + * @return view Return a view for collecting payment method information + */ public function authorize($payment_method) {} - public function purchase() {} + /** + * Executes purchase attempt for a given amount + * + * @param float $amount The amount to be collected + * @param boolean $return_client_response Whether the method needs to return a response (otherwise we assume an unattended payment) + * @return mixed + */ + public function purchase($amount, $return_client_response = false) {} - public function refund() {} + /** + * Executes a refund attempt for a given amount with a transaction_reference + * + * @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) {} + + /** + * Set the inbound request payment method type for access. + * + * @param int $payment_method_id The Payment Method ID + */ + public function setPaymentMethod($payment_method_id) + { + $this->payment_method = $payment_method_id; + return $this; + } + + /** + * Get the payment method ID + * + * @return int The payment method ID + */ + public function getPaymentMethod() + { + return $this->payment_method; + } } diff --git a/app/Services/Invoice/HandleCancellation.php b/app/Services/Invoice/HandleCancellation.php index 867cd189e2d7..4b206867ea34 100644 --- a/app/Services/Invoice/HandleCancellation.php +++ b/app/Services/Invoice/HandleCancellation.php @@ -45,6 +45,9 @@ class HandleCancellation extends AbstractService } $adjustment = $this->invoice->balance*-1; + + $this->backupCancellation($adjustment); + //set invoice balance to 0 $this->invoice->ledger()->updateInvoiceBalance($adjustment, "Invoice cancellation"); @@ -56,6 +59,58 @@ class HandleCancellation extends AbstractService event(new InvoiceWasCancelled($this->invoice)); + return $this->invoice; } + + public function reverse() + { + + $cancellation = $this->invoice->backup->cancellation; + + $adjustment = $cancellation->adjustment*-1; + + $this->invoice->ledger()->updateInvoiceBalance($adjustment, "Invoice cancellation REVERSAL"); + + /* Reverse the invoice status and balance */ + $this->invoice->balance += $adjustment; + $this->invoice->status_id = $cancellation->status_id; + + $this->invoice->client->service()->updateBalance($adjustment)->save(); + + /* Pop the cancellation out of the backup*/ + $backup = $this->invoice->backup; + unset($backup->cancellation); + $this->invoice->backup = $backup; + $this->invoice->save(); + + return $this->invoice; + + } + + /** + * Backup the cancellation in case we ever need to reverse it. + * + * @param float $adjustment The amount the balance has been reduced by to cancel the invoice + * @return void + */ + private function backupCancellation($adjustment) + { + + if(!is_object($this->invoice->backup)){ + $backup = new \stdClass; + $this->invoice->backup = $backup; + } + + $cancellation = new \stdClass; + $cancellation->adjustment = $adjustment; + $cancellation->status_id = $this->invoice->status_id; + + $invoice_backup = $this->invoice->backup; + $invoice_backup->cancellation = $cancellation; + + $this->invoice->backup = $invoice_backup; + $this->invoice->save(); + + } } diff --git a/app/Services/Invoice/HandleReversal.php b/app/Services/Invoice/HandleReversal.php index a72d313772a7..00989431d425 100644 --- a/app/Services/Invoice/HandleReversal.php +++ b/app/Services/Invoice/HandleReversal.php @@ -44,12 +44,14 @@ class HandleReversal extends AbstractService return $this->invoice; } + if($this->invoice->status_id == Invoice::STATUS_CANCELLED) + $this->invoice = $this->invoice->service()->reverseCancellation()->save(); + $balance_remaining = $this->invoice->balance; $total_paid = $this->invoice->amount - $this->invoice->balance; /*Adjust payment applied and the paymentables to the correct amount */ - $paymentables = Paymentable::wherePaymentableType(Invoice::class) ->wherePaymentableId($this->invoice->id) ->get(); @@ -88,10 +90,12 @@ class HandleReversal extends AbstractService $credit->service()->markSent()->save(); } - /* Set invoice balance to 0 */ - $this->invoice->ledger()->updateInvoiceBalance($balance_remaining*-1, $notes)->save(); - $this->invoice->balance= 0; + /* Set invoice balance to 0 */ + if($this->invoice->balance != 0) + $this->invoice->ledger()->updateInvoiceBalance($balance_remaining*-1, $notes)->save(); + + $this->invoice->balance=0; /* Set invoice status to reversed... somehow*/ $this->invoice->service()->setStatus(Invoice::STATUS_REVERSED)->save(); @@ -109,6 +113,42 @@ class HandleReversal extends AbstractService return $this->invoice; //create a ledger row for this with the resulting Credit ( also include an explanation in the notes section ) } + + + // public function run2() + // { + + // /* Check again!! */ + // if (!$this->invoice->invoiceReversable($this->invoice)) { + // return $this->invoice; + // } + + // if($this->invoice->status_id == Invoice::STATUS_CANCELLED) + // $this->invoice = $this->invoice->service()->reverseCancellation()->save(); + + // //$balance_remaining = $this->invoice->balance; + + // //$total_paid = $this->invoice->amount - $this->invoice->balance; + + // /*Adjust payment applied and the paymentables to the correct amount */ + // $paymentables = Paymentable::wherePaymentableType(Invoice::class) + // ->wherePaymentableId($this->invoice->id) + // ->get(); + + // $total_paid = 0; + + // $paymentables->each(function ($paymentable) use ($total_paid) { + + // $reversable_amount = $paymentable->amount - $paymentable->refunded; + // $total_paid -= $reversable_amount; + // $paymentable->amount = $paymentable->refunded; + // $paymentable->save(); + // }); + + // //Unwinding any payments made to this invoice + + + // } } -// The client paid to date amount is reduced by the calculated amount of (invoice balance - invoice amount). + \ No newline at end of file diff --git a/app/Services/Invoice/InvoiceService.php b/app/Services/Invoice/InvoiceService.php index 589f6a3e24c7..f0b3158618bd 100644 --- a/app/Services/Invoice/InvoiceService.php +++ b/app/Services/Invoice/InvoiceService.php @@ -129,6 +129,13 @@ class InvoiceService return $this; } + public function reverseCancellation() + { + $this->invoice = (new HandleCancellation($this->invoice))->reverse(); + + return $this; + } + public function markViewed() { $this->invoice->last_viewed = Carbon::now()->format('Y-m-d H:i'); diff --git a/app/Transformers/CompanyTransformer.php b/app/Transformers/CompanyTransformer.php index ab72a3b0bdd6..96e7d2be7038 100644 --- a/app/Transformers/CompanyTransformer.php +++ b/app/Transformers/CompanyTransformer.php @@ -121,6 +121,7 @@ class CompanyTransformer extends EntityTransformer 'slack_webhook_url' => (string)$company->slack_webhook_url, 'google_analytics_url' => (string)$company->google_analytics_key, //@deprecate 'google_analytics_key' => (string)$company->google_analytics_key, + 'enabled_item_tax_rates' => (int) $company->enabled_item_tax_rates ]; } diff --git a/app/Utils/Traits/Invoice/ActionsInvoice.php b/app/Utils/Traits/Invoice/ActionsInvoice.php index 78c344def9de..fb523b8227c1 100644 --- a/app/Utils/Traits/Invoice/ActionsInvoice.php +++ b/app/Utils/Traits/Invoice/ActionsInvoice.php @@ -17,7 +17,10 @@ trait ActionsInvoice { public function invoiceDeletable($invoice) :bool { - if ($invoice->status_id <= Invoice::STATUS_SENT && $invoice->is_deleted == false && $invoice->deleted_at == null && $invoice->balance == 0) { + if ($invoice->status_id <= Invoice::STATUS_SENT && + $invoice->is_deleted == false && + $invoice->deleted_at == null && + $invoice->balance == 0) { return true; } @@ -26,7 +29,10 @@ trait ActionsInvoice public function invoiceCancellable($invoice) :bool { - if (($invoice->status_id == Invoice::STATUS_SENT || $invoice->status_id == Invoice::STATUS_PARTIAL) && $invoice->is_deleted == false && $invoice->deleted_at == null) { + if (($invoice->status_id == Invoice::STATUS_SENT || + $invoice->status_id == Invoice::STATUS_PARTIAL) && + $invoice->is_deleted == false && + $invoice->deleted_at == null) { return true; } @@ -35,7 +41,12 @@ trait ActionsInvoice public function invoiceReversable($invoice) :bool { - if (($invoice->status_id == Invoice::STATUS_SENT || $invoice->status_id == Invoice::STATUS_PARTIAL || $invoice->status_id == Invoice::STATUS_PAID) && $invoice->is_deleted == false && $invoice->deleted_at == null) { + if (($invoice->status_id == Invoice::STATUS_SENT || + $invoice->status_id == Invoice::STATUS_PARTIAL || + $invoice->status_id == Invoice::STATUS_CANCELLED || + $invoice->status_id == Invoice::STATUS_PAID) && + $invoice->is_deleted == false && + $invoice->deleted_at == null) { return true; } diff --git a/composer.json b/composer.json index 39a99a6e92c5..f335a7735fda 100644 --- a/composer.json +++ b/composer.json @@ -21,6 +21,7 @@ "php": ">=7.3", "ext-json": "*", "asgrim/ofxparser": "^1.2", + "authorizenet/authorizenet": "^2.0", "beganovich/omnipay-checkout": "dev-master", "cleverit/ubl_invoice": "^1.3", "composer/composer": "^1.10", @@ -53,7 +54,7 @@ "spatie/browsershot": "^3.29", "staudenmeir/eloquent-has-many-deep": "^1.11", "stripe/stripe-php": "^7.0", - "turbo124/beacon": "^0", + "turbo124/beacon": "^1", "webpatser/laravel-countries": "dev-master#75992ad", "yajra/laravel-datatables-oracle": "~9.0" }, diff --git a/composer.lock b/composer.lock index f2b241ba5897..34bb1de41415 100644 --- a/composer.lock +++ b/composer.lock @@ -4,7 +4,7 @@ "Read more about it at https://getcomposer.org/doc/01-basic-usage.md#installing-dependencies", "This file is @generated automatically" ], - "content-hash": "723f03b92457a3f3410083e2b42f96c3", + "content-hash": "6441fc634b3600e7099ae8c02d6230b0", "packages": [ { "name": "asgrim/ofxparser", @@ -63,17 +63,60 @@ "time": "2018-10-29T10:10:13+00:00" }, { - "name": "aws/aws-sdk-php", - "version": "3.140.4", + "name": "authorizenet/authorizenet", + "version": "2.0.0", "source": { "type": "git", - "url": "https://github.com/aws/aws-sdk-php.git", - "reference": "298ec070adad5760c4b90348219bb3e6bd7a9322" + "url": "https://github.com/AuthorizeNet/sdk-php.git", + "reference": "7fa78e6397d363296e462c3b348573c17175b7a8" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/aws/aws-sdk-php/zipball/298ec070adad5760c4b90348219bb3e6bd7a9322", - "reference": "298ec070adad5760c4b90348219bb3e6bd7a9322", + "url": "https://api.github.com/repos/AuthorizeNet/sdk-php/zipball/7fa78e6397d363296e462c3b348573c17175b7a8", + "reference": "7fa78e6397d363296e462c3b348573c17175b7a8", + "shasum": "" + }, + "require": { + "ext-curl": "*", + "ext-json": "*", + "php": ">=5.6" + }, + "require-dev": { + "phpmd/phpmd": "~2.0", + "phpunit/phpunit": "~4.0" + }, + "type": "library", + "autoload": { + "classmap": [ + "lib" + ] + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "proprietary" + ], + "description": "Official PHP SDK for Authorize.Net", + "homepage": "http://developer.authorize.net", + "keywords": [ + "authorize.net", + "authorizenet", + "ecommerce", + "payment" + ], + "time": "2019-01-14T13:32:41+00:00" + }, + { + "name": "aws/aws-sdk-php", + "version": "3.142.1", + "source": { + "type": "git", + "url": "https://github.com/aws/aws-sdk-php.git", + "reference": "ab92ec111132712417cc97be06275553b10a76ab" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/aws/aws-sdk-php/zipball/ab92ec111132712417cc97be06275553b10a76ab", + "reference": "ab92ec111132712417cc97be06275553b10a76ab", "shasum": "" }, "require": { @@ -96,6 +139,7 @@ "ext-pcntl": "*", "ext-sockets": "*", "nette/neon": "^2.3", + "paragonie/random_compat": ">= 2", "phpunit/phpunit": "^4.8.35|^5.4.3", "psr/cache": "^1.0", "psr/simple-cache": "^1.0", @@ -144,7 +188,7 @@ "s3", "sdk" ], - "time": "2020-06-09T18:11:16+00:00" + "time": "2020-06-12T18:16:31+00:00" }, { "name": "beganovich/omnipay-checkout", @@ -4214,16 +4258,16 @@ }, { "name": "php-http/discovery", - "version": "1.7.4", + "version": "1.8.0", "source": { "type": "git", "url": "https://github.com/php-http/discovery.git", - "reference": "82dbef649ccffd8e4f22e1953c3a5265992b83c0" + "reference": "10d9019f393773345aedc0dc79e7fd678da874ee" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/php-http/discovery/zipball/82dbef649ccffd8e4f22e1953c3a5265992b83c0", - "reference": "82dbef649ccffd8e4f22e1953c3a5265992b83c0", + "url": "https://api.github.com/repos/php-http/discovery/zipball/10d9019f393773345aedc0dc79e7fd678da874ee", + "reference": "10d9019f393773345aedc0dc79e7fd678da874ee", "shasum": "" }, "require": { @@ -4275,7 +4319,7 @@ "message", "psr7" ], - "time": "2020-01-03T11:25:47+00:00" + "time": "2020-06-14T10:44:12+00:00" }, { "name": "php-http/guzzle6-adapter", @@ -6009,16 +6053,16 @@ }, { "name": "stripe/stripe-php", - "version": "v7.37.0", + "version": "v7.37.1", "source": { "type": "git", "url": "https://github.com/stripe/stripe-php.git", - "reference": "246871743edb26c7a7657784205218daf7d99a73" + "reference": "e3e29131a131785c3d2f85556b0154e8170e9bba" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/stripe/stripe-php/zipball/246871743edb26c7a7657784205218daf7d99a73", - "reference": "246871743edb26c7a7657784205218daf7d99a73", + "url": "https://api.github.com/repos/stripe/stripe-php/zipball/e3e29131a131785c3d2f85556b0154e8170e9bba", + "reference": "e3e29131a131785c3d2f85556b0154e8170e9bba", "shasum": "" }, "require": { @@ -6062,7 +6106,7 @@ "payment processing", "stripe" ], - "time": "2020-06-09T22:55:43+00:00" + "time": "2020-06-11T16:27:35+00:00" }, { "name": "swiftmailer/swiftmailer", @@ -6128,7 +6172,7 @@ }, { "name": "symfony/console", - "version": "v4.4.9", + "version": "v4.4.10", "source": { "type": "git", "url": "https://github.com/symfony/console.git", @@ -6219,7 +6263,7 @@ }, { "name": "symfony/css-selector", - "version": "v5.1.0", + "version": "v5.1.1", "source": { "type": "git", "url": "https://github.com/symfony/css-selector.git", @@ -6286,7 +6330,7 @@ }, { "name": "symfony/debug", - "version": "v4.4.9", + "version": "v4.4.10", "source": { "type": "git", "url": "https://github.com/symfony/debug.git", @@ -6417,7 +6461,7 @@ }, { "name": "symfony/error-handler", - "version": "v4.4.9", + "version": "v4.4.10", "source": { "type": "git", "url": "https://github.com/symfony/error-handler.git", @@ -6488,7 +6532,7 @@ }, { "name": "symfony/event-dispatcher", - "version": "v4.4.9", + "version": "v4.4.10", "source": { "type": "git", "url": "https://github.com/symfony/event-dispatcher.git", @@ -6630,7 +6674,7 @@ }, { "name": "symfony/filesystem", - "version": "v5.1.0", + "version": "v5.1.1", "source": { "type": "git", "url": "https://github.com/symfony/filesystem.git", @@ -6694,7 +6738,7 @@ }, { "name": "symfony/finder", - "version": "v4.4.9", + "version": "v4.4.10", "source": { "type": "git", "url": "https://github.com/symfony/finder.git", @@ -6757,7 +6801,7 @@ }, { "name": "symfony/http-foundation", - "version": "v4.4.9", + "version": "v4.4.10", "source": { "type": "git", "url": "https://github.com/symfony/http-foundation.git", @@ -6826,16 +6870,16 @@ }, { "name": "symfony/http-kernel", - "version": "v4.4.9", + "version": "v4.4.10", "source": { "type": "git", "url": "https://github.com/symfony/http-kernel.git", - "reference": "54526b598d7fc86a67850488b194a88a79ab8467" + "reference": "81d42148474e1852a333ed7a732f2a014af75430" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/symfony/http-kernel/zipball/54526b598d7fc86a67850488b194a88a79ab8467", - "reference": "54526b598d7fc86a67850488b194a88a79ab8467", + "url": "https://api.github.com/repos/symfony/http-kernel/zipball/81d42148474e1852a333ed7a732f2a014af75430", + "reference": "81d42148474e1852a333ed7a732f2a014af75430", "shasum": "" }, "require": { @@ -6927,20 +6971,20 @@ "type": "tidelift" } ], - "time": "2020-05-31T05:25:51+00:00" + "time": "2020-06-12T11:15:37+00:00" }, { "name": "symfony/mime", - "version": "v5.1.0", + "version": "v5.1.1", "source": { "type": "git", "url": "https://github.com/symfony/mime.git", - "reference": "56261f89385f9d13cf843a5101ac72131190bc91" + "reference": "c0c418f05e727606e85b482a8591519c4712cf45" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/symfony/mime/zipball/56261f89385f9d13cf843a5101ac72131190bc91", - "reference": "56261f89385f9d13cf843a5101ac72131190bc91", + "url": "https://api.github.com/repos/symfony/mime/zipball/c0c418f05e727606e85b482a8591519c4712cf45", + "reference": "c0c418f05e727606e85b482a8591519c4712cf45", "shasum": "" }, "require": { @@ -7004,11 +7048,11 @@ "type": "tidelift" } ], - "time": "2020-05-25T12:33:44+00:00" + "time": "2020-06-09T15:07:35+00:00" }, { "name": "symfony/options-resolver", - "version": "v5.1.0", + "version": "v5.1.1", "source": { "type": "git", "url": "https://github.com/symfony/options-resolver.git", @@ -7662,7 +7706,7 @@ }, { "name": "symfony/process", - "version": "v4.4.9", + "version": "v4.4.10", "source": { "type": "git", "url": "https://github.com/symfony/process.git", @@ -7725,7 +7769,7 @@ }, { "name": "symfony/routing", - "version": "v4.4.9", + "version": "v4.4.10", "source": { "type": "git", "url": "https://github.com/symfony/routing.git", @@ -7887,7 +7931,7 @@ }, { "name": "symfony/translation", - "version": "v4.4.9", + "version": "v4.4.10", "source": { "type": "git", "url": "https://github.com/symfony/translation.git", @@ -8048,7 +8092,7 @@ }, { "name": "symfony/var-dumper", - "version": "v4.4.9", + "version": "v4.4.10", "source": { "type": "git", "url": "https://github.com/symfony/var-dumper.git", @@ -8188,16 +8232,16 @@ }, { "name": "turbo124/beacon", - "version": "0.83", + "version": "1.0.0", "source": { "type": "git", "url": "https://github.com/turbo124/beacon.git", - "reference": "97157e507fcca352d1cc445b8a3a1970ec448eee" + "reference": "21e1ba46776fae8dc4bcf672890b257e3452be59" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/turbo124/beacon/zipball/97157e507fcca352d1cc445b8a3a1970ec448eee", - "reference": "97157e507fcca352d1cc445b8a3a1970ec448eee", + "url": "https://api.github.com/repos/turbo124/beacon/zipball/21e1ba46776fae8dc4bcf672890b257e3452be59", + "reference": "21e1ba46776fae8dc4bcf672890b257e3452be59", "shasum": "" }, "require": { @@ -8244,7 +8288,7 @@ "lightlogs", "turbo124" ], - "time": "2020-06-09T07:24:25+00:00" + "time": "2020-06-10T22:55:22+00:00" }, { "name": "vlucas/phpdotenv", @@ -8925,16 +8969,16 @@ }, { "name": "filp/whoops", - "version": "2.7.2", + "version": "2.7.3", "source": { "type": "git", "url": "https://github.com/filp/whoops.git", - "reference": "17d0d3f266c8f925ebd035cd36f83cf802b47d4a" + "reference": "5d5fe9bb3d656b514d455645b3addc5f7ba7714d" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/filp/whoops/zipball/17d0d3f266c8f925ebd035cd36f83cf802b47d4a", - "reference": "17d0d3f266c8f925ebd035cd36f83cf802b47d4a", + "url": "https://api.github.com/repos/filp/whoops/zipball/5d5fe9bb3d656b514d455645b3addc5f7ba7714d", + "reference": "5d5fe9bb3d656b514d455645b3addc5f7ba7714d", "shasum": "" }, "require": { @@ -8982,7 +9026,7 @@ "throwable", "whoops" ], - "time": "2020-05-05T12:28:07+00:00" + "time": "2020-06-14T09:00:00+00:00" }, { "name": "hamcrest/hamcrest-php", @@ -10688,16 +10732,16 @@ }, { "name": "swagger-api/swagger-ui", - "version": "v3.26.0", + "version": "v3.26.2", "source": { "type": "git", "url": "https://github.com/swagger-api/swagger-ui.git", - "reference": "b9064157e710d0c56d4459b5a7c16751ad0ae72c" + "reference": "ae33deeaab47129844b89192d35762abf5cf80fb" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/swagger-api/swagger-ui/zipball/b9064157e710d0c56d4459b5a7c16751ad0ae72c", - "reference": "b9064157e710d0c56d4459b5a7c16751ad0ae72c", + "url": "https://api.github.com/repos/swagger-api/swagger-ui/zipball/ae33deeaab47129844b89192d35762abf5cf80fb", + "reference": "ae33deeaab47129844b89192d35762abf5cf80fb", "shasum": "" }, "type": "library", @@ -10741,11 +10785,11 @@ "swagger", "ui" ], - "time": "2020-06-05T00:57:11+00:00" + "time": "2020-06-12T13:09:03+00:00" }, { "name": "symfony/yaml", - "version": "v4.4.9", + "version": "v4.4.10", "source": { "type": "git", "url": "https://github.com/symfony/yaml.git", diff --git a/config/beacon.php b/config/beacon.php index 884266b8f62c..e84902dd71e4 100644 --- a/config/beacon.php +++ b/config/beacon.php @@ -36,7 +36,8 @@ return [ 'system_logging' => [ 'Turbo124\Beacon\Jobs\System\CpuMetric', 'Turbo124\Beacon\Jobs\System\HdMetric', - 'Turbo124\Beacon\Jobs\System\MemMetric' + 'Turbo124\Beacon\Jobs\System\MemMetric', + 'App\Jobs\Ninja\CheckDbStatus', ], ]; \ No newline at end of file diff --git a/config/ninja.php b/config/ninja.php index 62122a5c2730..d2a5bed810ff 100644 --- a/config/ninja.php +++ b/config/ninja.php @@ -9,6 +9,7 @@ return [ 'version_url' => 'https://raw.githubusercontent.com/invoiceninja/invoiceninja/v2/VERSION.txt', 'app_name' => env('APP_NAME'), 'app_env' => env('APP_ENV', 'local'), + 'require_https' => env('REQUIRE_HTTPS', true), 'app_url' => env('APP_URL', ''), 'app_domain' => env('APP_DOMAIN', ''), 'app_version' => '5.0.4', 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 5c773db50605..f01254ba61b4 100644 --- a/database/migrations/2014_10_13_000000_create_users_table.php +++ b/database/migrations/2014_10_13_000000_create_users_table.php @@ -166,6 +166,7 @@ class CreateUsersTable extends Migration $table->string('subdomain')->nullable(); $table->string('db')->nullable(); $table->unsignedInteger('size_id')->nullable(); + $table->unsignedInteger('enabled_item_tax_rates')->nullable(); $table->string('first_day_of_week')->nullable(); $table->string('first_month_of_year')->nullable(); $table->string('portal_mode')->default('subdomain'); @@ -454,6 +455,7 @@ class CreateUsersTable extends Migration $t->boolean('is_deleted')->default(false); $t->mediumText('line_items')->nullable(); + $t->mediumText('backup')->nullable(); $t->text('footer')->nullable(); $t->text('public_notes')->nullable(); $t->text('private_notes')->nullable(); @@ -530,6 +532,7 @@ class CreateUsersTable extends Migration $t->boolean('is_deleted')->default(false); $t->mediumText('line_items')->nullable(); + $t->mediumText('backup')->nullable(); $t->text('footer')->nullable(); $t->text('public_notes')->nullable(); $t->text('private_notes')->nullable(); @@ -633,6 +636,7 @@ class CreateUsersTable extends Migration $t->boolean('is_deleted')->default(false); $t->mediumText('line_items')->nullable(); + $t->mediumText('backup')->nullable(); $t->text('footer')->nullable(); $t->text('public_notes')->nullable(); $t->text('private_notes')->nullable(); @@ -699,6 +703,7 @@ class CreateUsersTable extends Migration $t->boolean('is_deleted')->default(false); $t->mediumText('line_items')->nullable(); + $t->mediumText('backup')->nullable(); $t->text('footer')->nullable(); $t->text('public_notes')->nullable(); @@ -770,7 +775,7 @@ class CreateUsersTable extends Migration $t->boolean('is_deleted')->default(false); $t->mediumText('line_items')->nullable(); - + $t->mediumText('backup')->nullable(); $t->text('footer')->nullable(); $t->text('public_notes')->nullable(); diff --git a/database/migrations/2020_05_13_035355_add_google_refresh_token_to_users_table.php b/database/migrations/2020_05_13_035355_add_google_refresh_token_to_users_table.php index 09131c84e437..20e97c469cf3 100644 --- a/database/migrations/2020_05_13_035355_add_google_refresh_token_to_users_table.php +++ b/database/migrations/2020_05_13_035355_add_google_refresh_token_to_users_table.php @@ -20,6 +20,10 @@ class AddGoogleRefreshTokenToUsersTable extends Migration DB::statement("alter table users modify column oauth_user_token text"); + Schema::table('companies', function (Blueprint $table){ + $table->integer('enabled_item_tax_rates')->default(0); + }); + } /** diff --git a/resources/views/index/index.blade.php b/resources/views/index/index.blade.php index 07fbd1bca63b..48236cbcb726 100644 --- a/resources/views/index/index.blade.php +++ b/resources/views/index/index.blade.php @@ -16,7 +16,7 @@ } - +
Loading... diff --git a/resources/views/portal/ninja2020/gateways/authorize/add_credit_card.blade.php b/resources/views/portal/ninja2020/gateways/authorize/add_credit_card.blade.php index 804b3b68528d..aaeba35c1aaf 100644 --- a/resources/views/portal/ninja2020/gateways/authorize/add_credit_card.blade.php +++ b/resources/views/portal/ninja2020/gateways/authorize/add_credit_card.blade.php @@ -81,7 +81,7 @@
- +
diff --git a/tests/Unit/CompareObjectTest.php b/tests/Unit/CompareObjectTest.php index 8da8373e8fad..b5e32e605400 100644 --- a/tests/Unit/CompareObjectTest.php +++ b/tests/Unit/CompareObjectTest.php @@ -51,6 +51,6 @@ class CompareObjectTest extends TestCase $this->assertEquals($settings->timezone_id, 1); $this->assertEquals($settings->language_id, 1); $this->assertEquals($settings->payment_terms, -1); - $this->assertFalse($settings->send_portal_password); + $this->assertFalse($settings->auto_archive_invoice); } }