mirror of
				https://github.com/invoiceninja/invoiceninja.git
				synced 2025-11-04 02:57:33 -05:00 
			
		
		
		
	
						commit
						9f9a0f6a3a
					
				
							
								
								
									
										2
									
								
								.env.ci
									
									
									
									
									
								
							
							
						
						
									
										2
									
								
								.env.ci
									
									
									
									
									
								
							@ -10,6 +10,8 @@ DB_DATABASE1=ninja
 | 
			
		||||
DB_USERNAME1=root
 | 
			
		||||
DB_PASSWORD1=ninja
 | 
			
		||||
DB_HOST1=127.0.0.1
 | 
			
		||||
DB_PORT1=32768
 | 
			
		||||
DB_PORT=32768
 | 
			
		||||
DB_DATABASE=ninja
 | 
			
		||||
DB_USERNAME=root
 | 
			
		||||
DB_PASSWORD=ninja
 | 
			
		||||
 | 
			
		||||
							
								
								
									
										13
									
								
								.github/workflows/phpunit.yml
									
									
									
									
										vendored
									
									
								
							
							
						
						
									
										13
									
								
								.github/workflows/phpunit.yml
									
									
									
									
										vendored
									
									
								
							@ -39,7 +39,7 @@ jobs:
 | 
			
		||||
      mariadb:
 | 
			
		||||
        image: mariadb:latest
 | 
			
		||||
        ports:
 | 
			
		||||
          - 3306
 | 
			
		||||
          - 32768:3306
 | 
			
		||||
        env:
 | 
			
		||||
          MYSQL_ALLOW_EMPTY_PASSWORD: yes
 | 
			
		||||
          MYSQL_USER: ninja
 | 
			
		||||
@ -52,7 +52,6 @@ jobs:
 | 
			
		||||
    - name: Start mysql service
 | 
			
		||||
      run: |
 | 
			
		||||
        sudo /etc/init.d/mysql start
 | 
			
		||||
 | 
			
		||||
    - name: Verify MariaDB connection
 | 
			
		||||
      env:
 | 
			
		||||
        DB_PORT: ${{ job.services.mariadb.ports[3306] }}
 | 
			
		||||
@ -62,12 +61,11 @@ jobs:
 | 
			
		||||
        while ! mysqladmin ping -h"127.0.0.1" -P"$DB_PORT" --silent; do
 | 
			
		||||
          sleep 1
 | 
			
		||||
        done
 | 
			
		||||
 | 
			
		||||
    - name: Setup PHP
 | 
			
		||||
      uses: shivammathur/setup-php@v2
 | 
			
		||||
      with:
 | 
			
		||||
        php-version: ${{ matrix.php-versions }}
 | 
			
		||||
        extensions: mysql, sqlite3, bcmath, gmp, gd, curl, zip, openssl, mbstring, xml
 | 
			
		||||
        extensions: mysql, mysqlnd, sqlite3, bcmath, gmp, gd, curl, zip, openssl, mbstring, xml
 | 
			
		||||
 | 
			
		||||
    - uses: actions/checkout@v1
 | 
			
		||||
      with:
 | 
			
		||||
@ -77,33 +75,27 @@ jobs:
 | 
			
		||||
    - name: Copy .env
 | 
			
		||||
      run: |
 | 
			
		||||
        cp .env.ci .env
 | 
			
		||||
 | 
			
		||||
    - name: Install composer dependencies
 | 
			
		||||
      run: |
 | 
			
		||||
        composer config -g github-oauth.github.com ${{ secrets.GITHUB_TOKEN }}
 | 
			
		||||
        composer install
 | 
			
		||||
 | 
			
		||||
    - name: Prepare Laravel Application
 | 
			
		||||
      run: |
 | 
			
		||||
        php artisan key:generate
 | 
			
		||||
        php artisan optimize
 | 
			
		||||
        php artisan cache:clear
 | 
			
		||||
        php artisan config:cache
 | 
			
		||||
 | 
			
		||||
    - name: Create DB and schemas
 | 
			
		||||
      run: |
 | 
			
		||||
        mkdir -p database
 | 
			
		||||
        touch database/database.sqlite
 | 
			
		||||
 | 
			
		||||
    - name: Migrate Database
 | 
			
		||||
      run: |
 | 
			
		||||
        php artisan migrate:fresh --seed --force && php artisan db:seed --force
 | 
			
		||||
 | 
			
		||||
    - name: Prepare JS/CSS assets
 | 
			
		||||
      run: |
 | 
			
		||||
        npm i
 | 
			
		||||
        npm run production
 | 
			
		||||
 | 
			
		||||
    - name: Run Testsuite
 | 
			
		||||
      run: |
 | 
			
		||||
        cat .env
 | 
			
		||||
@ -114,4 +106,3 @@ jobs:
 | 
			
		||||
    - name: Run php-cs-fixer
 | 
			
		||||
      run: |
 | 
			
		||||
        vendor/bin/php-cs-fixer fix
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
@ -1 +1 @@
 | 
			
		||||
5.1.1
 | 
			
		||||
5.1.2
 | 
			
		||||
@ -224,8 +224,7 @@ class EmailTemplateDefaults
 | 
			
		||||
    private static function transformText($string)
 | 
			
		||||
    {
 | 
			
		||||
        //preformat the string, removing trailing colons.
 | 
			
		||||
        $string = rtrim($string, ":");
 | 
			
		||||
 | 
			
		||||
        return str_replace(':', '$', ctrans('texts.'.$string));
 | 
			
		||||
        return str_replace(':', '$', rtrim( ctrans('texts.'.$string), ":"));
 | 
			
		||||
    }
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
@ -122,25 +122,23 @@ class InvoiceItemSum
 | 
			
		||||
 | 
			
		||||
        $item_tax += $item_tax_rate1_total;
 | 
			
		||||
 | 
			
		||||
        if ($item_tax_rate1_total > 0) {
 | 
			
		||||
        if($item_tax_rate1_total != 0)     
 | 
			
		||||
            $this->groupTax($this->item->tax_name1, $this->item->tax_rate1, $item_tax_rate1_total);
 | 
			
		||||
        }
 | 
			
		||||
        
 | 
			
		||||
        $item_tax_rate2_total = $this->calcAmountLineTax($this->item->tax_rate2, $amount);
 | 
			
		||||
 | 
			
		||||
        $item_tax += $item_tax_rate2_total;
 | 
			
		||||
 | 
			
		||||
        if ($item_tax_rate2_total > 0) {
 | 
			
		||||
        if($item_tax_rate2_total != 0)     
 | 
			
		||||
            $this->groupTax($this->item->tax_name2, $this->item->tax_rate2, $item_tax_rate2_total);
 | 
			
		||||
        }
 | 
			
		||||
        
 | 
			
		||||
        $item_tax_rate3_total = $this->calcAmountLineTax($this->item->tax_rate3, $amount);
 | 
			
		||||
 | 
			
		||||
        $item_tax += $item_tax_rate3_total;
 | 
			
		||||
 | 
			
		||||
        if ($item_tax_rate3_total > 0) {
 | 
			
		||||
        if($item_tax_rate3_total != 0)     
 | 
			
		||||
            $this->groupTax($this->item->tax_name3, $this->item->tax_rate3, $item_tax_rate3_total);
 | 
			
		||||
        }
 | 
			
		||||
        
 | 
			
		||||
 | 
			
		||||
        $this->setTotalTaxes($this->formatValue($item_tax, $this->currency->precision));
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
@ -119,25 +119,23 @@ class InvoiceItemSumInclusive
 | 
			
		||||
 | 
			
		||||
        $item_tax += $this->formatValue($item_tax_rate1_total, $this->currency->precision);
 | 
			
		||||
 | 
			
		||||
        if ($item_tax_rate1_total > 0) {
 | 
			
		||||
        if($item_tax_rate1_total != 0)     
 | 
			
		||||
            $this->groupTax($this->item->tax_name1, $this->item->tax_rate1, $item_tax_rate1_total);        
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        $item_tax_rate2_total = $this->calcInclusiveLineTax($this->item->tax_rate2, $amount);
 | 
			
		||||
 | 
			
		||||
        $item_tax += $this->formatValue($item_tax_rate2_total, $this->currency->precision);
 | 
			
		||||
 | 
			
		||||
        if ($item_tax_rate2_total > 0) {
 | 
			
		||||
        if($item_tax_rate2_total != 0)     
 | 
			
		||||
            $this->groupTax($this->item->tax_name2, $this->item->tax_rate2, $item_tax_rate2_total);
 | 
			
		||||
        }
 | 
			
		||||
        
 | 
			
		||||
        $item_tax_rate3_total = $this->calcInclusiveLineTax($this->item->tax_rate3, $amount);
 | 
			
		||||
 | 
			
		||||
        $item_tax += $this->formatValue($item_tax_rate3_total, $this->currency->precision);
 | 
			
		||||
 | 
			
		||||
        if ($item_tax_rate3_total > 0) {
 | 
			
		||||
        if($item_tax_rate3_total != 0)     
 | 
			
		||||
            $this->groupTax($this->item->tax_name3, $this->item->tax_rate3, $item_tax_rate3_total);
 | 
			
		||||
        }
 | 
			
		||||
        
 | 
			
		||||
 | 
			
		||||
        $this->setTotalTaxes($this->formatValue($item_tax, $this->currency->precision));
 | 
			
		||||
 | 
			
		||||
@ -225,7 +223,12 @@ class InvoiceItemSumInclusive
 | 
			
		||||
        $item_tax = 0;
 | 
			
		||||
 | 
			
		||||
        foreach ($this->line_items as $this->item) {
 | 
			
		||||
            $amount = $this->item->line_total - ($this->item->line_total * ($this->invoice->discount / $this->sub_total));
 | 
			
		||||
 | 
			
		||||
            if($this->sub_total == 0)
 | 
			
		||||
                $amount = $this->item->line_total;
 | 
			
		||||
            else
 | 
			
		||||
                $amount = $this->item->line_total - ($this->item->line_total * ($this->invoice->discount / $this->sub_total));
 | 
			
		||||
            
 | 
			
		||||
            $item_tax_rate1_total = $this->calcInclusiveLineTax($this->item->tax_rate1, $amount);
 | 
			
		||||
 | 
			
		||||
            $item_tax += $item_tax_rate1_total;
 | 
			
		||||
 | 
			
		||||
@ -35,10 +35,9 @@ class InvoiceWorkflowSettings implements ShouldQueue
 | 
			
		||||
     * @param Invoice $invoice
 | 
			
		||||
     * @param Client|null $client
 | 
			
		||||
     */
 | 
			
		||||
    public function __construct(Invoice $invoice, Client $client = null)
 | 
			
		||||
    public function __construct(Invoice $invoice)
 | 
			
		||||
    {
 | 
			
		||||
        $this->invoice = $invoice;
 | 
			
		||||
        $this->client = $client ?? $invoice->client;
 | 
			
		||||
        $this->base_repository = new BaseRepository();
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
@ -49,6 +48,8 @@ class InvoiceWorkflowSettings implements ShouldQueue
 | 
			
		||||
     */
 | 
			
		||||
    public function handle()
 | 
			
		||||
    {
 | 
			
		||||
        $this->client = $this->invoice->client;
 | 
			
		||||
 | 
			
		||||
        if ($this->client->getSetting('auto_archive_invoice')) {
 | 
			
		||||
            /* Throws: Payment amount xxx does not match invoice totals. */
 | 
			
		||||
            $this->base_repository->archive($this->invoice);
 | 
			
		||||
 | 
			
		||||
@ -205,7 +205,7 @@ class Import implements ShouldQueue
 | 
			
		||||
 | 
			
		||||
        $this->setInitialCompanyLedgerBalances();
 | 
			
		||||
        
 | 
			
		||||
        $this->fixClientBalances();
 | 
			
		||||
        // $this->fixClientBalances();
 | 
			
		||||
 | 
			
		||||
        Mail::to($this->user)
 | 
			
		||||
            ->send(new MigrationCompleted($this->company));
 | 
			
		||||
@ -779,6 +779,14 @@ class Import implements ShouldQueue
 | 
			
		||||
                CreditFactory::create($this->company->id, $modified['user_id'])
 | 
			
		||||
            );
 | 
			
		||||
 | 
			
		||||
            //remove credit balance from ledger
 | 
			
		||||
            if($credit->balance > 0 && $credit->client->balance > 0){
 | 
			
		||||
                $client = $credit->client;
 | 
			
		||||
                $client->balance -= $credit->balance;
 | 
			
		||||
                $client->save();
 | 
			
		||||
            }
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
            $key = "credits_{$resource['id']}";
 | 
			
		||||
 | 
			
		||||
            $this->ids['credits'][$key] = [
 | 
			
		||||
@ -897,8 +905,9 @@ class Import implements ShouldQueue
 | 
			
		||||
                    if ($this->tryTransformingId('invoices', $invoice['invoice_id'])) {
 | 
			
		||||
                        $modified['invoices'][$key]['invoice_id'] = $this->transformId('invoices', $invoice['invoice_id']);
 | 
			
		||||
                    } else {
 | 
			
		||||
                        $modified['credits'][$key]['credit_id'] = $this->transformId('credits', $invoice['invoice_id']);
 | 
			
		||||
                        $modified['credits'][$key]['amount'] = $modified['invoices'][$key]['amount'];
 | 
			
		||||
                       nlog($modified['invoices']);
 | 
			
		||||
                        // $modified['credits'][$key]['credit_id'] = $this->transformId('credits', $invoice['invoice_id']);
 | 
			
		||||
                        // $modified['credits'][$key]['amount'] = $modified['invoices'][$key]['amount'];
 | 
			
		||||
                    }
 | 
			
		||||
                }
 | 
			
		||||
            }
 | 
			
		||||
@ -1433,19 +1442,19 @@ class Import implements ShouldQueue
 | 
			
		||||
    /* In V4 we use negative invoices (credits) and add then into the client balance. In V5, these sit off ledger and are applied later.
 | 
			
		||||
     This next section will check for credit balances and reduce the client balance so that the V5 balances are correct
 | 
			
		||||
    */
 | 
			
		||||
    private function fixClientBalances()
 | 
			
		||||
    {
 | 
			
		||||
    // private function fixClientBalances()
 | 
			
		||||
    // {
 | 
			
		||||
       
 | 
			
		||||
        Client::cursor()->each(function ($client) {
 | 
			
		||||
    //     Client::cursor()->each(function ($client) {
 | 
			
		||||
 | 
			
		||||
            $credit_balance = $client->credits->where('is_deleted', false)->sum('balance');
 | 
			
		||||
    //         $credit_balance = $client->credits->where('is_deleted', false)->sum('balance');
 | 
			
		||||
 | 
			
		||||
            if($credit_balance > 0){
 | 
			
		||||
                $client->balance += $credit_balance;
 | 
			
		||||
                $client->save();
 | 
			
		||||
            }
 | 
			
		||||
    //         if($credit_balance > 0){
 | 
			
		||||
    //             $client->balance += $credit_balance;
 | 
			
		||||
    //             $client->save();
 | 
			
		||||
    //         }
 | 
			
		||||
 | 
			
		||||
        });
 | 
			
		||||
    //     });
 | 
			
		||||
 | 
			
		||||
    }
 | 
			
		||||
    // }
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
@ -92,6 +92,10 @@ class PaymentMigrationRepository extends BaseRepository
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        $payment->status_id = $data['status_id'];
 | 
			
		||||
 | 
			
		||||
        if($payment->status_id == Payment::STATUS_CANCELLED)
 | 
			
		||||
            $payment->is_deleted = true;
 | 
			
		||||
 | 
			
		||||
        $payment->deleted_at = $data['deleted_at'] ?: null;
 | 
			
		||||
        $payment->save();
 | 
			
		||||
 | 
			
		||||
@ -113,20 +117,26 @@ class PaymentMigrationRepository extends BaseRepository
 | 
			
		||||
 | 
			
		||||
            $payment->invoices()->saveMany($invoices);
 | 
			
		||||
 | 
			
		||||
            $payment->invoices->each(function ($inv) use ($invoice_totals, $refund_totals) {
 | 
			
		||||
            $payment->invoices->each(function ($inv) use ($invoice_totals, $refund_totals, $payment) {
 | 
			
		||||
 | 
			
		||||
                $inv->pivot->amount = $invoice_totals;
 | 
			
		||||
                $inv->pivot->refunded = $refund_totals;
 | 
			
		||||
                $inv->pivot->save();
 | 
			
		||||
 | 
			
		||||
                $inv->paid_to_date += $invoice_totals;
 | 
			
		||||
                if($payment->status_id != Payment::STATUS_CANCELLED || !$payment->is_deleted)
 | 
			
		||||
                {
 | 
			
		||||
                    $inv->pivot->amount = $invoice_totals;
 | 
			
		||||
                    $inv->pivot->refunded = $refund_totals;
 | 
			
		||||
                    $inv->pivot->save();
 | 
			
		||||
 | 
			
		||||
                if($inv->balance > 0)
 | 
			
		||||
                    $inv->paid_to_date += $invoice_totals;
 | 
			
		||||
                    $inv->balance -= $invoice_totals;
 | 
			
		||||
 | 
			
		||||
                $inv->balance = max(0, $inv->balance);
 | 
			
		||||
                    if($inv->status_id == Invoice::STATUS_PAID)
 | 
			
		||||
                        $inv->balance = 0;
 | 
			
		||||
 | 
			
		||||
                $inv->save();
 | 
			
		||||
                    // if($inv->balance > 0)
 | 
			
		||||
                    // $inv->balance = max(0, $inv->balance);
 | 
			
		||||
 | 
			
		||||
                    $inv->save();
 | 
			
		||||
                }
 | 
			
		||||
 | 
			
		||||
            });
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
@ -12,6 +12,7 @@
 | 
			
		||||
namespace App\Services\Invoice;
 | 
			
		||||
 | 
			
		||||
use App\Jobs\Entity\CreateEntityPdf;
 | 
			
		||||
use App\Jobs\Invoice\InvoiceWorkflowSettings;
 | 
			
		||||
use App\Jobs\Util\UnlinkFile;
 | 
			
		||||
use App\Models\CompanyGateway;
 | 
			
		||||
use App\Models\Expense;
 | 
			
		||||
@ -239,6 +240,9 @@ class InvoiceService
 | 
			
		||||
    public function updateStatus()
 | 
			
		||||
    {
 | 
			
		||||
        if ((int)$this->invoice->balance == 0) {
 | 
			
		||||
            
 | 
			
		||||
            InvoiceWorkflowSettings::dispatch($this->invoice);
 | 
			
		||||
 | 
			
		||||
            $this->setStatus(Invoice::STATUS_PAID);
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
@ -14,6 +14,7 @@ namespace App\Services\Invoice;
 | 
			
		||||
use App\Events\Invoice\InvoiceWasPaid;
 | 
			
		||||
use App\Events\Payment\PaymentWasCreated;
 | 
			
		||||
use App\Factory\PaymentFactory;
 | 
			
		||||
use App\Jobs\Invoice\InvoiceWorkflowSettings;
 | 
			
		||||
use App\Jobs\Payment\EmailPayment;
 | 
			
		||||
use App\Models\Invoice;
 | 
			
		||||
use App\Models\Payment;
 | 
			
		||||
@ -90,6 +91,8 @@ class MarkPaid extends AbstractService
 | 
			
		||||
            ->updatePaidToDate($payment->amount)
 | 
			
		||||
            ->save();
 | 
			
		||||
 | 
			
		||||
        InvoiceWorkflowSettings::dispatchNow($this->invoice);
 | 
			
		||||
 | 
			
		||||
        return $this->invoice;
 | 
			
		||||
    }
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
@ -13,7 +13,7 @@ return [
 | 
			
		||||
    'require_https' => env('REQUIRE_HTTPS', true),
 | 
			
		||||
    'app_url' => rtrim(env('APP_URL', ''), '/'),
 | 
			
		||||
    'app_domain' => env('APP_DOMAIN', ''),
 | 
			
		||||
    'app_version' => '5.1.1',
 | 
			
		||||
    'app_version' => '5.1.2',
 | 
			
		||||
    'minimum_client_version' => '5.0.16',
 | 
			
		||||
    'terms_version' => '1.0.1',
 | 
			
		||||
    'api_secret' => env('API_SECRET', false),
 | 
			
		||||
 | 
			
		||||
							
								
								
									
										2
									
								
								public/flutter_service_worker.js
									
									
									
									
										vendored
									
									
								
							
							
						
						
									
										2
									
								
								public/flutter_service_worker.js
									
									
									
									
										vendored
									
									
								
							@ -26,7 +26,7 @@ const RESOURCES = {
 | 
			
		||||
"assets/packages/material_design_icons_flutter/lib/fonts/materialdesignicons-webfont.ttf": "3e722fd57a6db80ee119f0e2c230ccff",
 | 
			
		||||
"assets/fonts/MaterialIcons-Regular.otf": "1288c9e28052e028aba623321f7826ac",
 | 
			
		||||
"/": "23224b5e03519aaa87594403d54412cf",
 | 
			
		||||
"main.dart.js": "de56853e220a15bb1f361a7bcc8e396a",
 | 
			
		||||
"main.dart.js": "ea5e5c0e239e56013a4a49a241fd6c73",
 | 
			
		||||
"icons/Icon-512.png": "0f9aff01367f0a0c69773d25ca16ef35",
 | 
			
		||||
"icons/Icon-192.png": "bb1cf5f6982006952211c7c8404ffbed",
 | 
			
		||||
"manifest.json": "77215c1737c7639764e64a192be2f7b8",
 | 
			
		||||
 | 
			
		||||
							
								
								
									
										105026
									
								
								public/main.dart.js
									
									
									
									
										vendored
									
									
								
							
							
						
						
									
										105026
									
								
								public/main.dart.js
									
									
									
									
										vendored
									
									
								
							
										
											
												File diff suppressed because one or more lines are too long
											
										
									
								
							@ -275,6 +275,7 @@ class InvoiceInclusiveTest extends TestCase
 | 
			
		||||
        $this->assertEquals($this->invoice_calc->getSubTotal(), 19);
 | 
			
		||||
        $this->assertEquals($this->invoice_calc->getTotalDiscount(), 0.95);
 | 
			
		||||
        $this->assertEquals($this->invoice_calc->getTotalTaxes(), 4.92);
 | 
			
		||||
        nlog($this->invoice_calc->getTaxMap());
 | 
			
		||||
        $this->assertEquals(count($this->invoice_calc->getTaxMap()), 1);
 | 
			
		||||
        $this->assertEquals($this->invoice_calc->getTotal(), 18.05);
 | 
			
		||||
        $this->assertEquals($this->invoice_calc->getBalance(), 18.05);
 | 
			
		||||
 | 
			
		||||
		Loading…
	
	
			
			x
			
			
		
	
		Reference in New Issue
	
	Block a user