diff --git a/app/Import/Transformer/Csv/InvoiceTransformer.php b/app/Import/Transformer/Csv/InvoiceTransformer.php index b7a069ea19d6..50a85a0922ca 100644 --- a/app/Import/Transformer/Csv/InvoiceTransformer.php +++ b/app/Import/Transformer/Csv/InvoiceTransformer.php @@ -93,7 +93,7 @@ class InvoiceTransformer extends BaseTransformer 'invoice.custom_value4' ), 'footer' => $this->getString($invoice_data, 'invoice.footer'), - 'partial' => $this->getFloat($invoice_data, 'invoice.partial') > 0 ?: null, + 'partial' => $this->getFloat($invoice_data, 'invoice.partial') > 0 ? $this->getFloat($invoice_data, 'invoice.partial') : null, 'partial_due_date' => isset($invoice_data['invoice.partial_due_date']) ? $this->parseDate($invoice_data['invoice.partial_due_date']) : null, 'custom_surcharge1' => $this->getFloat( $invoice_data, diff --git a/app/Import/Transformer/Csv/RecurringInvoiceTransformer.php b/app/Import/Transformer/Csv/RecurringInvoiceTransformer.php index 9750bd434292..74f1a9b05ff1 100644 --- a/app/Import/Transformer/Csv/RecurringInvoiceTransformer.php +++ b/app/Import/Transformer/Csv/RecurringInvoiceTransformer.php @@ -99,7 +99,7 @@ class RecurringInvoiceTransformer extends BaseTransformer 'invoice.custom_value4' ), 'footer' => $this->getString($invoice_data, 'invoice.footer'), - 'partial' => $this->getFloat($invoice_data, 'invoice.partial') > 0 ?: null, + 'partial' => $this->getFloat($invoice_data, 'invoice.partial') > 0 ? $this->getFloat($invoice_data, 'invoice.partial') : null, 'partial_due_date' => isset($invoice_data['invoice.partial_due_date']) ? $this->parseDate($invoice_data['invoice.partial_due_date']) : null, 'custom_surcharge1' => $this->getString( $invoice_data, diff --git a/app/PaymentDrivers/Stripe/Jobs/PaymentIntentFailureWebhook.php b/app/PaymentDrivers/Stripe/Jobs/PaymentIntentFailureWebhook.php index 2dd7aa420e31..d804bc8e964d 100644 --- a/app/PaymentDrivers/Stripe/Jobs/PaymentIntentFailureWebhook.php +++ b/app/PaymentDrivers/Stripe/Jobs/PaymentIntentFailureWebhook.php @@ -57,20 +57,17 @@ class PaymentIntentFailureWebhook implements ShouldQueue $company = Company::query()->where('company_key', $this->company_key)->first(); foreach ($this->stripe_request as $transaction) { - if (array_key_exists('payment_intent', $transaction)) { - $payment = Payment::query() - ->where('company_id', $company->id) - ->where(function ($query) use ($transaction) { - $query->where('transaction_reference', $transaction['payment_intent']) - ->orWhere('transaction_reference', $transaction['id']); - }) - ->first(); - } else { - $payment = Payment::query() - ->where('company_id', $company->id) - ->where('transaction_reference', $transaction['id']) - ->first(); - } + + + $payment = Payment::query() + ->where('company_id', $company->id) + ->when(isset($transaction['payment_intent']), function ($query) use ($transaction) { + $query->where('transaction_reference', $transaction['payment_intent']); + }) + ->when(isset($transaction['id']), function ($query) use ($transaction) { + $query->where('transaction_reference', $transaction['id']); + }) + ->first(); if ($payment) { $client = $payment->client; diff --git a/app/PaymentDrivers/Stripe/Jobs/PaymentIntentProcessingWebhook.php b/app/PaymentDrivers/Stripe/Jobs/PaymentIntentProcessingWebhook.php index 8c3cb35f3772..cce5ed08f91b 100644 --- a/app/PaymentDrivers/Stripe/Jobs/PaymentIntentProcessingWebhook.php +++ b/app/PaymentDrivers/Stripe/Jobs/PaymentIntentProcessingWebhook.php @@ -64,17 +64,17 @@ class PaymentIntentProcessingWebhook implements ShouldQueue $company = Company::query()->where('company_key', $this->company_key)->first(); foreach ($this->stripe_request as $transaction) { - if (array_key_exists('payment_intent', $transaction)) { - $payment = Payment::query() - ->where('company_id', $company->id) - ->where('transaction_reference', $transaction['payment_intent']) - ->first(); - } else { - $payment = Payment::query() - ->where('company_id', $company->id) - ->where('transaction_reference', $transaction['id']) - ->first(); - } + + $payment = Payment::query() + ->where('company_id', $company->id) + ->when(isset($transaction['payment_intent']), function ($query) use ($transaction) { + $query->where('transaction_reference', $transaction['payment_intent']); + }) + ->when(isset($transaction['id']), function ($query) use ($transaction) { + $query->where('transaction_reference', $transaction['id']); + }) + ->first(); + if ($payment) { $payment->status_id = Payment::STATUS_PENDING; diff --git a/app/PaymentDrivers/Stripe/Jobs/PaymentIntentWebhook.php b/app/PaymentDrivers/Stripe/Jobs/PaymentIntentWebhook.php index 7aecf4a21702..b078378b3215 100644 --- a/app/PaymentDrivers/Stripe/Jobs/PaymentIntentWebhook.php +++ b/app/PaymentDrivers/Stripe/Jobs/PaymentIntentWebhook.php @@ -63,17 +63,17 @@ class PaymentIntentWebhook implements ShouldQueue $company = Company::query()->where('company_key', $this->company_key)->first(); foreach ($this->stripe_request as $transaction) { - if (array_key_exists('payment_intent', $transaction)) { - $payment = Payment::query() - ->where('company_id', $company->id) - ->where('transaction_reference', $transaction['payment_intent']) - ->first(); - } else { - $payment = Payment::query() - ->where('company_id', $company->id) - ->where('transaction_reference', $transaction['id']) - ->first(); - } + + $payment = Payment::query() + ->where('company_id', $company->id) + ->when(isset($transaction['payment_intent']), function ($query) use ($transaction) { + $query->where('transaction_reference', $transaction['payment_intent']); + }) + ->when(isset($transaction['id']), function ($query) use ($transaction) { + $query->where('transaction_reference', $transaction['id']); + }) + ->first(); + if ($payment) { $payment->status_id = Payment::STATUS_COMPLETED; diff --git a/app/PaymentDrivers/StripePaymentDriver.php b/app/PaymentDrivers/StripePaymentDriver.php index c2d74d97f7a4..a9e62c0cf708 100644 --- a/app/PaymentDrivers/StripePaymentDriver.php +++ b/app/PaymentDrivers/StripePaymentDriver.php @@ -705,19 +705,17 @@ class StripePaymentDriver extends BaseDriver if ($request->type === 'charge.succeeded') { foreach ($request->data as $transaction) { - if (array_key_exists('payment_intent', $transaction) && $transaction['payment_intent']) { - $payment = Payment::query() - // ->where('company_id', $request->getCompany()->id) - ->where(function ($query) use ($transaction) { - $query->where('transaction_reference', $transaction['payment_intent']) - ->orWhere('transaction_reference', $transaction['id']); - }) - ->first(); - } else { - $payment = Payment::query() - ->where('transaction_reference', $transaction['id']) - ->first(); - } + + $payment = Payment::query() + ->where('company_id', $this->company_gateway->company_id) + ->when(isset($transaction['payment_intent']), function ($query) use ($transaction) { + $query->where('transaction_reference', $transaction['payment_intent']); + }) + ->when(isset($transaction['id']), function ($query) use ($transaction) { + $query->where('transaction_reference', $transaction['id']); + }) + ->first(); + if ($payment) { @@ -744,19 +742,17 @@ class StripePaymentDriver extends BaseDriver ], $this->stripe_connect_auth); if ($charge->captured) { - $payment = false; + + $payment = Payment::query() + ->where('company_id', $this->company_gateway->company_id) + ->when(isset($transaction['payment_intent']), function ($query) use ($transaction) { + $query->where('transaction_reference', $transaction['payment_intent']); + }) + ->when(isset($transaction['id']), function ($query) use ($transaction) { + $query->where('transaction_reference', $transaction['id']); + }) + ->first(); - if (isset($transaction['payment_intent'])) { - $payment = Payment::query() - ->where('transaction_reference', $transaction['payment_intent']) - ->where('company_id', $request->getCompany()->id) - ->first(); - } elseif (isset($transaction['id'])) { - $payment = Payment::query() - ->where('transaction_reference', $transaction['id']) - ->where('company_id', $request->getCompany()->id) - ->first(); - } if ($payment) { $payment->status_id = Payment::STATUS_COMPLETED; diff --git a/lang/en/texts.php b/lang/en/texts.php index aaf8fee7a0b9..ffc9c157cc7a 100644 --- a/lang/en/texts.php +++ b/lang/en/texts.php @@ -5303,7 +5303,7 @@ $lang = array( 'always_show_required_fields' => 'Allows show required fields form', 'always_show_required_fields_help' => 'Displays the required fields form always at checkout', 'advanced_cards' => 'Advanced Cards', - 'activity_140' => 'Statement sent to :client - [:notes]', + 'activity_140' => 'Statement sent to :client', ); return $lang; diff --git a/tests/Feature/TaskApiTest.php b/tests/Feature/TaskApiTest.php index ebd881225e51..5a82a3b63781 100644 --- a/tests/Feature/TaskApiTest.php +++ b/tests/Feature/TaskApiTest.php @@ -104,6 +104,33 @@ class TaskApiTest extends TestCase } } + public function testTimeLogWithSameStartAndStopTimes() + { + $settings = ClientSettings::defaults(); + $settings->default_task_rate = 41; + + $c = Client::factory()->create([ + 'user_id' => $this->user->id, + 'company_id' => $this->company->id, + 'settings' => $settings, + ]); + + $data = [ + 'client_id' => $c->hashed_id, + 'description' => 'Test Task', + 'time_log' => '[[1681165417,1681165432,"sumtin",true],[1681165446,1681165446]]', + ]; + + $response = $this->withHeaders([ + 'X-API-SECRET' => config('ninja.api_secret'), + 'X-API-TOKEN' => $this->token, + ])->postJson("/api/v1/tasks", $data); + + $response->assertStatus(200); + $arr = $response->json(); + + } + public function testRoundingViaApi() { diff --git a/tests/Unit/TaskRoundingTest.php b/tests/Unit/TaskRoundingTest.php new file mode 100644 index 000000000000..4ace3afa45df --- /dev/null +++ b/tests/Unit/TaskRoundingTest.php @@ -0,0 +1,73 @@ +task_round_to_nearest = 600; + + //calculated time = 7:10am + $rounded = 1714943400; + + $this->assertEquals($rounded, $this->roundTimeLog($start_time, $end_time)); + + } + + public function testRoundDown() + { + $start_time = 1714942800; + $end_time = 1714943220; //7:07am + $this->task_round_to_nearest = 600; + $this->task_round_up = false; + + //calculated time = 7:10am + $rounded = $start_time; + + $this->assertEquals($rounded, $this->roundTimeLog($start_time, $end_time)); + + } + + public function roundTimeLog(int $start_time, int $end_time): int + { + if($this->task_round_to_nearest == 1) + return $end_time; + + $interval = $end_time - $start_time; + + if($this->task_round_up) + return $start_time + (int)ceil($interval/$this->task_round_to_nearest)*$this->task_round_to_nearest; + + return $start_time - (int)floor($interval/$this->task_round_to_nearest) * $this->task_round_to_nearest; + + } + +}