mirror of
				https://github.com/invoiceninja/invoiceninja.git
				synced 2025-11-04 04:07:32 -05:00 
			
		
		
		
	Merge branch 'v5-develop' into bank_rules
This commit is contained in:
		
						commit
						31c9c0c5a3
					
				@ -1 +1 @@
 | 
			
		||||
5.5.41
 | 
			
		||||
5.5.42
 | 
			
		||||
@ -87,7 +87,8 @@ class AccountTransformer implements AccountTransformerInterface
 | 
			
		||||
        return [
 | 
			
		||||
            'id' => $account->id,
 | 
			
		||||
            'account_type' => $account->CONTAINER,
 | 
			
		||||
            'account_name' => $account->accountName,
 | 
			
		||||
            // 'account_name' => $account->accountName,
 | 
			
		||||
            'account_name' => property_exists($account, 'accountName') ? $account->accountName : $account->nickname,
 | 
			
		||||
            'account_status' => $account->accountStatus,
 | 
			
		||||
            'account_number' => property_exists($account, 'accountNumber') ? '**** ' . substr($account?->accountNumber, -7) : '',
 | 
			
		||||
            'provider_account_id' => $account->providerAccountId,
 | 
			
		||||
 | 
			
		||||
@ -48,8 +48,15 @@ class EpcQrGenerator
 | 
			
		||||
 | 
			
		||||
        $this->validateFields();
 | 
			
		||||
 | 
			
		||||
        $qr = $writer->writeString($this->encodeMessage());
 | 
			
		||||
 | 
			
		||||
        try {
 | 
			
		||||
            $qr = $writer->writeString($this->encodeMessage(), 'utf-8');
 | 
			
		||||
        }
 | 
			
		||||
        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>";
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
@ -87,10 +87,10 @@ class SwissQrGenerator
 | 
			
		||||
    $qrBill->setUltimateDebtor(
 | 
			
		||||
        QrBill\DataGroup\Element\StructuredAddress::createWithStreet(
 | 
			
		||||
            substr($this->client->present()->name(), 0 , 70),
 | 
			
		||||
            $this->client->address1 ? substr($this->client->address1, 0 , 70) : '',
 | 
			
		||||
            $this->client->address2 ? substr($this->client->address2, 0 , 16) : '',
 | 
			
		||||
            $this->client->postal_code ? substr($this->client->postal_code, 0, 16) : '',
 | 
			
		||||
            $this->client->city ? substr($this->client->city, 0, 35) : '',
 | 
			
		||||
            $this->client->address1 ? substr($this->client->address1, 0 , 70) : '_',
 | 
			
		||||
            $this->client->address2 ? substr($this->client->address2, 0 , 16) : '_',
 | 
			
		||||
            $this->client->postal_code ? substr($this->client->postal_code, 0, 16) : '_',
 | 
			
		||||
            $this->client->city ? substr($this->client->city, 0, 35) : '_',
 | 
			
		||||
            'CH'
 | 
			
		||||
        ));
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
@ -164,7 +164,8 @@ class CompanyController extends BaseController
 | 
			
		||||
     */
 | 
			
		||||
    public function create(CreateCompanyRequest $request)
 | 
			
		||||
    {
 | 
			
		||||
        $company = CompanyFactory::create(auth()->user()->company()->account->id);
 | 
			
		||||
        $cf = new \App\Factory\CompanyFactory;
 | 
			
		||||
        $company = $cf->create(auth()->user()->company()->account->id);
 | 
			
		||||
 | 
			
		||||
        return $this->itemResponse($company);
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
@ -44,7 +44,7 @@ class StoreBankTransactionRequest extends Request
 | 
			
		||||
    {
 | 
			
		||||
        $input = $this->all();
 | 
			
		||||
 | 
			
		||||
            if(array_key_exists('bank_integration_id', $input) && strlen($input['bank_integration_id']) > 1)
 | 
			
		||||
            if(array_key_exists('bank_integration_id', $input) && strlen($input['bank_integration_id']) > 1 && !is_numeric($input['bank_integration_id']))
 | 
			
		||||
                $input['bank_integration_id'] = $this->decodePrimaryKey($input['bank_integration_id']);
 | 
			
		||||
 | 
			
		||||
        $this->replace($input);
 | 
			
		||||
 | 
			
		||||
@ -108,6 +108,8 @@ class UpdateCompanyRequest extends Request
 | 
			
		||||
            }
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
            $settings['email_style_custom'] = str_replace("{{", "", $settings['email_style_custom']);
 | 
			
		||||
 | 
			
		||||
        if (! $account->isFreeHostedClient()) {
 | 
			
		||||
            return $settings;
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
@ -12,6 +12,7 @@
 | 
			
		||||
namespace App\Http\Requests\Report;
 | 
			
		||||
 | 
			
		||||
use App\Http\Requests\Request;
 | 
			
		||||
use Illuminate\Validation\Rule;
 | 
			
		||||
 | 
			
		||||
class GenericReportRequest extends Request
 | 
			
		||||
{
 | 
			
		||||
@ -27,11 +28,14 @@ class GenericReportRequest extends Request
 | 
			
		||||
 | 
			
		||||
    public function rules()
 | 
			
		||||
    {
 | 
			
		||||
        nlog($this->date_range);
 | 
			
		||||
 | 
			
		||||
        return [
 | 
			
		||||
            'start_date' => 'string|date',
 | 
			
		||||
            'end_date' => 'string|date',
 | 
			
		||||
            'date_key' => 'string',
 | 
			
		||||
            'date_range' => 'sometimes|string',
 | 
			
		||||
            'date_range' => 'bail|required|string',
 | 
			
		||||
            // 'start_date' => [Rule::requiredIf($this->date_range === 'custom')],
 | 
			
		||||
            // 'end_date' => [Rule::requiredIf($this->date_range === 'custom')],
 | 
			
		||||
            'end_date' => 'bail|required_if:date_range,custom|nullable|date',
 | 
			
		||||
            'start_date' => 'bail|required_if:date_range,custom|nullable|date',
 | 
			
		||||
            'report_keys' => 'present|array',
 | 
			
		||||
            'send_email' => 'required|bool',
 | 
			
		||||
        ];
 | 
			
		||||
 | 
			
		||||
@ -28,8 +28,8 @@ class ProfitLossRequest extends Request
 | 
			
		||||
    public function rules()
 | 
			
		||||
    {
 | 
			
		||||
        return [
 | 
			
		||||
            'start_date' => 'string|date',
 | 
			
		||||
            'end_date' => 'string|date',
 | 
			
		||||
            'start_date' => 'required_if:date_range,custom|string|date',
 | 
			
		||||
            'end_date' => 'required_if:date_range,custom|string|date',
 | 
			
		||||
            'is_income_billed' => 'required|bail|bool',
 | 
			
		||||
            'is_expense_billed' => 'bool',
 | 
			
		||||
            'include_tax' => 'required|bail|bool',
 | 
			
		||||
 | 
			
		||||
@ -293,7 +293,7 @@ class CompanyExport implements ShouldQueue
 | 
			
		||||
        $this->export_data['payments'] = $this->company->payments()->orderBy('number', 'DESC')->cursor()->map(function ($payment){
 | 
			
		||||
 | 
			
		||||
            $payment = $this->transformBasicEntities($payment);
 | 
			
		||||
            $payment = $this->transformArrayOfKeys($payment, ['client_id','project_id', 'vendor_id', 'client_contact_id', 'invitation_id', 'company_gateway_id']);
 | 
			
		||||
            $payment = $this->transformArrayOfKeys($payment, ['client_id','project_id', 'vendor_id', 'client_contact_id', 'invitation_id', 'company_gateway_id', 'transaction_id']);
 | 
			
		||||
 | 
			
		||||
            $payment->paymentables = $this->transformPaymentable($payment);
 | 
			
		||||
 | 
			
		||||
@ -456,7 +456,6 @@ class CompanyExport implements ShouldQueue
 | 
			
		||||
 | 
			
		||||
        })->all();
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
        $this->export_data['purchase_order_invitations'] = PurchaseOrderInvitation::where('company_id', $this->company->id)->withTrashed()->cursor()->map(function ($purchase_order){
 | 
			
		||||
 | 
			
		||||
            $purchase_order = $this->transformArrayOfKeys($purchase_order, ['company_id', 'user_id', 'vendor_contact_id', 'purchase_order_id']);
 | 
			
		||||
@ -466,6 +465,21 @@ class CompanyExport implements ShouldQueue
 | 
			
		||||
        })->all();
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
        $this->export_data['bank_integrations'] = $this->company->bank_integrations()->orderBy('id', 'ASC')->cursor()->map(function ($bank_integration){
 | 
			
		||||
 | 
			
		||||
            $bank_integration = $this->transformArrayOfKeys($bank_integration, ['account_id','company_id', 'user_id']);
 | 
			
		||||
 | 
			
		||||
            return $bank_integration->makeVisible(['id','user_id','company_id','account_id']);
 | 
			
		||||
 | 
			
		||||
        })->all();
 | 
			
		||||
 | 
			
		||||
        $this->export_data['bank_transactions'] = $this->company->bank_transactions()->orderBy('id', 'ASC')->cursor()->map(function ($bank_transaction){
 | 
			
		||||
 | 
			
		||||
            $bank_transaction = $this->transformArrayOfKeys($bank_transaction, ['company_id', 'user_id','bank_integration_id','expense_id','category_id','ninja_category_id','vendor_id']);
 | 
			
		||||
 | 
			
		||||
            return $bank_transaction->makeVisible(['id','user_id','company_id']);
 | 
			
		||||
 | 
			
		||||
        })->all();
 | 
			
		||||
 | 
			
		||||
        //write to tmp and email to owner();
 | 
			
		||||
        
 | 
			
		||||
@ -516,9 +530,6 @@ class CompanyExport implements ShouldQueue
 | 
			
		||||
        $file_name = date('Y-m-d').'_'.str_replace([" ", "/"],["_",""], $this->company->present()->name() . '_' . $this->company->company_key .'.zip');
 | 
			
		||||
 | 
			
		||||
        $path = 'backups';
 | 
			
		||||
        
 | 
			
		||||
        // if(!Storage::disk(config('filesystems.default'))->exists($path))
 | 
			
		||||
        //     Storage::disk(config('filesystems.default'))->makeDirectory($path, 0775);
 | 
			
		||||
 | 
			
		||||
        $zip_path = public_path('storage/backups/'.$file_name);
 | 
			
		||||
        $zip = new \ZipArchive();
 | 
			
		||||
 | 
			
		||||
@ -24,6 +24,8 @@ use App\Mail\Import\CompanyImportFailure;
 | 
			
		||||
use App\Mail\Import\ImportCompleted;
 | 
			
		||||
use App\Models\Activity;
 | 
			
		||||
use App\Models\Backup;
 | 
			
		||||
use App\Models\BankIntegration;
 | 
			
		||||
use App\Models\BankTransaction;
 | 
			
		||||
use App\Models\Client;
 | 
			
		||||
use App\Models\ClientContact;
 | 
			
		||||
use App\Models\ClientGatewayToken;
 | 
			
		||||
@ -142,15 +144,16 @@ class CompanyImport implements ShouldQueue
 | 
			
		||||
        'expenses',
 | 
			
		||||
        'tasks',
 | 
			
		||||
        'payments',
 | 
			
		||||
        // 'activities',
 | 
			
		||||
        // 'backups',
 | 
			
		||||
        'company_ledger',
 | 
			
		||||
        'designs',
 | 
			
		||||
        'documents',
 | 
			
		||||
        'webhooks',
 | 
			
		||||
        'system_logs',
 | 
			
		||||
        'purchase_orders',
 | 
			
		||||
        'purchase_order_invitations'
 | 
			
		||||
        'purchase_order_invitations',
 | 
			
		||||
        'bank_integrations',
 | 
			
		||||
        'bank_transactions',
 | 
			
		||||
        'payments',
 | 
			
		||||
    ];
 | 
			
		||||
 | 
			
		||||
    private $company_properties = [
 | 
			
		||||
@ -527,6 +530,37 @@ class CompanyImport implements ShouldQueue
 | 
			
		||||
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    private function import_bank_integrations()
 | 
			
		||||
    {
 | 
			
		||||
        $this->genericImport(BankIntegration::class, 
 | 
			
		||||
            ['assigned_user_id','account_id', 'company_id', 'id', 'hashed_id'], 
 | 
			
		||||
            [
 | 
			
		||||
                ['users' => 'user_id'], 
 | 
			
		||||
            ], 
 | 
			
		||||
            'bank_integrations',
 | 
			
		||||
            'description');
 | 
			
		||||
 | 
			
		||||
        return $this;
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    private function import_bank_transactions()
 | 
			
		||||
    {
 | 
			
		||||
        $this->genericImport(BankTransaction::class, 
 | 
			
		||||
            ['assigned_user_id','company_id', 'id', 'hashed_id', 'user_id'], 
 | 
			
		||||
            [
 | 
			
		||||
                ['users' => 'user_id'], 
 | 
			
		||||
                ['expenses' => 'expense_id'],
 | 
			
		||||
                ['vendors' => 'vendor_id'],
 | 
			
		||||
                ['expense_categories' => 'ninja_category_id'],
 | 
			
		||||
                ['expense_categories' => 'category_id'],
 | 
			
		||||
                ['bank_integrations' => 'bank_integration_id']
 | 
			
		||||
            ], 
 | 
			
		||||
            'bank_transactions',
 | 
			
		||||
            null);
 | 
			
		||||
 | 
			
		||||
        return $this;
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    private function import_recurring_expenses()
 | 
			
		||||
    {
 | 
			
		||||
//unset / transforms / object_property / match_key
 | 
			
		||||
@ -979,6 +1013,7 @@ class CompanyImport implements ShouldQueue
 | 
			
		||||
                ['vendors' => 'vendor_id'],
 | 
			
		||||
                ['invoice_invitations' => 'invitation_id'],
 | 
			
		||||
                ['company_gateways' => 'company_gateway_id'],
 | 
			
		||||
                ['bank_transactions' => 'transaction_id'],
 | 
			
		||||
            ], 
 | 
			
		||||
            'payments',
 | 
			
		||||
            'number');
 | 
			
		||||
@ -1569,6 +1604,28 @@ class CompanyImport implements ShouldQueue
 | 
			
		||||
                        $obj_array,
 | 
			
		||||
                    );
 | 
			
		||||
            }
 | 
			
		||||
            elseif($class == 'App\Models\BankIntegration'){
 | 
			
		||||
                $new_obj = new BankIntegration();
 | 
			
		||||
                $new_obj->company_id = $this->company->id;
 | 
			
		||||
                $new_obj->account_id = $this->account->id;
 | 
			
		||||
                $new_obj->fill($obj_array);
 | 
			
		||||
                $new_obj->save(['timestamps' => false]);
 | 
			
		||||
            }
 | 
			
		||||
            elseif($class == 'App\Models\BankTransaction'){
 | 
			
		||||
 | 
			
		||||
                $new_obj = new BankTransaction();
 | 
			
		||||
                $new_obj->company_id = $this->company->id;
 | 
			
		||||
 | 
			
		||||
                $obj_array['invoice_ids'] = collect(explode(",",$obj_array['invoice_ids']))->map(function ($id) {
 | 
			
		||||
                    return $this->transformId('invoices', $id); 
 | 
			
		||||
                })->map(function ($encodeable){
 | 
			
		||||
                    return $this->encodePrimaryKey($encodeable);
 | 
			
		||||
                })->implode(",");
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
                $new_obj->fill($obj_array);
 | 
			
		||||
                $new_obj->save(['timestamps' => false]);
 | 
			
		||||
            }
 | 
			
		||||
            else{
 | 
			
		||||
                $new_obj = $class::withTrashed()->firstOrNew(
 | 
			
		||||
                        [$match_key => $obj->{$match_key}, 'company_id' => $this->company->id],
 | 
			
		||||
 | 
			
		||||
@ -129,11 +129,8 @@ class NinjaMailerJob implements ShouldQueue
 | 
			
		||||
            LightLogs::create(new EmailSuccess($this->nmo->company->company_key))
 | 
			
		||||
                     ->send();
 | 
			
		||||
 | 
			
		||||
            // nlog('Using ' . ((int) (memory_get_usage(true) / (1024 * 1024))) . 'MB ');
 | 
			
		||||
 | 
			
		||||
            $this->nmo = null;
 | 
			
		||||
            $this->company = null;
 | 
			
		||||
            app('queue.worker')->shouldQuit  = 1;
 | 
			
		||||
    
 | 
			
		||||
        } catch (\Exception | \RuntimeException | \Google\Service\Exception $e) {
 | 
			
		||||
            
 | 
			
		||||
 | 
			
		||||
@ -19,6 +19,9 @@ use stdClass;
 | 
			
		||||
 | 
			
		||||
class InvoiceEmailFailedActivity implements ShouldQueue
 | 
			
		||||
{
 | 
			
		||||
 | 
			
		||||
    // public $delay = 10;
 | 
			
		||||
 | 
			
		||||
    protected $activity_repo;
 | 
			
		||||
 | 
			
		||||
    /**
 | 
			
		||||
 | 
			
		||||
@ -18,13 +18,18 @@ use App\Libraries\MultiDB;
 | 
			
		||||
use App\Mail\Admin\EntityFailedSendObject;
 | 
			
		||||
use App\Notifications\Admin\EntitySentNotification;
 | 
			
		||||
use App\Utils\Traits\Notifications\UserNotifies;
 | 
			
		||||
use Illuminate\Bus\Queueable;
 | 
			
		||||
use Illuminate\Contracts\Queue\ShouldQueue;
 | 
			
		||||
use Illuminate\Foundation\Bus\Dispatchable;
 | 
			
		||||
use Illuminate\Queue\InteractsWithQueue;
 | 
			
		||||
use Illuminate\Queue\SerializesModels;
 | 
			
		||||
 | 
			
		||||
class InvoiceFailedEmailNotification
 | 
			
		||||
{
 | 
			
		||||
    use UserNotifies;
 | 
			
		||||
 | 
			
		||||
    public $delay = 5;
 | 
			
		||||
    use UserNotifies, Dispatchable, InteractsWithQueue, Queueable, SerializesModels;
 | 
			
		||||
 | 
			
		||||
    public $delay = 10;
 | 
			
		||||
 | 
			
		||||
    public function __construct()
 | 
			
		||||
    {
 | 
			
		||||
 | 
			
		||||
@ -111,7 +111,10 @@ class PayPal
 | 
			
		||||
            'paymentMethodNonce' => $gateway_response->nonce,
 | 
			
		||||
        ]);
 | 
			
		||||
 | 
			
		||||
        return $payment_method->paymentMethod->token;
 | 
			
		||||
        if($payment_method->success)
 | 
			
		||||
            return $payment_method->paymentMethod->token;
 | 
			
		||||
        else
 | 
			
		||||
            throw new PaymentFailed(property_exists($payment_method, 'message') ? $payment_method->message : 'Undefined error storing payment token.', 0);
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    /**
 | 
			
		||||
 | 
			
		||||
@ -306,10 +306,53 @@ class CheckoutComPaymentDriver extends BaseDriver
 | 
			
		||||
 | 
			
		||||
                try {
 | 
			
		||||
                    $response = $this->gateway->getCustomersClient()->create($request);
 | 
			
		||||
                } catch (\Exception $e) {
 | 
			
		||||
                    // API error
 | 
			
		||||
                    throw new PaymentFailed($e->getMessage(), $e->getCode());
 | 
			
		||||
                } 
 | 
			
		||||
                catch (CheckoutApiException $e) {
 | 
			
		||||
                    // API error
 | 
			
		||||
                    $request_id = $e->request_id;
 | 
			
		||||
                    $http_status_code = $e->http_status_code;
 | 
			
		||||
                    $error_details = $e->error_details;
 | 
			
		||||
 | 
			
		||||
                    if(is_array($error_details)) {
 | 
			
		||||
                        $error_details = end($e->error_details['error_codes']);
 | 
			
		||||
                    }
 | 
			
		||||
 | 
			
		||||
                    $human_exception = $error_details ? new \Exception($error_details, 400) : $e;
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
                    throw new PaymentFailed($human_exception);
 | 
			
		||||
                } catch (CheckoutArgumentException $e) {
 | 
			
		||||
                    // Bad arguments
 | 
			
		||||
 | 
			
		||||
                    $error_details = $e->error_details;
 | 
			
		||||
 | 
			
		||||
                    if(is_array($error_details)) {
 | 
			
		||||
                        $error_details = end($e->error_details['error_codes']);
 | 
			
		||||
                    }
 | 
			
		||||
 | 
			
		||||
                    $human_exception = $error_details ? new \Exception($error_details, 400) : $e;
 | 
			
		||||
 | 
			
		||||
                    throw new PaymentFailed($human_exception);
 | 
			
		||||
                } catch (CheckoutAuthorizationException $e) {
 | 
			
		||||
                    // Bad Invalid authorization
 | 
			
		||||
          
 | 
			
		||||
                    $error_details = $e->error_details;
 | 
			
		||||
         
 | 
			
		||||
                     if(is_array($error_details)) {
 | 
			
		||||
                        $error_details = end($e->error_details['error_codes']);
 | 
			
		||||
                    }
 | 
			
		||||
 | 
			
		||||
                    $human_exception = $error_details ? new \Exception($error_details, 400) : $e;
 | 
			
		||||
 | 
			
		||||
                    throw new PaymentFailed($human_exception);
 | 
			
		||||
                }
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
                // catch (\Exception $e) {
 | 
			
		||||
                //     // API error
 | 
			
		||||
                //     throw new PaymentFailed($e->getMessage(), $e->getCode());
 | 
			
		||||
                // } 
 | 
			
		||||
 | 
			
		||||
            return $response;
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
@ -63,7 +63,11 @@ class ImportCustomers
 | 
			
		||||
                $this->addCustomer($customer);
 | 
			
		||||
            }
 | 
			
		||||
 | 
			
		||||
            $starting_after = end($customers->data)['id'];
 | 
			
		||||
            //handle 
 | 
			
		||||
            if(is_array($customers->data) && end($customers->data) && array_key_exists('id', end($customers->data)))
 | 
			
		||||
                $starting_after = end($customers->data)['id'];
 | 
			
		||||
            else
 | 
			
		||||
                break;
 | 
			
		||||
 | 
			
		||||
        } while ($customers->has_more);
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
@ -451,7 +451,7 @@ class EventServiceProvider extends ServiceProvider
 | 
			
		||||
            PaymentEmailedActivity::class,
 | 
			
		||||
        ],
 | 
			
		||||
        PaymentWasEmailedAndFailed::class => [
 | 
			
		||||
            PaymentEmailFailureActivity::class,
 | 
			
		||||
            // PaymentEmailFailureActivity::class,
 | 
			
		||||
        ],
 | 
			
		||||
        PurchaseOrderWasArchived::class => [
 | 
			
		||||
            PurchaseOrderArchivedActivity::class,
 | 
			
		||||
 | 
			
		||||
@ -60,7 +60,7 @@ class ActivityRepository extends BaseRepository
 | 
			
		||||
        $activity->save();
 | 
			
		||||
 | 
			
		||||
        //rate limiter
 | 
			
		||||
       // $this->createBackup($entity, $activity);
 | 
			
		||||
       $this->createBackup($entity, $activity);
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    /**
 | 
			
		||||
 | 
			
		||||
@ -104,7 +104,6 @@ class DeletePayment
 | 
			
		||||
 | 
			
		||||
                    $client = $this->payment
 | 
			
		||||
                                   ->client
 | 
			
		||||
                                   ->fresh()
 | 
			
		||||
                                   ->service()
 | 
			
		||||
                                   ->updateBalance($net_deletable)
 | 
			
		||||
                                   ->save();
 | 
			
		||||
@ -136,9 +135,8 @@ class DeletePayment
 | 
			
		||||
            });
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        $client = $this->payment->client->fresh();
 | 
			
		||||
 | 
			
		||||
        $client
 | 
			
		||||
        $this->payment
 | 
			
		||||
        ->client
 | 
			
		||||
        ->service()
 | 
			
		||||
        ->updatePaidToDate(($this->payment->amount - $this->payment->refunded) * -1)
 | 
			
		||||
        ->save();
 | 
			
		||||
@ -146,7 +144,7 @@ class DeletePayment
 | 
			
		||||
        $transaction = [
 | 
			
		||||
            'invoice' => [],
 | 
			
		||||
            'payment' => [],
 | 
			
		||||
            'client' => $client->transaction_event(),
 | 
			
		||||
            'client' => $this->payment->client->transaction_event(),
 | 
			
		||||
            'credit' => [],
 | 
			
		||||
            'metadata' => [],
 | 
			
		||||
        ];
 | 
			
		||||
 | 
			
		||||
@ -62,12 +62,14 @@ class UpdateInvoicePayment
 | 
			
		||||
                $paid_amount = $paid_invoice->amount;
 | 
			
		||||
            }
 | 
			
		||||
 | 
			
		||||
            $client->service()->updateBalanceAndPaidToDate($paid_amount*-1, $paid_amount);
 | 
			
		||||
            $client->service()->updatePaidToDate($paid_amount); //always use the payment->amount
 | 
			
		||||
 | 
			
		||||
            /* Need to determine here is we have an OVER payment - if YES only apply the max invoice amount */
 | 
			
		||||
            if($paid_amount > $invoice->partial && $paid_amount > $invoice->balance)
 | 
			
		||||
                $paid_amount = $invoice->balance;
 | 
			
		||||
 | 
			
		||||
            $client->service()->updateBalance($paid_amount*-1); //only ever use the amount applied to the invoice
 | 
			
		||||
 | 
			
		||||
            /*Improve performance here - 26-01-2022 - also change the order of events for invoice first*/
 | 
			
		||||
            //caution what if we amount paid was less than partial - we wipe it!
 | 
			
		||||
            $invoice->balance -= $paid_amount;
 | 
			
		||||
 | 
			
		||||
@ -40,12 +40,8 @@ use Symfony\Component\HttpFoundation\Request;
 | 
			
		||||
 | 
			
		||||
class TaskSchedulerService
 | 
			
		||||
{
 | 
			
		||||
    public Scheduler $scheduler;
 | 
			
		||||
 | 
			
		||||
    public function __construct(Scheduler $scheduler)
 | 
			
		||||
    {
 | 
			
		||||
        $this->scheduler = $scheduler;
 | 
			
		||||
    }
 | 
			
		||||
    
 | 
			
		||||
    public function __construct(public Scheduler $scheduler) {}
 | 
			
		||||
 | 
			
		||||
    public function store(Scheduler $scheduler, CreateScheduledTaskRequest $request)
 | 
			
		||||
    {
 | 
			
		||||
 | 
			
		||||
@ -134,6 +134,30 @@ class Helpers
 | 
			
		||||
 | 
			
		||||
        $replacements = [
 | 
			
		||||
            'literal' => [
 | 
			
		||||
                ':MONTH_BEFORE' => \sprintf(
 | 
			
		||||
                    '%s %s %s',
 | 
			
		||||
                    Carbon::now()->subMonth(1)->translatedFormat($entity->date_format()),
 | 
			
		||||
                    ctrans('texts.to'),
 | 
			
		||||
                    Carbon::now()->subDay(1)->translatedFormat($entity->date_format()),
 | 
			
		||||
                ),
 | 
			
		||||
                ':YEAR_BEFORE' => \sprintf(
 | 
			
		||||
                    '%s %s %s',
 | 
			
		||||
                    Carbon::now()->subYear(1)->translatedFormat($entity->date_format()),
 | 
			
		||||
                    ctrans('texts.to'),
 | 
			
		||||
                    Carbon::now()->subDay(1)->translatedFormat($entity->date_format()),
 | 
			
		||||
                ),
 | 
			
		||||
                ':MONTH_AFTER' => \sprintf(
 | 
			
		||||
                    '%s %s %s',
 | 
			
		||||
                    Carbon::now()->translatedFormat($entity->date_format()),
 | 
			
		||||
                    ctrans('texts.to'),
 | 
			
		||||
                    Carbon::now()->addMonth(1)->subDay(1)->translatedFormat($entity->date_format()),
 | 
			
		||||
                ),
 | 
			
		||||
                ':YEAR_AFTER' => \sprintf(
 | 
			
		||||
                    '%s %s %s',
 | 
			
		||||
                    Carbon::now()->translatedFormat($entity->date_format()),
 | 
			
		||||
                    ctrans('texts.to'),
 | 
			
		||||
                    Carbon::now()->addYear(1)->subDay(1)->translatedFormat($entity->date_format()),
 | 
			
		||||
                ),
 | 
			
		||||
                ':MONTHYEAR' => \sprintf(
 | 
			
		||||
                    '%s %s',
 | 
			
		||||
                    Carbon::createFromDate(now()->month)->translatedFormat('F'),
 | 
			
		||||
@ -150,15 +174,15 @@ class Helpers
 | 
			
		||||
                ),
 | 
			
		||||
                ':WEEK_AHEAD' => \sprintf(
 | 
			
		||||
                    '%s %s %s',
 | 
			
		||||
                    Carbon::now()->addDays(6)->translatedFormat($entity->date_format()),
 | 
			
		||||
                    Carbon::now()->addDays(7)->translatedFormat($entity->date_format()),
 | 
			
		||||
                    ctrans('texts.to'),
 | 
			
		||||
                    Carbon::now()->addDays(13)->translatedFormat($entity->date_format())
 | 
			
		||||
                ),
 | 
			
		||||
                ':WEEK' => \sprintf(
 | 
			
		||||
                    '%s %s %s',
 | 
			
		||||
                    Carbon::now()->subDays(7)->translatedFormat($entity->date_format()),
 | 
			
		||||
                    Carbon::now()->translatedFormat($entity->date_format()),
 | 
			
		||||
                    ctrans('texts.to'),
 | 
			
		||||
                    Carbon::now()->addDays(13)->translatedFormat($entity->date_format())
 | 
			
		||||
                    Carbon::now()->addDays(6)->translatedFormat($entity->date_format())
 | 
			
		||||
                ),
 | 
			
		||||
            ],
 | 
			
		||||
            'raw' => [
 | 
			
		||||
 | 
			
		||||
@ -95,10 +95,14 @@ class SystemHealth
 | 
			
		||||
 | 
			
		||||
        if(strlen(config('ninja.currency_converter_api_key')) == 0){
 | 
			
		||||
    
 | 
			
		||||
        try{
 | 
			
		||||
            $cs = DB::table('clients')
 | 
			
		||||
                  ->select('settings->currency_id as id')
 | 
			
		||||
                            ->get();
 | 
			
		||||
 | 
			
		||||
        }
 | 
			
		||||
        catch(\Exception $e){
 | 
			
		||||
            return true; //fresh installs, there may be no DB connection, nor migrations could have run yet.
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
            $currency_count = $cs->unique('id')->filter(function ($value){
 | 
			
		||||
                return !is_null($value->id);
 | 
			
		||||
 | 
			
		||||
@ -14,8 +14,8 @@ return [
 | 
			
		||||
    'require_https' => env('REQUIRE_HTTPS', true),
 | 
			
		||||
    'app_url' => rtrim(env('APP_URL', ''), '/'),
 | 
			
		||||
    'app_domain' => env('APP_DOMAIN', 'invoicing.co'),
 | 
			
		||||
    'app_version' => '5.5.41',
 | 
			
		||||
    'app_tag' => '5.5.41',
 | 
			
		||||
    'app_version' => '5.5.42',
 | 
			
		||||
    'app_tag' => '5.5.42',
 | 
			
		||||
    'minimum_client_version' => '5.0.16',
 | 
			
		||||
    'terms_version' => '1.0.1',
 | 
			
		||||
    'api_secret' => env('API_SECRET', ''),
 | 
			
		||||
 | 
			
		||||
							
								
								
									
										4
									
								
								public/flutter_service_worker.js
									
									
									
									
										vendored
									
									
								
							
							
						
						
									
										4
									
								
								public/flutter_service_worker.js
									
									
									
									
										vendored
									
									
								
							@ -11,9 +11,9 @@ const RESOURCES = {
 | 
			
		||||
"favicon.png": "dca91c54388f52eded692718d5a98b8b",
 | 
			
		||||
"favicon.ico": "51636d3a390451561744c42188ccd628",
 | 
			
		||||
"flutter.js": "f85e6fb278b0fd20c349186fb46ae36d",
 | 
			
		||||
"/": "112f22769207bffb3936c08dec3ffa4d",
 | 
			
		||||
"/": "9d48b2826c07eb42f0817289b6a7b7ca",
 | 
			
		||||
"manifest.json": "ef43d90e57aa7682d7e2cfba2f484a40",
 | 
			
		||||
"main.dart.js": "bddfba2a7d482fece1e7a9ff84429256",
 | 
			
		||||
"main.dart.js": "3568e02ff28e4dae78f695088a6e21c5",
 | 
			
		||||
"assets/AssetManifest.json": "759f9ef9973f7e26c2a51450b55bb9fa",
 | 
			
		||||
"assets/FontManifest.json": "087fb858dc3cbfbf6baf6a30004922f1",
 | 
			
		||||
"assets/NOTICES": "1a34e70168d56fad075adfb4bdbb20eb",
 | 
			
		||||
 | 
			
		||||
							
								
								
									
										131504
									
								
								public/main.dart.js
									
									
									
									
										vendored
									
									
								
							
							
						
						
									
										131504
									
								
								public/main.dart.js
									
									
									
									
										vendored
									
									
								
							
										
											
												File diff suppressed because one or more lines are too long
											
										
									
								
							
										
											
												File diff suppressed because one or more lines are too long
											
										
									
								
							
							
								
								
									
										129170
									
								
								public/main.foss.dart.js
									
									
									
									
										vendored
									
									
								
							
							
						
						
									
										129170
									
								
								public/main.foss.dart.js
									
									
									
									
										vendored
									
									
								
							
										
											
												File diff suppressed because one or more lines are too long
											
										
									
								
							
										
											
												File diff suppressed because one or more lines are too long
											
										
									
								
							
							
								
								
									
										8301
									
								
								public/main.profile.dart.js
									
									
									
									
										vendored
									
									
								
							
							
						
						
									
										8301
									
								
								public/main.profile.dart.js
									
									
									
									
										vendored
									
									
								
							
										
											
												File diff suppressed because one or more lines are too long
											
										
									
								
							@ -257,7 +257,7 @@
 | 
			
		||||
        overflow-wrap: break-word; 
 | 
			
		||||
    }
 | 
			
		||||
    
 | 
			
		||||
        .stamp {
 | 
			
		||||
    .stamp {
 | 
			
		||||
      transform: rotate(12deg);
 | 
			
		||||
        color: #555;
 | 
			
		||||
        font-size: 3rem;
 | 
			
		||||
 | 
			
		||||
@ -31,7 +31,7 @@
 | 
			
		||||
                                {{ ctrans('texts.type') }}
 | 
			
		||||
                            </dt>
 | 
			
		||||
                            <dd class="mt-1 text-sm leading-5 text-gray-900 sm:mt-0 sm:col-span-2">
 | 
			
		||||
                                {{ $payment_method->meta?->brand }}
 | 
			
		||||
                                {{ property_exists($payment_method->meta, 'brand') ? $payment_method->meta?->brand : ''}}
 | 
			
		||||
                                {{ property_exists($payment_method->meta, 'scheme') ? $payment_method->meta?->scheme : '' }}
 | 
			
		||||
                            </dd>
 | 
			
		||||
                        </div>
 | 
			
		||||
 | 
			
		||||
@ -186,7 +186,7 @@ Route::group(['middleware' => ['throttle:300,1', 'api_db', 'token_auth', 'locale
 | 
			
		||||
    Route::put('expenses/{expense}/upload', [ExpenseController::class, 'upload']);
 | 
			
		||||
    Route::post('expenses/bulk', [ExpenseController::class, 'bulk'])->name('expenses.bulk');
 | 
			
		||||
 | 
			
		||||
    Route::post('export', [ExportController::class, 'index'])->name('export.index');
 | 
			
		||||
    Route::post('export', [ExportController::class, 'index'])->middleware('throttle:2,1')->name('export.index');
 | 
			
		||||
 | 
			
		||||
    Route::resource('expense_categories', ExpenseCategoryController::class); // name = (expense_categories. index / create / show / update / destroy / edit
 | 
			
		||||
    Route::post('expense_categories/bulk', [ExpenseCategoryController::class, 'bulk'])->name('expense_categories.bulk');
 | 
			
		||||
@ -196,7 +196,7 @@ Route::group(['middleware' => ['throttle:300,1', 'api_db', 'token_auth', 'locale
 | 
			
		||||
    Route::put('group_settings/{group_setting}/upload', [GroupSettingController::class, 'upload'])->name('group_settings.upload');
 | 
			
		||||
 | 
			
		||||
    Route::post('import', [ImportController::class, 'import'])->name('import.import');
 | 
			
		||||
    Route::post('import_json', [ImportJsonController::class, 'import'])->name('import.import_json');
 | 
			
		||||
    Route::post('import_json', [ImportJsonController::class, 'import'])->middleware('throttle:2,1')->name('import.import_json');
 | 
			
		||||
    Route::post('preimport', [ImportController::class, 'preimport'])->name('import.preimport');
 | 
			
		||||
 | 
			
		||||
    Route::resource('invoices', InvoiceController::class); // name = (invoices. index / create / show / update / destroy / edit
 | 
			
		||||
 | 
			
		||||
		Loading…
	
	
			
			x
			
			
		
	
		Reference in New Issue
	
	Block a user