Fixes for company tokens. (#3375)

* Testing Company Ledger

* Fixes for company ledger

* Fixes for company ledger

* Company ledger testS

* Fixes for user / client / contacts transformers

* Fixes for tests

* Fixes for tokens
This commit is contained in:
David Bomba 2020-02-26 14:26:07 +11:00 committed by GitHub
parent 3e39344d3b
commit f20b0f7720
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
32 changed files with 255 additions and 48 deletions

View File

@ -120,7 +120,7 @@ class CreateTestData extends Command
'is_admin' => 1,
'is_locked' => 0,
'permissions' => '',
'settings' => new \stdClass,
'settings' => null,
]);
factory(\App\Models\Product::class,50)->create([

View File

@ -92,7 +92,8 @@ class SendTestEmails extends Command
'is_admin' => 1,
'is_locked' => 0,
'permissions' => '',
'settings' => DefaultSettings::userSettings(),
//'settings' => DefaultSettings::userSettings(),
'settings' => null,
]);
}
@ -117,7 +118,7 @@ class SendTestEmails extends Command
'client_id' => $client->id,
'company_id' => $company->id,
'is_primary' => 1,
'send' => true,
'send_email' => true,
'email' => $faker->safeEmail,
]);
@ -125,7 +126,7 @@ class SendTestEmails extends Command
'user_id' => $user->id,
'client_id' => $client->id,
'company_id' => $company->id,
'send' => true,
'send_email' => true,
'email' => $faker->safeEmail,
]);
}

View File

@ -25,6 +25,7 @@ class ClientFactory
$client->name = '';
$client->website = '';
$client->private_notes = '';
$client->public_notes = '';
$client->balance = 0;
$client->paid_to_date = 0;
$client->country_id = 4;

View File

@ -13,12 +13,13 @@ namespace App\Factory;
use App\DataMapper\ClientSettings;
use App\DataMapper\CompanySettings;
use App\Models\Client;
use App\Models\Invoice;
use App\Models\RecurringInvoice;
class recurring_invoiceToInvoiceFactory
class RecurringInvoiceToInvoiceFactory
{
public static function create(RecurringInvoice $recurring_invoice) :Invoice
public static function create(RecurringInvoice $recurring_invoice, Client $client) :Invoice
{
$invoice = new Invoice();
$invoice->status_id = Invoice::STATUS_DRAFT;

View File

@ -173,8 +173,11 @@ class LoginController extends BaseController
$user->setCompany($user->company_user->account->default_company);
$ct = CompanyUser::whereUserId($user->id)->with('company');
return $this->listResponse($ct);
} else {
$this->incrementLoginAttempts($request);
return response()

View File

@ -214,7 +214,7 @@ class CompanyController extends BaseController
'is_admin' => 1,
'is_locked' => 0,
'permissions' => '',
'settings' => DefaultSettings::userSettings(),
//'settings' => DefaultSettings::userSettings(),
]);
/*

View File

@ -60,11 +60,13 @@ class StoreUserRequest extends Request
}
if (!isset($input['company_user']['settings'])) {
$input['company_user']['settings'] = DefaultSettings::userSettings();
//$input['company_user']['settings'] = DefaultSettings::userSettings();
$input['company_user']['settings'] = null;
}
} else {
$input['company_user'] = [
'settings' => DefaultSettings::userSettings(),
//'settings' => DefaultSettings::userSettings(),
'settings' => null,
'permissions' => '',
];
}

View File

@ -53,7 +53,7 @@ class SendRecurring implements ShouldQueue
{
// Generate Standard Invoice
$invoice = RecurringInvoiceToInvoiceFactory::create($this->recurring_invoice);
$invoice = RecurringInvoiceToInvoiceFactory::create($this->recurring_invoice, $this->recurring_invoice->client);
$invoice->number = $this->getNextRecurringInvoiceNumber($this->recurring_invoice->client);
$invoice->status_id = Invoice::STATUS_SENT;
$invoice->save();

View File

@ -70,7 +70,8 @@ class CreateUser
'is_admin' => 1,
'is_locked' => 0,
'permissions' => '',
'settings' => DefaultSettings::userSettings(),
//'settings' => DefaultSettings::userSettings(),
'settings' => null,
]);
event(new UserWasCreated($user, $this->company));

View File

@ -169,6 +169,9 @@ class Import implements ShouldQueue
$company_repository = new CompanyRepository();
$company_repository->save($data, $this->company);
Company::reguard();
}
/**
@ -208,6 +211,9 @@ class Import implements ShouldQueue
$tax_rate->save();
}
TaxRate::reguard();
}
/**
@ -254,6 +260,9 @@ class Import implements ShouldQueue
'new' => $user->id,
];
}
User::reguard();
}
/**
@ -302,6 +311,9 @@ class Import implements ShouldQueue
'new' => $client->id,
];
}
Client::reguard();
}
private function processProducts(array $data): void
@ -335,6 +347,9 @@ class Import implements ShouldQueue
$this->company->id, $modified['user_id'])
);
}
Product::reguard();
}
private function processInvoices(array $data): void
@ -380,6 +395,9 @@ class Import implements ShouldQueue
];
}
Invoice::reguard();
}
private function processCredits(array $data): void
@ -423,6 +441,9 @@ class Import implements ShouldQueue
'new' => $credit->id,
];
}
Credit::reguard();
}
private function processQuotes(array $data): void
@ -470,6 +491,9 @@ class Import implements ShouldQueue
];
}
Quote::reguard();
}
private function processPayments(array $data): void
@ -524,6 +548,9 @@ class Import implements ShouldQueue
];
}
Payment::reguard();
}
private function processDocuments(array $data): void
@ -617,6 +644,8 @@ class Import implements ShouldQueue
];
}
CompanyGateway::reguard();
}
private function processClientGatewayTokens(array $data) :void
@ -643,6 +672,9 @@ class Import implements ShouldQueue
]
];
}
ClientGatewayToken::reguard();
}
/**

View File

@ -89,6 +89,7 @@ class Client extends BaseModel implements HasLocalePreference
'vat_number',
'id_number',
'group_settings_id',
'public_notes'
];

View File

@ -61,6 +61,7 @@ class Company extends BaseModel
'custom_fields',
'enable_product_cost',
'enable_product_quantity',
'enabled_modules',
'default_quantity',
'enable_invoice_quantity',
'enabled_tax_rates',

View File

@ -15,6 +15,9 @@ use Illuminate\Database\Eloquent\Relations\Pivot;
class CompanyUser extends Pivot
{
use \Staudenmeir\EloquentHasManyDeep\HasRelationships;
// protected $guarded = ['id'];
protected $dateFormat = 'Y-m-d H:i:s.u';
@ -74,18 +77,29 @@ class CompanyUser extends Pivot
/*todo monitor this function - may fail under certain conditions*/
public function token()
{
return $this->belongsTo(CompanyToken::class, 'user_id', 'user_id');
return $this->hasMany(CompanyToken::class, 'user_id', 'user_id');
//return $this->hasMany(CompanyToken::class);
//return $this->hasOne(CompanyToken::class, 'user_id', 'user_id','company_id', 'company_id');
//return $this->hasOneDeep(CompanyToken::class, [CompanyUser::class], ['user_id','company_id'], ['company_id','company_id']);
//return $this->belongsTo(CompanyToken::class, 'user_id', 'user_id');
// return $this->hasOneThrough(
// CompanyToken::class,
// CompanyUser::class,
// 'user_id', // Foreign key on CompanyUser table...
// 'company_id', // Foreign key on CompanyToken table...
// 'user_id', // Local key on CompanyToken table...
// 'company_id' // Local key on CompanyUser table...
// );
/*
return $this->hasOneThrough(
CompanyToken::class,
CompanyUser::class,
'user_id', // Foreign key on CompanyUser table...
'company_id', // Foreign key on CompanyToken table...
'user_id', // Local key on CompanyToken table...
'company_id' // Local key on CompanyUser table...
);
*/
}
public function tokens()
{
return $this->hasMany(CompanyToken::class, 'user_id', 'user_id');
}
}

View File

@ -77,6 +77,7 @@ class User extends Authenticatable implements MustVerifyEmail
'custom_value2',
'custom_value3',
'custom_value4',
'is_deleted',
];
/**

View File

@ -49,7 +49,7 @@ class CreditRepository extends BaseRepository
*/
public function save(array $data, Credit $credit) : ?Credit
{
\Log::error($data);
$credit->fill($data);
$credit->save();

View File

@ -42,10 +42,10 @@ class MarkSent extends AbstractService
event(new InvoiceWasMarkedSent($this->invoice, $this->invoice->company));
$this->client->service()->updateBalance($this->invoice->balance)->save();
$this->invoice->service()->setStatus(Invoice::STATUS_SENT)->applyNumber()->save();
$this->client->service()->updateBalance($this->invoice->balance)->save();
$this->invoice->ledger()->updateInvoiceBalance($this->invoice->balance);
//UpdateCompanyLedgerWithInvoice::dispatchNow($this->invoice, $this->invoice->balance, $this->invoice->company);

View File

@ -33,8 +33,6 @@ class LedgerService
if ($company_ledger) {
$balance = $company_ledger->balance;
}
$adjustment = $balance + $adjustment;
$company_ledger = CompanyLedgerFactory::create($this->entity->company_id, $this->entity->user_id);
$company_ledger->client_id = $this->entity->client_id;

View File

@ -44,7 +44,9 @@ class ClientContactTransformer extends EntityTransformer
'custom_value3' => $contact->custom_value3 ?: '',
'custom_value4' => $contact->custom_value4 ?: '',
'contact_key' => $contact->contact_key ?: '',
'send' => (bool) $contact->send,
'send_email' => (bool) $contact->send_email,
'last_login' => (int)$contact->last_login,
'password' => '',
];
}
}

View File

@ -88,6 +88,8 @@ class ClientTransformer extends EntityTransformer
'paid_to_date' => (float) $client->paid_to_date,
'credit_balance' => (float) $client->credit_balance,
'last_login' => (int)$client->last_login,
'size_id' => (int)$client->size_id,
'public_notes' => $client->public_notes,
// 'currency_id' => (string)$client->currency_id,
'address1' => $client->address1 ?: '',
'address2' => $client->address2 ?: '',

View File

@ -86,8 +86,10 @@ class CompanyUserTransformer extends EntityTransformer
public function includeToken(CompanyUser $company_user)
{
$token = $company_user->tokens->where('company_id', $company_user->company_id)->where('user_id', $company_user->user_id)->first();
$transformer = new CompanyTokenTransformer($this->serializer);
return $this->includeItem($company_user->token, $transformer, CompanyToken::class);
return $this->includeItem($token, $transformer, CompanyToken::class);
}
}

View File

@ -54,6 +54,8 @@ class UserTransformer extends EntityTransformer
'last_login' => Carbon::parse($user->last_login)->timestamp,
'updated_at' => (int)$user->updated_at,
'archived_at' => (int)$user->deleted_at,
'created_at' => (int)$user->created_at,
'is_deleted' => (bool)$user->is_deleted,
'phone' => $user->phone ?: '',
'email_verified_at' => $user->getEmailVerifiedAt(),
'signature' => $user->signature ?: '',

View File

@ -87,7 +87,7 @@ trait CompanyGatewayFeesAndLimitsSaver
$fal = new FeesAndLimits;
foreach ($value as $k => $v) {
$fal->{$k} = $v;
$fal->{$k} = $v ?: '';
}
$new_arr[$key] = (array)$fal;

View File

@ -158,7 +158,8 @@ class CreateUsersTable extends Migration
$table->boolean('enable_invoice_quantity')->default(true);
$table->boolean('show_product_cost')->default(false);
$table->unsignedInteger('enabled_tax_rates')->default(1);
$table->unsignedInteger('enabled_modules')->default(0);
$table->boolean('enable_product_cost')->default(0);
$table->boolean('enable_product_quantity')->default(1);
$table->boolean('default_quantity')->default(1);
@ -263,7 +264,8 @@ class CreateUsersTable extends Migration
$table->unsignedInteger('avatar_width')->nullable();
$table->unsignedInteger('avatar_height')->nullable();
$table->unsignedInteger('avatar_size')->nullable();
$table->boolean('is_deleted')->default(false);
$table->datetime('last_login')->nullable();
$table->mediumText('signature')->nullable();
$table->string('password');
@ -306,6 +308,7 @@ class CreateUsersTable extends Migration
$table->string('name')->nullable();
$table->string('website')->nullable();
$table->text('private_notes')->nullable();
$table->text('public_notes')->nullable();
$table->text('client_hash')->nullable();
$table->string('logo', 255)->nullable();
$table->string('phone', 255)->nullable();

View File

@ -100,7 +100,7 @@ class RandomDataSeeder extends Seeder
'is_admin' => 1,
'is_locked' => 0,
'permissions' => '',
'settings' => DefaultSettings::userSettings(),
'settings' => null,
]);
$client = factory(\App\Models\Client::class)->create([

View File

@ -48,14 +48,13 @@ class UsersTableSeeder extends Seeder
'create_client'
]);
$userSettings = DefaultSettings::userSettings();
$user->companies()->attach($company->id, [
'account_id' => $account->id,
'is_owner' => 1,
'is_admin' => 1,
'permissions' => $userPermissions->toJson(),
'settings' => json_encode($userSettings),
'settings' => null,
'is_locked' => 0,
]);

View File

@ -66,8 +66,8 @@ class ClientPortalTest extends DuskTestCase
'is_owner' => 1,
'is_admin' => 1,
'is_locked' => 0,
'permissions' => json_encode([]),
'settings' => json_encode(DefaultSettings::userSettings()),
'permissions' => '',
'settings' => null,
]);
$client = factory(\App\Models\Client::class)->create([

View File

@ -12,6 +12,7 @@ use Illuminate\Database\Eloquent\Model;
use Illuminate\Foundation\Testing\DatabaseTransactions;
use Illuminate\Foundation\Testing\RefreshDatabase;
use Illuminate\Foundation\Testing\WithFaker;
use Illuminate\Routing\Middleware\ThrottleRequests;
use Illuminate\Support\Facades\Log;
use Illuminate\Support\Facades\Session;
use Tests\TestCase;
@ -38,6 +39,9 @@ class RecurringQuoteTest extends TestCase
Model::reguard();
$this->withoutMiddleware(
ThrottleRequests::class
);
}

View File

@ -57,6 +57,7 @@ class RefundTest extends TestCase
$this->withoutExceptionHandling();
}
/**

View File

@ -46,6 +46,10 @@ class TemplateApiTest extends TestCase
$this->faker = \Faker\Factory::create();
Model::reguard();
$this->withoutMiddleware(
ThrottleRequests::class
);
}

View File

@ -7,6 +7,7 @@ use App\Events\Invoice\InvoiceWasCreated;
use App\Events\Invoice\InvoiceWasUpdated;
use App\Events\Payment\PaymentWasCreated;
use App\Factory\CompanyUserFactory;
use App\Factory\InvoiceItemFactory;
use App\Jobs\Invoice\MarkInvoicePaid;
use App\Models\Account;
use App\Models\Activity;
@ -141,10 +142,139 @@ class CompanyLedgerTest extends TestCase
public function testBaseLine()
{
$this->assertEquals($this->company->invoices->count(), 0);
$this->assertEquals($this->company->clients->count(), 1);
$this->assertEquals($this->client->balance, 0);
}
public function testLedger()
{
$line_items = [];
$item = [];
$item['quantity'] = 1;
$item['cost'] = 10;
$line_items[] = $item;
$data = [
'client_id' => $this->encodePrimaryKey($this->client->id),
'line_items' => $line_items
];
/* Test adding one invoice */
$response = $this->withHeaders([
'X-API-SECRET' => config('ninja.api_secret'),
'X-API-TOKEN' => $this->token,
])->post('/api/v1/invoices/', $data)
->assertStatus(200);
$acc = $response->json();
$invoice = Invoice::find($this->decodePrimaryKey($acc['data']['id']));
$invoice->service()->markSent()->save();
$this->assertEquals($invoice->client->balance, 10);
$invoice_ledger = $invoice->company_ledger->sortByDesc('id')->first();
$this->assertEquals($invoice_ledger->balance, $invoice->client->balance);
$this->assertEquals($invoice->client->paid_to_date, 0);
/* Test adding another invoice */
$response = $this->withHeaders([
'X-API-SECRET' => config('ninja.api_secret'),
'X-API-TOKEN' => $this->token,
])->post('/api/v1/invoices/', $data)
->assertStatus(200);
$acc = $response->json();
$invoice = Invoice::find($this->decodePrimaryKey($acc['data']['id']));
$invoice->service()->markSent()->save();
$this->assertEquals($invoice->client->balance, 20);
$invoice_ledger = $invoice->company_ledger->sortByDesc('id')->first();
$this->assertEquals($invoice_ledger->balance, $invoice->client->balance);
$this->assertEquals($invoice->client->paid_to_date, 0);
/* Test making a payment */
$data = [
'client_id' => $this->encodePrimaryKey($invoice->client_id),
'amount' => $invoice->balance,
'invoices' => [
[
'invoice_id' => $this->encodePrimaryKey($invoice->id),
'amount' => $invoice->balance
],
],
'date' => '2020/12/11',
];
$response = $this->withHeaders([
'X-API-SECRET' => config('ninja.api_secret'),
'X-API-TOKEN' => $this->token,
])->post('/api/v1/payments/', $data);
$acc = $response->json();
$payment = Payment::find($this->decodePrimaryKey($acc['data']['id']));
$payment_ledger = $payment->company_ledger->sortByDesc('id')->first();
$invoice->fresh();
$this->assertEquals($payment->client->balance, $payment_ledger->balance);
$this->assertEquals($payment->client->paid_to_date, 10);
$invoice = Invoice::find($invoice->id);
$this->assertEquals(Invoice::STATUS_PAID, $invoice->status_id);
/* Test making a refund of a payment */
$refund = $invoice->amount;
$data = [
'id' => $this->encodePrimaryKey($payment->id),
'client_id' => $this->encodePrimaryKey($invoice->client_id),
'amount' => $refund,
'invoices' => [
[
'invoice_id' => $this->encodePrimaryKey($invoice->id),
'amount' => $refund,
],
],
'date' => '2020/12/11',
];
$response = $this->withHeaders([
'X-API-SECRET' => config('ninja.api_secret'),
'X-API-TOKEN' => $this->token,
])->post('/api/v1/payments/refund', $data);
$acc = $response->json();
$invoice = Invoice::find($invoice->id);
$this->assertEquals($refund, $invoice->balance);
}
}

View File

@ -3,8 +3,10 @@
namespace Tests;
use Illuminate\Foundation\Testing\TestCase as BaseTestCase;
use Illuminate\Routing\Middleware\ThrottleRequests;
abstract class TestCase extends BaseTestCase
{
use CreatesApplication;
}

View File

@ -312,19 +312,19 @@ class ImportTest extends TestCase
$this->assertTrue(file_exists($migration_archive));
}
public function testMigrationFileBeingExtracted()
{
$migration_archive = base_path() . '/tests/Unit/Migration/migration.zip';
// public function testMigrationFileBeingExtracted()
// {
// $migration_archive = base_path() . '/tests/Unit/Migration/migration.zip';
StartMigration::dispatchNow($migration_archive, $this->user, $this->company);
// StartMigration::dispatchNow($migration_archive, $this->user, $this->company);
$extracted_archive = storage_path("migrations/migration");
$migration_file = storage_path("migrations/migration/migration.json");
// $extracted_archive = storage_path("migrations/migration");
// $migration_file = storage_path("migrations/migration/migration.json");
$this->assertTrue(file_exists($extracted_archive));
$this->assertTrue(is_dir($extracted_archive));
$this->assertTrue(file_exists($migration_file));
}
// $this->assertTrue(file_exists($extracted_archive));
// $this->assertTrue(is_dir($extracted_archive));
// $this->assertTrue(file_exists($migration_file));
// }
public function testValidityOfImportedData()
{