Merge pull request #8866 from turbo124/v5-develop

v5.7.28
This commit is contained in:
David Bomba 2023-10-10 14:30:10 +11:00 committed by GitHub
commit fadd482341
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
28 changed files with 152 additions and 56 deletions

View File

@ -1 +1 @@
5.7.27
5.7.28

View File

@ -158,9 +158,7 @@ class ActivityExport extends BaseExport
$clean_row = [];
foreach (array_values($this->input['report_keys']) as $key => $value) {
nlog("key: {$key}, value: {$value}");
nlog($row);
$clean_row[$key]['entity'] = 'activity';
$clean_row[$key]['id'] = $key;
$clean_row[$key]['hashed_id'] = null;

View File

@ -115,7 +115,7 @@ class TaskExport extends BaseExport
$this->storage_array = [];
});
nlog($this->storage_item_array);
// nlog($this->storage_item_array);
return array_merge(['columns' => $header], $this->storage_item_array);
}

View File

@ -25,7 +25,8 @@ class GroupSettingFilters extends QueryFilters
* @return Builder
*/
public function name(string $name = ''): Builder
{nlog("filter");
{
if (strlen($name) == 0) {
return $this->builder;
}

View File

@ -53,12 +53,17 @@ class EpcQrGenerator
$this->validateFields();
$qr = $writer->writeString($this->encodeMessage(), 'utf-8');
return "<svg viewBox='0 0 200 200' width='200' height='200' x='0' y='0' xmlns='http://www.w3.org/2000/svg'>
<rect x='0' y='0' width='100%'' height='100%' />{$qr}</svg>";
} catch(\Throwable $e) {
return '';
} catch(\Exception $e) {
return '';
}
return "<svg viewBox='0 0 200 200' width='200' height='200' x='0' y='0' xmlns='http://www.w3.org/2000/svg'>
<rect x='0' y='0' width='100%'' height='100%' />{$qr}</svg>";
}
public function encodeMessage()

View File

@ -458,14 +458,15 @@ class ProductController extends BaseController
*/
public function bulk(BulkProductRequest $request)
{
/** @var \App\Models\User $user */
$user = auth()->user();
$action = $request->input('action');
$ids = $request->input('ids');
$products = Product::withTrashed()->whereIn('id', $ids);
nlog($products->count());
if($action == 'set_tax_id'){
$tax_id = $request->input('tax_id');
@ -475,8 +476,8 @@ class ProductController extends BaseController
return $this->listResponse(Product::withTrashed()->whereIn('id', $ids));
}
$products->cursor()->each(function ($product, $key) use ($action) {
if (auth()->user()->can('edit', $product)) {
$products->cursor()->each(function ($product, $key) use ($action, $user) {
if ($user->can('edit', $product)) {
$this->product_repo->{$action}($product);
}
});

View File

@ -99,7 +99,7 @@ class SearchController extends Controller
'name' => $invoice->client->present()->name() . ' - ' . $invoice->number,
'type' => '/invoice',
'id' => $invoice->hashed_id,
'path' => "/clients/{$invoice->hashed_id}/edit"
'path' => "/invoices/{$invoice->hashed_id}/edit"
];
}

View File

@ -182,7 +182,8 @@ class SetupController extends Controller
* @return Application|ResponseFactory|JsonResponse|Response
*/
public function checkDB(CheckDatabaseRequest $request)
{nlog("trying");
{
try {
$status = SystemHealth::dbCheck($request);

View File

@ -26,14 +26,21 @@ class StoreBankTransactionRequest extends Request
*/
public function authorize() : bool
{
return auth()->user()->can('create', BankTransaction::class);
/** @var \App\Models\User $user */
$user = auth()->user();
return $user->can('create', BankTransaction::class);
}
public function rules()
{
/** @var \App\Models\User $user */
$user = auth()->user();
$rules = [];
$rules['bank_integration_id'] = 'bail|required|exists:bank_integrations,id,company_id,'.auth()->user()->company()->id.',is_deleted,0';
$rules['bank_integration_id'] = 'bail|required|exists:bank_integrations,id,company_id,'.$user->company()->id.',is_deleted,0';
return $rules;
}

View File

@ -47,6 +47,9 @@ class BaseTransformer
public function parseDate($date)
{
if(stripos($date,"/") !== false && $this->company->settings->country_id != 840)
$date = str_replace('/', '-', $date);
try {
$parsed_date = Carbon::parse($date);

View File

@ -11,6 +11,7 @@
namespace App\Jobs\Ninja;
use App\Models\Payment;
use App\Libraries\MultiDB;
use Illuminate\Bus\Queueable;
use App\Models\ClientGatewayToken;
@ -74,6 +75,53 @@ class CheckACHStatus implements ShouldQueue
}
});
Payment::where('status_id', 1)
->whereHas('company_gateway', function ($q){
$q->whereIn('gateway_key', ['d14dd26a47cecc30fdd65700bfb67b34', 'd14dd26a37cecc30fdd65700bfb55b23']);
})
->cursor()
->each(function ($p) {
try {
$stripe = $p->company_gateway->driver($p->client)->init();
} catch(\Exception $e) {
return;
}
$pi = false;
try {
$pi = $stripe->getPaymentIntent($p->transaction_reference);
} catch(\Exception $e) {
}
if(!$pi) {
try {
$pi = \Stripe\Charge::retrieve($p->transaction_reference, $stripe->stripe_connect_auth);
} catch(\Exception $e) {
return;
}
}
if($pi && $pi->status == 'succeeded') {
$p->status_id = Payment::STATUS_COMPLETED;
$p->saveQuietly();
} else {
if($pi) {
nlog("{$p->id} did not complete {$p->transaction_reference}");
} else {
nlog("did not find a payment intent {$p->transaction_reference}");
}
}
});
}
}
}

View File

@ -75,6 +75,7 @@ class ClientPaymentFailureObject
$mail_obj->data = $this->getData();
$mail_obj->markdown = 'email.client.generic';
$mail_obj->tag = $this->company->company_key;
$mail_obj->text_view = 'email.template.text';
return $mail_obj;
}
@ -122,10 +123,13 @@ class ClientPaymentFailureObject
'button' => ctrans('texts.pay_now'),
'additional_info' => false,
'company' => $this->company,
'text_body' => ctrans('texts.client_payment_failure_body', ['invoice' => implode(',', $this->invoices->pluck('number')->toArray()), 'amount' => $this->getAmount()]),
'additional_info' => $this->error ?? '',
];
if (strlen($this->error > 1)) {
$data['content'] .= "\n\n".$this->error;
// $data['content'] .= "\n\n{$this->error}";
$data['text_body'] .= "\n\n".$this->error;
}
return $data;

View File

@ -11,8 +11,9 @@
namespace App\Models;
use App\Services\Bank\BankService;
use App\Models\Expense;
use App\Utils\Traits\MakesHash;
use App\Services\Bank\BankService;
use Illuminate\Database\Eloquent\SoftDeletes;
/**
@ -137,11 +138,6 @@ class BankTransaction extends BaseModel
return $this->belongsTo(Vendor::class)->withTrashed();
}
public function expense(): \Illuminate\Database\Eloquent\Relations\BelongsTo
{
return $this->belongsTo(Expense::class)->withTrashed();
}
public function user(): \Illuminate\Database\Eloquent\Relations\BelongsTo
{
return $this->belongsTo(User::class)->withTrashed();
@ -162,8 +158,18 @@ class BankTransaction extends BaseModel
return $this->belongsTo(Payment::class)->withTrashed();
}
// public function expense(): \Illuminate\Database\Eloquent\Relations\BelongsTo
// {
// return $this->belongsTo(Expense::class)->withTrashed();
// }
public function service() :BankService
{
return new BankService($this);
}
public function getExpenses()
{
return Expense::whereIn('id', $this->getExpenseIds())->get();
}
}

View File

@ -220,7 +220,7 @@ class Expense extends BaseModel
public function transaction(): \Illuminate\Database\Eloquent\Relations\BelongsTo
{
return $this->belongsTo(BankTransaction::class);
return $this->belongsTo(BankTransaction::class)->withTrashed();
}
public function stringStatus()

View File

@ -319,6 +319,14 @@ class Invoice extends BaseModel
return $this->morphToMany(Payment::class, 'paymentable')->withTrashed()->withPivot('amount', 'refunded', 'deleted_at')->withTimestamps();
}
/**
* @return \Illuminate\Database\Eloquent\Relations\MorphToMany<Payment>
*/
public function net_payments(): \Illuminate\Database\Eloquent\Relations\MorphToMany
{
return $this->morphToMany(Payment::class, 'paymentable')->withTrashed()->where('is_deleted',0)->withPivot('amount', 'refunded', 'deleted_at')->withTimestamps();
}
/**
* @return \Illuminate\Database\Eloquent\Relations\MorphMany<CompanyLedger>
*/

View File

@ -251,7 +251,7 @@ class Payment extends BaseModel
public function transaction(): \Illuminate\Database\Eloquent\Relations\BelongsTo
{
return $this->belongsTo(BankTransaction::class);
return $this->belongsTo(BankTransaction::class)->withTrashed();
}
public function exchange_currency(): \Illuminate\Database\Eloquent\Relations\BelongsTo

View File

@ -12,14 +12,15 @@
namespace App\PaymentDrivers\Authorize;
use App\Exceptions\GenericPaymentDriverFailure;
use App\Models\Client;
use App\PaymentDrivers\AuthorizePaymentDriver;
use net\authorize\api\contract\v1\CreateCustomerProfileRequest;
use App\Exceptions\GenericPaymentDriverFailure;
use net\authorize\api\contract\v1\CustomerAddressType;
use net\authorize\api\contract\v1\CustomerProfileType;
use net\authorize\api\contract\v1\GetCustomerProfileRequest;
use net\authorize\api\controller\CreateCustomerProfileController;
use net\authorize\api\controller\GetCustomerProfileController;
use net\authorize\api\contract\v1\CreateCustomerProfileRequest;
use net\authorize\api\controller\CreateCustomerProfileController;
/**
* Class BaseDriver.
@ -53,6 +54,28 @@ class AuthorizeCreateCustomer
$customerProfile->setMerchantCustomerId('M_'.time());
$customerProfile->setEmail($this->client->present()->email());
// if($this->client) {
// $primary_contact = $this->client->primary_contact()->first() ?? $this->client->contacts()->first();
// $shipTo = new CustomerAddressType();
// $shipTo->setFirstName(substr($primary_contact->present()->first_name(), 0, 50));
// $shipTo->setLastName(substr($primary_contact->present()->last_name(), 0, 50));
// $shipTo->setCompany(substr($this->client->present()->name(), 0, 50));
// $shipTo->setAddress(substr($this->client->shipping_address1, 0, 60));
// $shipTo->setCity(substr($this->client->shipping_city, 0, 40));
// $shipTo->setState(substr($this->client->shipping_state, 0, 40));
// $shipTo->setZip(substr($this->client->shipping_postal_code, 0, 20));
// if ($this->client->country_id) {
// $shipTo->setCountry($this->client->shipping_country->name);
// }
// $shipTo->setPhoneNumber(substr($this->client->phone, 0, 20));
// $customerProfile->setShipToList([$shipTo]);
// }
// Assemble the complete transaction request
$request = new CreateCustomerProfileRequest();
$request->setMerchantAuthentication($this->authorize->merchant_authentication);

View File

@ -39,7 +39,6 @@ use App\PaymentDrivers\Stripe\FPX;
use App\PaymentDrivers\Stripe\GIROPAY;
use App\PaymentDrivers\Stripe\iDeal;
use App\PaymentDrivers\Stripe\ImportCustomers;
use App\PaymentDrivers\Stripe\Jobs\ChargeRefunded;
use App\PaymentDrivers\Stripe\Jobs\PaymentIntentFailureWebhook;
use App\PaymentDrivers\Stripe\Jobs\PaymentIntentPartiallyFundedWebhook;
use App\PaymentDrivers\Stripe\Jobs\PaymentIntentProcessingWebhook;
@ -791,12 +790,6 @@ class StripePaymentDriver extends BaseDriver
} elseif ($request->data['object']['status'] == "pending") {
return response()->json([], 200);
}
} elseif ($request->type === "charge.refunded") {
ChargeRefunded::dispatch($request->data, $request->company_key, $this->company_gateway->id)->delay(now()->addSeconds(rand(5, 10)));
return response()->json([], 200);
}
return response()->json([], 200);

View File

@ -135,7 +135,6 @@ class ActivityRepository extends BaseRepository
$design = Design::withTrashed()->find($entity_design_id);
if (! $entity->invitations()->exists() || ! $design) {
nlog("No invitations for entity {$entity->id} - {$entity->number}");
return '';
}
@ -204,8 +203,6 @@ class ActivityRepository extends BaseRepository
$design = Design::withTrashed()->find($entity_design_id);
if (! $entity->invitations()->exists() || ! $design) {
nlog("No invitations for entity {$entity->id} - {$entity->number}");
return '';
}

View File

@ -38,11 +38,14 @@ class BankTransactionRepository extends BaseRepository
public function convert_matched($bank_transactions)
{
/** @var \App\Models\User $user */
$user = auth()->user();
$data['transactions'] = $bank_transactions->map(function ($bt) {
return ['id' => $bt->id, 'invoice_ids' => $bt->invoice_ids, 'ninja_category_id' => $bt->ninja_category_id];
})->toArray();
$bts = (new MatchBankTransactions(auth()->user()->company()->id, auth()->user()->company()->db, $data))->handle();
$bts = (new MatchBankTransactions($user->company()->id, $user->company()->db, $data))->handle();
}
public function unlink($bt)

View File

@ -67,9 +67,12 @@ class ExpenseRepository extends BaseRepository
*/
public function create($expense): ?Expense
{
/** @var \App\Models\User $user */
$user = auth()->user();
return $this->save(
$expense,
ExpenseFactory::create(auth()->user()->company()->id, auth()->user()->id)
ExpenseFactory::create($user->company()->id, $user->id)
);
}

View File

@ -138,7 +138,7 @@ class ZugferdEInvoice extends AbstractService
$this->xrechnung->addDocumentPositionTax($taxtype, 'VAT', $item->tax_rate3);
$this->addtoTaxMap($taxtype, $linenetamount, $item->tax_rate3);
} else {
nlog("Can't add correct tax position");
// nlog("Can't add correct tax position");
}
} else {
if (!empty($this->invoice->tax_name1)) {
@ -157,7 +157,7 @@ class ZugferdEInvoice extends AbstractService
$taxtype = ZugferdDutyTaxFeeCategories::ZERO_RATED_GOODS;
$this->xrechnung->addDocumentPositionTax($taxtype, 'VAT', 0);
$this->addtoTaxMap($taxtype, $linenetamount, 0);
nlog("Can't add correct tax position");
// nlog("Can't add correct tax position");
}
}
}

View File

@ -81,8 +81,6 @@ class HandleRestore extends AbstractService
Paymentable::query()
->withTrashed()
->where('payment_id', $payment->id)
// ->where('paymentable_type', '=', 'invoices')
// ->where('paymentable_id', $this->invoice->id)
->update(['deleted_at' => null]);
});
@ -93,11 +91,6 @@ class HandleRestore extends AbstractService
private function setAdjustmentAmount()
{
foreach ($this->invoice->payments as $payment) {
$this->adjustment_amount += $payment->paymentables
->where('paymentable_type', '=', 'invoices')
->where('paymentable_id', $this->invoice->id)
->sum('amount');
$this->adjustment_amount += $payment->paymentables
->where('paymentable_type', '=', 'invoices')
->where('paymentable_id', $this->invoice->id)
@ -108,6 +101,7 @@ class HandleRestore extends AbstractService
->where('paymentable_type', '=', 'App\Models\Credit')
->sum('amount');
nlog("Adjustment amount: {$this->adjustment_amount}");
}
$this->total_payments = $this->invoice->payments->sum('amount') - $this->invoice->payments->sum('refunded');
@ -122,10 +116,12 @@ class HandleRestore extends AbstractService
if ($this->adjustment_amount == $this->total_payments) {
$this->invoice->payments()->update(['payments.deleted_at' => null, 'payments.is_deleted' => false]);
}
else
$this->invoice->net_payments()->update(['payments.deleted_at' => null, 'payments.is_deleted' => false]);
//adjust payments down by the amount applied to the invoice payment.
$this->invoice->payments->fresh()->each(function ($payment) {
$this->invoice->net_payments()->each(function ($payment) {
$payment_adjustment = $payment->paymentables
->where('paymentable_type', '=', 'invoices')
->where('paymentable_id', $this->invoice->id)

View File

@ -76,14 +76,12 @@ class MarkInvoiceDeleted extends AbstractService
private function adjustPayments()
{
//if total payments = adjustment amount - that means we need to delete the payments as well.
if ($this->adjustment_amount == $this->total_payments) {
$this->invoice->payments()->update(['payments.deleted_at' => now(), 'payments.is_deleted' => true]);
}
//adjust payments down by the amount applied to the invoice payment.
$this->invoice->payments->each(function ($payment) {
$payment_adjustment = $payment->paymentables
->where('paymentable_type', '=', 'invoices')

View File

@ -156,7 +156,6 @@ class DeletePayment
$client
->service()
// ->updatePaidToDate(($paymentable_credit->pivot->amount) * -1)
->adjustCreditBalance($paymentable_credit->pivot->amount)
->save();
});

View File

@ -355,7 +355,7 @@ class ProfitLoss
$csv->insertOne(['--------------------']);
$csv->insertOne([ctrans('texts.total_revenue'), Number::formatMoney($this->income - $this->income_taxes, $this->company)]);
$csv->insertOne([ctrans('texts.total_revenue'), Number::formatMoney($this->income, $this->company)]);
//total taxes

View File

@ -15,8 +15,8 @@ return [
'require_https' => env('REQUIRE_HTTPS', true),
'app_url' => rtrim(env('APP_URL', ''), '/'),
'app_domain' => env('APP_DOMAIN', 'invoicing.co'),
'app_version' => env('APP_VERSION','5.7.27'),
'app_tag' => env('APP_TAG','5.7.27'),
'app_version' => env('APP_VERSION','5.7.28'),
'app_tag' => env('APP_TAG','5.7.28'),
'minimum_client_version' => '5.0.16',
'terms_version' => '1.0.1',
'api_secret' => env('API_SECRET', ''),
@ -194,6 +194,7 @@ return [
'ninja_default_company_gateway_id' => env('NINJA_COMPANY_GATEWAY_ID', null),
'ninja_hosted_secret' => env('NINJA_HOSTED_SECRET', ''),
'ninja_hosted_header' =>env('NINJA_HEADER', ''),
'ninja_connect_secret' => env('NINJA_CONNECT_SECRET',''),
'internal_queue_enabled' => env('INTERNAL_QUEUE_ENABLED', true),
'ninja_apple_api_key' => env('APPLE_API_KEY', false),
'ninja_apple_private_key' => env('APPLE_PRIVATE_KEY', false),

View File

@ -5178,6 +5178,7 @@ $LANG = array(
'classification' => 'Classification',
'stock_quantity_number' => 'Stock :quantity',
'upcoming' => 'Upcoming',
'client_contact' => 'Client Contact',
);
return $LANG;