mirror of
https://github.com/invoiceninja/invoiceninja.git
synced 2025-05-24 02:14:21 -04:00
merge v5-dev
This commit is contained in:
commit
9b6bfbf96c
@ -91,38 +91,38 @@ class CheckData extends Command
|
||||
|
||||
protected $wrong_paid_status = 0;
|
||||
|
||||
|
||||
public function handle()
|
||||
{
|
||||
$time_start = microtime(true);
|
||||
$time_start = microtime(true);
|
||||
|
||||
$database_connection = $this->option('database') ? $this->option('database') : 'Connected to Default DB';
|
||||
$fix_status = $this->option('fix') ? 'Fixing Issues' : 'Just checking issues ';
|
||||
$fix_status = $this->option('fix') ? "Fixing Issues" : "Just checking issues ";
|
||||
|
||||
$this->logMessage(date('Y-m-d h:i:s').' Running CheckData... on '.$database_connection." Fix Status = {$fix_status}");
|
||||
$this->logMessage(date('Y-m-d h:i:s').' Running CheckData... on ' . $database_connection . " Fix Status = {$fix_status}");
|
||||
|
||||
if ($database = $this->option('database')) {
|
||||
config(['database.default' => $database]);
|
||||
}
|
||||
|
||||
$this->checkInvoiceBalances();
|
||||
$this->checkInvoiceBalances();
|
||||
$this->checkClientBalanceEdgeCases();
|
||||
$this->checkPaidToDatesNew();
|
||||
|
||||
$this->checkContacts();
|
||||
$this->checkVendorContacts();
|
||||
$this->checkEntityInvitations();
|
||||
$this->checkCompanyData();
|
||||
$this->checkBalanceVsPaidStatus();
|
||||
|
||||
if (Ninja::isHosted()) {
|
||||
if(Ninja::isHosted())
|
||||
$this->checkAccountStatuses();
|
||||
}
|
||||
|
||||
if (! $this->option('client_id')) {
|
||||
$this->checkOAuth();
|
||||
}
|
||||
|
||||
$this->logMessage('Done: '.strtoupper($this->isValid ? Account::RESULT_SUCCESS : Account::RESULT_FAILURE));
|
||||
$this->logMessage('Total execution time in seconds: '.(microtime(true) - $time_start));
|
||||
$this->logMessage('Total execution time in seconds: ' . (microtime(true) - $time_start));
|
||||
|
||||
$errorEmail = config('ninja.error_email');
|
||||
|
||||
@ -235,7 +235,7 @@ class CheckData extends Command
|
||||
if ($this->option('fix') == 'true') {
|
||||
foreach ($clients as $client) {
|
||||
$this->logMessage("Fixing missing contacts #{$client->id}");
|
||||
|
||||
|
||||
$new_contact = ClientContactFactory::create($client->company_id, $client->user_id);
|
||||
$new_contact->client_id = $client->id;
|
||||
$new_contact->contact_key = Str::random(40);
|
||||
@ -243,6 +243,7 @@ class CheckData extends Command
|
||||
$new_contact->save();
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
private function checkVendorContacts()
|
||||
@ -290,11 +291,12 @@ class CheckData extends Command
|
||||
}
|
||||
|
||||
if ($this->option('fix') == 'true') {
|
||||
|
||||
$vendors = Vendor::withTrashed()->doesntHave('contacts')->get();
|
||||
|
||||
foreach ($vendors as $vendor) {
|
||||
$this->logMessage("Fixing missing vendor contacts #{$vendor->id}");
|
||||
|
||||
|
||||
$new_contact = VendorContactFactory::create($vendor->company_id, $vendor->user_id);
|
||||
$new_contact->vendor_id = $vendor->id;
|
||||
$new_contact->contact_key = Str::random(40);
|
||||
@ -302,8 +304,10 @@ class CheckData extends Command
|
||||
$new_contact->save();
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
|
||||
private function checkFailedJobs()
|
||||
{
|
||||
if (config('ninja.testvars.travis')) {
|
||||
@ -352,32 +356,36 @@ class CheckData extends Command
|
||||
|
||||
private function checkEntityInvitations()
|
||||
{
|
||||
RecurringInvoiceInvitation::where('deleted_at', '0000-00-00 00:00:00.000000')->withTrashed()->update(['deleted_at' => null]);
|
||||
InvoiceInvitation::where('deleted_at', '0000-00-00 00:00:00.000000')->withTrashed()->update(['deleted_at' => null]);
|
||||
QuoteInvitation::where('deleted_at', '0000-00-00 00:00:00.000000')->withTrashed()->update(['deleted_at' => null]);
|
||||
CreditInvitation::where('deleted_at', '0000-00-00 00:00:00.000000')->withTrashed()->update(['deleted_at' => null]);
|
||||
|
||||
RecurringInvoiceInvitation::where('deleted_at',"0000-00-00 00:00:00.000000")->withTrashed()->update(['deleted_at' => null]);
|
||||
InvoiceInvitation::where('deleted_at',"0000-00-00 00:00:00.000000")->withTrashed()->update(['deleted_at' => null]);
|
||||
QuoteInvitation::where('deleted_at',"0000-00-00 00:00:00.000000")->withTrashed()->update(['deleted_at' => null]);
|
||||
CreditInvitation::where('deleted_at',"0000-00-00 00:00:00.000000")->withTrashed()->update(['deleted_at' => null]);
|
||||
|
||||
$entities = ['invoice', 'quote', 'credit', 'recurring_invoice'];
|
||||
|
||||
foreach ($entities as $entity) {
|
||||
foreach($entities as $entity)
|
||||
{
|
||||
$table = "{$entity}s";
|
||||
$invitation_table = "{$entity}_invitations";
|
||||
|
||||
$entities = DB::table($table)
|
||||
->leftJoin($invitation_table, function ($join) use ($invitation_table, $table, $entity) {
|
||||
$entities = DB::table($table)
|
||||
->leftJoin($invitation_table, function ($join) use($invitation_table, $table, $entity){
|
||||
$join->on("{$invitation_table}.{$entity}_id", '=', "{$table}.id");
|
||||
// ->whereNull("{$invitation_table}.deleted_at");
|
||||
// ->whereNull("{$invitation_table}.deleted_at");
|
||||
})
|
||||
->groupBy("{$table}.id", "{$table}.user_id", "{$table}.company_id", "{$table}.client_id")
|
||||
->havingRaw("count({$invitation_table}.id) = 0")
|
||||
->get(["{$table}.id", "{$table}.user_id", "{$table}.company_id", "{$table}.client_id"]);
|
||||
|
||||
$this->logMessage($entities->count()." {$table} without any invitations");
|
||||
|
||||
if ($this->option('fix') == 'true') {
|
||||
$this->fixInvitations($entities, $entity);
|
||||
}
|
||||
$this->logMessage($entities->count()." {$table} without any invitations");
|
||||
|
||||
if ($this->option('fix') == 'true')
|
||||
$this->fixInvitations($entities, $entity);
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
private function fixInvitations($entities, $entity)
|
||||
@ -386,7 +394,8 @@ class CheckData extends Command
|
||||
|
||||
$entity_obj = 'App\Models\\'.ucfirst(Str::camel($entity)).'Invitation';
|
||||
|
||||
foreach ($entities as $entity) {
|
||||
foreach($entities as $entity)
|
||||
{
|
||||
$invitation = new $entity_obj();
|
||||
$invitation->company_id = $entity->company_id;
|
||||
$invitation->user_id = $entity->user_id;
|
||||
@ -394,17 +403,20 @@ class CheckData extends Command
|
||||
$invitation->client_contact_id = ClientContact::whereClientId($entity->client_id)->first()->id;
|
||||
$invitation->key = Str::random(config('ninja.key_length'));
|
||||
|
||||
try {
|
||||
try{
|
||||
$invitation->save();
|
||||
} catch (\Exception $e) {
|
||||
}
|
||||
catch(\Exception $e){
|
||||
$invitation = null;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
private function clientPaidToDateQuery()
|
||||
{
|
||||
$results = \DB::select(\DB::raw('
|
||||
$results = \DB::select( \DB::raw("
|
||||
SELECT
|
||||
clients.id as client_id,
|
||||
clients.paid_to_date as client_paid_to_date,
|
||||
@ -419,14 +431,14 @@ class CheckData extends Command
|
||||
GROUP BY clients.id
|
||||
HAVING payments_applied != client_paid_to_date
|
||||
ORDER BY clients.id;
|
||||
'));
|
||||
|
||||
") );
|
||||
|
||||
return $results;
|
||||
}
|
||||
|
||||
private function clientCreditPaymentables($client)
|
||||
{
|
||||
$results = \DB::select(\DB::raw('
|
||||
$results = \DB::select( \DB::raw("
|
||||
SELECT
|
||||
SUM(paymentables.amount - paymentables.refunded) as credit_payment
|
||||
FROM payments
|
||||
@ -438,8 +450,8 @@ class CheckData extends Command
|
||||
AND paymentables.amount > 0
|
||||
AND payments.is_deleted = 0
|
||||
AND payments.client_id = ?;
|
||||
'), [App\Models\Credit::class, $client->id]);
|
||||
|
||||
"), [App\Models\Credit::class, $client->id] );
|
||||
|
||||
return $results;
|
||||
}
|
||||
|
||||
@ -448,8 +460,9 @@ class CheckData extends Command
|
||||
$clients_to_check = $this->clientPaidToDateQuery();
|
||||
|
||||
$this->wrong_paid_to_dates = 0;
|
||||
|
||||
foreach ($clients_to_check as $_client) {
|
||||
|
||||
foreach($clients_to_check as $_client)
|
||||
{
|
||||
$client = Client::withTrashed()->find($_client->client_id);
|
||||
|
||||
$credits_from_reversal = Credit::withTrashed()->where('client_id', $client->id)->where('is_deleted', 0)->whereNotNull('invoice_id')->sum('amount');
|
||||
@ -458,22 +471,26 @@ class CheckData extends Command
|
||||
|
||||
$total_paid_to_date = $_client->payments_applied + $credits_used_for_payments[0]->credit_payment - $credits_from_reversal;
|
||||
|
||||
if (round($total_paid_to_date, 2) != round($_client->client_paid_to_date, 2)) {
|
||||
if(round($total_paid_to_date,2) != round($_client->client_paid_to_date,2)){
|
||||
|
||||
$this->wrong_paid_to_dates++;
|
||||
|
||||
$this->logMessage($client->present()->name.' id = # '.$client->id." - Client Paid To Date = {$client->paid_to_date} != Invoice Payments = {$total_paid_to_date} - {$_client->payments_applied} + {$credits_used_for_payments[0]->credit_payment}");
|
||||
|
||||
$this->isValid = false;
|
||||
|
||||
if ($this->option('paid_to_date')) {
|
||||
$this->logMessage("# {$client->id} ".$client->present()->name.' - '.$client->number." Fixing {$client->paid_to_date} to {$total_paid_to_date}");
|
||||
if($this->option('paid_to_date')){
|
||||
$this->logMessage("# {$client->id} " . $client->present()->name.' - '.$client->number." Fixing {$client->paid_to_date} to {$total_paid_to_date}");
|
||||
$client->paid_to_date = $total_paid_to_date;
|
||||
$client->save();
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
$this->logMessage("{$this->wrong_paid_to_dates} clients with incorrect paid to dates");
|
||||
|
||||
}
|
||||
|
||||
private function checkPaidToDates()
|
||||
@ -482,12 +499,12 @@ class CheckData extends Command
|
||||
$credit_total_applied = 0;
|
||||
|
||||
$clients = DB::table('clients')
|
||||
->leftJoin('payments', function ($join) {
|
||||
->leftJoin('payments', function($join) {
|
||||
$join->on('payments.client_id', '=', 'clients.id')
|
||||
->where('payments.is_deleted', 0)
|
||||
->whereIn('payments.status_id', [Payment::STATUS_COMPLETED, Payment:: STATUS_PENDING, Payment::STATUS_PARTIALLY_REFUNDED, Payment::STATUS_REFUNDED]);
|
||||
})
|
||||
->where('clients.is_deleted', 0)
|
||||
->where('clients.is_deleted',0)
|
||||
->where('clients.updated_at', '>', now()->subDays(2))
|
||||
->groupBy('clients.id')
|
||||
->havingRaw('clients.paid_to_date != sum(coalesce(payments.amount - payments.refunded, 0))')
|
||||
@ -495,16 +512,19 @@ class CheckData extends Command
|
||||
|
||||
/* Due to accounting differences we need to perform a second loop here to ensure there actually is an issue */
|
||||
$clients->each(function ($client_record) use ($credit_total_applied) {
|
||||
|
||||
$client = Client::withTrashed()->find($client_record->id);
|
||||
|
||||
$total_invoice_payments = 0;
|
||||
|
||||
foreach ($client->invoices()->where('is_deleted', false)->where('status_id', '>', 1)->get() as $invoice) {
|
||||
|
||||
$total_invoice_payments += $invoice->payments()
|
||||
->where('is_deleted', false)->whereIn('status_id', [Payment::STATUS_COMPLETED, Payment:: STATUS_PENDING, Payment::STATUS_PARTIALLY_REFUNDED, Payment::STATUS_REFUNDED])
|
||||
->selectRaw('sum(paymentables.amount - paymentables.refunded) as p')
|
||||
->pluck('p')
|
||||
->first();
|
||||
|
||||
}
|
||||
|
||||
//commented IN 27/06/2021 - sums ALL client payments AND the unapplied amounts to match the client paid to date
|
||||
@ -517,6 +537,7 @@ class CheckData extends Command
|
||||
|
||||
// 10/02/21
|
||||
foreach ($client->payments as $payment) {
|
||||
|
||||
$credit_total_applied += $payment->paymentables()
|
||||
->where('paymentable_type', App\Models\Credit::class)
|
||||
->selectRaw('sum(paymentables.amount - paymentables.refunded) as p')
|
||||
@ -526,7 +547,7 @@ class CheckData extends Command
|
||||
|
||||
if ($credit_total_applied < 0) {
|
||||
$total_invoice_payments += $credit_total_applied;
|
||||
}
|
||||
}
|
||||
|
||||
if (round($total_invoice_payments, 2) != round($client->paid_to_date, 2)) {
|
||||
$this->wrong_paid_to_dates++;
|
||||
@ -535,8 +556,8 @@ class CheckData extends Command
|
||||
|
||||
$this->isValid = false;
|
||||
|
||||
if ($this->option('paid_to_date')) {
|
||||
$this->logMessage("# {$client->id} ".$client->present()->name.' - '.$client->number." Fixing {$client->paid_to_date} to {$total_invoice_payments}");
|
||||
if($this->option('paid_to_date')){
|
||||
$this->logMessage("# {$client->id} " . $client->present()->name.' - '.$client->number." Fixing {$client->paid_to_date} to {$total_invoice_payments}");
|
||||
$client->paid_to_date = $total_invoice_payments;
|
||||
$client->save();
|
||||
}
|
||||
@ -551,7 +572,9 @@ class CheckData extends Command
|
||||
$this->wrong_balances = 0;
|
||||
|
||||
Client::cursor()->where('is_deleted', 0)->where('clients.updated_at', '>', now()->subDays(2))->each(function ($client) {
|
||||
|
||||
$client->invoices->where('is_deleted', false)->whereIn('status_id', '!=', Invoice::STATUS_DRAFT)->each(function ($invoice) use ($client) {
|
||||
|
||||
$total_paid = $invoice->payments()
|
||||
->where('is_deleted', false)->whereIn('status_id', [Payment::STATUS_COMPLETED, Payment:: STATUS_PENDING, Payment::STATUS_PARTIALLY_REFUNDED, Payment::STATUS_REFUNDED])
|
||||
->selectRaw('sum(paymentables.amount - paymentables.refunded) as p')
|
||||
@ -562,7 +585,7 @@ class CheckData extends Command
|
||||
|
||||
$calculated_paid_amount = $invoice->amount - $invoice->balance - $total_credit;
|
||||
|
||||
if ((string) $total_paid != (string) ($invoice->amount - $invoice->balance - $total_credit)) {
|
||||
if ((string)$total_paid != (string)($invoice->amount - $invoice->balance - $total_credit)) {
|
||||
$this->wrong_balances++;
|
||||
|
||||
$this->logMessage($client->present()->name.' - '.$client->id." - Total Paid = {$total_paid} != Calculated Total = {$calculated_paid_amount}");
|
||||
@ -570,6 +593,7 @@ class CheckData extends Command
|
||||
$this->isValid = false;
|
||||
}
|
||||
});
|
||||
|
||||
});
|
||||
|
||||
$this->logMessage("{$this->wrong_balances} clients with incorrect invoice balances");
|
||||
@ -577,7 +601,7 @@ class CheckData extends Command
|
||||
|
||||
private function clientBalanceQuery()
|
||||
{
|
||||
$results = \DB::select(\DB::raw('
|
||||
$results = \DB::select( \DB::raw("
|
||||
SELECT
|
||||
SUM(invoices.balance) as invoice_balance,
|
||||
clients.id as client_id,
|
||||
@ -591,8 +615,8 @@ class CheckData extends Command
|
||||
GROUP BY clients.id
|
||||
HAVING invoice_balance != clients.balance
|
||||
ORDER BY clients.id;
|
||||
'));
|
||||
|
||||
") );
|
||||
|
||||
return $results;
|
||||
}
|
||||
|
||||
@ -603,32 +627,70 @@ class CheckData extends Command
|
||||
|
||||
$clients = $this->clientBalanceQuery();
|
||||
|
||||
foreach ($clients as $client) {
|
||||
$client = (array) $client;
|
||||
|
||||
foreach($clients as $client)
|
||||
{
|
||||
$client = (array)$client;
|
||||
|
||||
if ((string) $client['invoice_balance'] != (string) $client['client_balance']) {
|
||||
$this->wrong_paid_to_dates++;
|
||||
|
||||
$client_object = Client::withTrashed()->find($client['client_id']);
|
||||
|
||||
$this->logMessage($client_object->present()->name.' - '.$client_object->id.' - calculated client balances do not match Invoice Balances = '.$client['invoice_balance'].' - Client Balance = '.rtrim($client['client_balance'], '0'));
|
||||
|
||||
if ($this->option('client_balance')) {
|
||||
$this->logMessage("# {$client_object->id} ".$client_object->present()->name.' - '.$client_object->number." Fixing {$client_object->balance} to ".$client['invoice_balance']);
|
||||
$this->logMessage($client_object->present()->name.' - '.$client_object->id." - calculated client balances do not match Invoice Balances = ". $client['invoice_balance'] ." - Client Balance = ".rtrim($client['client_balance'], '0'));
|
||||
|
||||
if($this->option('client_balance')){
|
||||
|
||||
$this->logMessage("# {$client_object->id} " . $client_object->present()->name.' - '.$client_object->number." Fixing {$client_object->balance} to " . $client['invoice_balance']);
|
||||
$client_object->balance = $client['invoice_balance'];
|
||||
$client_object->save();
|
||||
|
||||
}
|
||||
|
||||
$this->isValid = false;
|
||||
$this->isValid = false;
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
$this->logMessage("{$this->wrong_paid_to_dates} clients with incorrect client balances");
|
||||
}
|
||||
|
||||
private function checkClientBalanceEdgeCases()
|
||||
{
|
||||
Client::query()
|
||||
->where('is_deleted',false)
|
||||
->where('balance', '!=', 0)
|
||||
->cursor()
|
||||
->each(function ($client){
|
||||
|
||||
$count = Invoice::withTrashed()
|
||||
->where('client_id', $client->id)
|
||||
->where('is_deleted',false)
|
||||
->whereIn('status_id', [2,3])
|
||||
->count();
|
||||
|
||||
if($count == 0){
|
||||
$this->logMessage("# {$client->id} # {$client->name} {$client->balance} is invalid should be 0");
|
||||
|
||||
if($this->option('client_balance')){
|
||||
|
||||
$this->logMessage("# {$client->id} " . $client->present()->name.' - '.$client->number." Fixing {$client->balance} to 0");
|
||||
|
||||
$client->balance = 0;
|
||||
$client->save();
|
||||
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
|
||||
});
|
||||
|
||||
}
|
||||
|
||||
private function invoiceBalanceQuery()
|
||||
{
|
||||
$results = \DB::select(\DB::raw('
|
||||
$results = \DB::select( \DB::raw("
|
||||
SELECT
|
||||
clients.id,
|
||||
clients.balance,
|
||||
@ -642,8 +704,8 @@ class CheckData extends Command
|
||||
GROUP BY clients.id
|
||||
HAVING(invoices_balance != clients.balance)
|
||||
ORDER BY clients.id;
|
||||
'));
|
||||
|
||||
") );
|
||||
|
||||
return $results;
|
||||
}
|
||||
|
||||
@ -654,10 +716,11 @@ class CheckData extends Command
|
||||
|
||||
$_clients = $this->invoiceBalanceQuery();
|
||||
|
||||
foreach ($_clients as $_client) {
|
||||
foreach($_clients as $_client)
|
||||
{
|
||||
$client = Client::withTrashed()->find($_client->id);
|
||||
|
||||
$invoice_balance = $client->invoices()->where('is_deleted', false)->whereIn('status_id', [2, 3])->sum('balance');
|
||||
$invoice_balance = $client->invoices()->where('is_deleted', false)->whereIn('status_id', [2,3])->sum('balance');
|
||||
|
||||
$ledger = CompanyLedger::where('client_id', $client->id)->orderBy('id', 'DESC')->first();
|
||||
|
||||
@ -665,26 +728,31 @@ class CheckData extends Command
|
||||
$this->wrong_balances++;
|
||||
$ledger_balance = $ledger ? $ledger->balance : 0;
|
||||
|
||||
$this->logMessage("# {$client->id} ".$client->present()->name.' - '.$client->number." - Balance Failure - Invoice Balances = {$invoice_balance} Client Balance = {$client->balance} Ledger Balance = {$ledger_balance}");
|
||||
$this->logMessage("# {$client->id} " . $client->present()->name.' - '.$client->number." - Balance Failure - Invoice Balances = {$invoice_balance} Client Balance = {$client->balance} Ledger Balance = {$ledger_balance}");
|
||||
|
||||
$this->isValid = false;
|
||||
|
||||
if ($this->option('client_balance')) {
|
||||
$this->logMessage("# {$client->id} ".$client->present()->name.' - '.$client->number." Fixing {$client->balance} to {$invoice_balance}");
|
||||
if($this->option('client_balance')){
|
||||
|
||||
$this->logMessage("# {$client->id} " . $client->present()->name.' - '.$client->number." Fixing {$client->balance} to {$invoice_balance}");
|
||||
$client->balance = $invoice_balance;
|
||||
$client->save();
|
||||
|
||||
}
|
||||
|
||||
if ($ledger && (number_format($invoice_balance, 4) != number_format($ledger->balance, 4))) {
|
||||
if($ledger && (number_format($invoice_balance, 4) != number_format($ledger->balance, 4)))
|
||||
{
|
||||
$ledger->adjustment = $invoice_balance;
|
||||
$ledger->balance = $invoice_balance;
|
||||
$ledger->notes = 'Ledger Adjustment';
|
||||
$ledger->save();
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
$this->logMessage("{$this->wrong_balances} clients with incorrect balances");
|
||||
|
||||
}
|
||||
|
||||
private function checkLedgerBalances()
|
||||
@ -693,17 +761,19 @@ class CheckData extends Command
|
||||
$this->wrong_paid_to_dates = 0;
|
||||
|
||||
foreach (Client::where('is_deleted', 0)->where('clients.updated_at', '>', now()->subDays(2))->cursor() as $client) {
|
||||
$invoice_balance = $client->invoices()->where('is_deleted', false)->whereIn('status_id', [2, 3])->sum('balance');
|
||||
$invoice_balance = $client->invoices()->where('is_deleted', false)->whereIn('status_id', [2,3])->sum('balance');
|
||||
$ledger = CompanyLedger::where('client_id', $client->id)->orderBy('id', 'DESC')->first();
|
||||
|
||||
if ($ledger && number_format($ledger->balance, 4) != number_format($client->balance, 4)) {
|
||||
$this->wrong_balances++;
|
||||
$this->logMessage("# {$client->id} ".$client->present()->name.' - '.$client->number." - Balance Failure - Client Balance = {$client->balance} Ledger Balance = {$ledger->balance}");
|
||||
$this->logMessage("# {$client->id} " . $client->present()->name.' - '.$client->number." - Balance Failure - Client Balance = {$client->balance} Ledger Balance = {$ledger->balance}");
|
||||
|
||||
$this->isValid = false;
|
||||
|
||||
if ($this->option('ledger_balance')) {
|
||||
$this->logMessage("# {$client->id} ".$client->present()->name.' - '.$client->number." Fixing {$client->balance} to {$invoice_balance}");
|
||||
|
||||
if($this->option('ledger_balance')){
|
||||
|
||||
$this->logMessage("# {$client->id} " . $client->present()->name.' - '.$client->number." Fixing {$client->balance} to {$invoice_balance}");
|
||||
$client->balance = $invoice_balance;
|
||||
$client->save();
|
||||
|
||||
@ -712,6 +782,7 @@ class CheckData extends Command
|
||||
$ledger->notes = 'Ledger Adjustment';
|
||||
$ledger->save();
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
@ -803,20 +874,22 @@ class CheckData extends Command
|
||||
|
||||
public function checkAccountStatuses()
|
||||
{
|
||||
Account::where('plan_expires', '<=', now()->subDays(2))->cursor()->each(function ($account) {
|
||||
$client = Client::on('db-ninja-01')->where('company_id', config('ninja.ninja_default_company_id'))->where('custom_value2', $account->key)->first();
|
||||
Account::where('plan_expires', '<=', now()->subDays(2))->cursor()->each(function ($account){
|
||||
|
||||
if ($client) {
|
||||
$client = Client::on('db-ninja-01')->where('company_id', config('ninja.ninja_default_company_id'))->where('custom_value2', $account->key)->first();
|
||||
|
||||
if($client){
|
||||
$payment = Payment::on('db-ninja-01')
|
||||
->where('company_id', config('ninja.ninja_default_company_id'))
|
||||
->where('client_id', $client->id)
|
||||
->where('date', '>=', now()->subDays(2))
|
||||
->exists();
|
||||
|
||||
if ($payment) {
|
||||
|
||||
if($payment)
|
||||
$this->logMessage("I found a payment for {$account->key}");
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
});
|
||||
}
|
||||
|
||||
@ -824,21 +897,24 @@ class CheckData extends Command
|
||||
{
|
||||
$this->wrong_paid_status = 0;
|
||||
|
||||
foreach (Invoice::with(['payments'])->whereHas('payments')->where('status_id', 4)->where('balance', '>', 0)->where('is_deleted', 0)->cursor() as $invoice) {
|
||||
foreach(Invoice::with(['payments'])->whereHas('payments')->where('status_id', 4)->where('balance', '>', 0)->where('is_deleted',0)->cursor() as $invoice)
|
||||
{
|
||||
$this->wrong_paid_status++;
|
||||
|
||||
$this->logMessage("# {$invoice->id} " . ' - '.$invoice->number." - Marked as paid, but balance = {$invoice->balance}");
|
||||
|
||||
$this->logMessage("# {$invoice->id} ".' - '.$invoice->number." - Marked as paid, but balance = {$invoice->balance}");
|
||||
if($this->option('balance_status')){
|
||||
|
||||
if ($this->option('balance_status')) {
|
||||
$val = $invoice->balance;
|
||||
|
||||
$invoice->balance = 0;
|
||||
$invoice->paid_to_date = $val;
|
||||
$invoice->paid_to_date=$val;
|
||||
$invoice->save();
|
||||
|
||||
$p = $invoice->payments->first();
|
||||
|
||||
if ($p && (int) $p->amount == 0) {
|
||||
if($p && (int)$p->amount == 0)
|
||||
{
|
||||
$p->amount = $val;
|
||||
$p->applied = $val;
|
||||
$p->save();
|
||||
@ -848,10 +924,14 @@ class CheckData extends Command
|
||||
$pivot->save();
|
||||
}
|
||||
|
||||
|
||||
$this->logMessage("Fixing {$invoice->id} settings payment to {$val}");
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
$this->logMessage($this->wrong_paid_status.' wrong invoices with bad balance state');
|
||||
$this->logMessage($this->wrong_paid_status." wrong invoices with bad balance state");
|
||||
|
||||
}
|
||||
}
|
||||
}
|
@ -57,9 +57,9 @@ use stdClass;
|
||||
class CreateSingleAccount extends Command
|
||||
{
|
||||
use MakesHash, GeneratesCounter;
|
||||
|
||||
|
||||
protected $description = 'Create Single Sample Account';
|
||||
|
||||
|
||||
protected $signature = 'ninja:create-single-account {gateway=all} {--database=db-ninja-01}';
|
||||
|
||||
protected $invoice_repo;
|
||||
@ -75,13 +75,12 @@ class CreateSingleAccount extends Command
|
||||
*/
|
||||
public function handle()
|
||||
{
|
||||
if (config('ninja.is_docker')) {
|
||||
return;
|
||||
}
|
||||
|
||||
if (! $this->confirm('Are you sure you want to inject dummy data?')) {
|
||||
if(config('ninja.is_docker'))
|
||||
return;
|
||||
|
||||
if (!$this->confirm('Are you sure you want to inject dummy data?'))
|
||||
return;
|
||||
}
|
||||
|
||||
$this->invoice_repo = new InvoiceRepository();
|
||||
|
||||
@ -106,10 +105,10 @@ class CreateSingleAccount extends Command
|
||||
$company = Company::factory()->create([
|
||||
'account_id' => $account->id,
|
||||
'slack_webhook_url' => config('ninja.notification.slack'),
|
||||
'default_password_timeout' => 30 * 60000,
|
||||
'default_password_timeout' => 30*60000,
|
||||
'portal_mode' => 'domain',
|
||||
'portal_domain' => 'http://ninja.test:8000',
|
||||
'track_inventory' => true,
|
||||
'track_inventory' => true
|
||||
]);
|
||||
|
||||
$settings = $company->settings;
|
||||
@ -154,31 +153,33 @@ class CreateSingleAccount extends Command
|
||||
]);
|
||||
|
||||
Product::factory()->count(1)->create([
|
||||
'user_id' => $user->id,
|
||||
'company_id' => $company->id,
|
||||
]);
|
||||
'user_id' => $user->id,
|
||||
'company_id' => $company->id,
|
||||
]);
|
||||
|
||||
|
||||
TaxRate::factory()->create([
|
||||
'user_id' => $user->id,
|
||||
'company_id' => $company->id,
|
||||
'name' => 'GST',
|
||||
'rate' => 10,
|
||||
'rate' => 10
|
||||
]);
|
||||
|
||||
TaxRate::factory()->create([
|
||||
'user_id' => $user->id,
|
||||
'company_id' => $company->id,
|
||||
'name' => 'VAT',
|
||||
'rate' => 17.5,
|
||||
'rate' => 17.5
|
||||
]);
|
||||
|
||||
TaxRate::factory()->create([
|
||||
'user_id' => $user->id,
|
||||
'company_id' => $company->id,
|
||||
'name' => 'CA Sales Tax',
|
||||
'rate' => 5,
|
||||
'rate' => 5
|
||||
]);
|
||||
|
||||
|
||||
$this->info('Creating '.$this->count.' clients');
|
||||
|
||||
for ($x = 0; $x < $this->count; $x++) {
|
||||
@ -188,7 +189,7 @@ class CreateSingleAccount extends Command
|
||||
$this->createClient($company, $user);
|
||||
}
|
||||
|
||||
CreateCompanyTaskStatuses::dispatchSync($company, $user);
|
||||
CreateCompanyTaskStatuses::dispatchNow($company, $user);
|
||||
|
||||
for ($x = 0; $x < $this->count; $x++) {
|
||||
$client = $company->clients->random();
|
||||
@ -226,18 +227,18 @@ class CreateSingleAccount extends Command
|
||||
|
||||
$client = $company->clients->random();
|
||||
|
||||
$this->info('creating task for client #'.$client->id);
|
||||
$this->info('creating task for client #' . $client->id);
|
||||
$this->createTask($client);
|
||||
|
||||
$client = $company->clients->random();
|
||||
|
||||
$this->info('creating project for client #'.$client->id);
|
||||
$this->info('creating project for client #' . $client->id);
|
||||
$this->createProject($client);
|
||||
|
||||
$this->info('creating credit for client #'.$client->id);
|
||||
$this->info('creating credit for client #' . $client->id);
|
||||
$this->createCredit($client);
|
||||
|
||||
$this->info('creating recurring invoice for client # '.$client->id);
|
||||
$this->info('creating recurring invoice for client # ' . $client->id);
|
||||
$this->createRecurringInvoice($client);
|
||||
}
|
||||
|
||||
@ -249,7 +250,7 @@ class CreateSingleAccount extends Command
|
||||
private function createSubsData($company, $user)
|
||||
{
|
||||
$gs = GroupSettingFactory::create($company->id, $user->id);
|
||||
$gs->name = 'plans';
|
||||
$gs->name = "plans";
|
||||
$gs->save();
|
||||
|
||||
$p1 = Product::factory()->create([
|
||||
@ -289,7 +290,7 @@ class CreateSingleAccount extends Command
|
||||
];
|
||||
|
||||
$sub = SubscriptionFactory::create($company->id, $user->id);
|
||||
$sub->name = 'Pro Plan';
|
||||
$sub->name = "Pro Plan";
|
||||
$sub->group_id = $gs->id;
|
||||
$sub->recurring_product_ids = "{$p1->hashed_id}";
|
||||
$sub->webhook_configuration = $webhook_config;
|
||||
@ -298,7 +299,7 @@ class CreateSingleAccount extends Command
|
||||
$sub->save();
|
||||
|
||||
$sub = SubscriptionFactory::create($company->id, $user->id);
|
||||
$sub->name = 'Enterprise Plan';
|
||||
$sub->name = "Enterprise Plan";
|
||||
$sub->group_id = $gs->id;
|
||||
$sub->recurring_product_ids = "{$p2->hashed_id}";
|
||||
$sub->webhook_configuration = $webhook_config;
|
||||
@ -307,7 +308,7 @@ class CreateSingleAccount extends Command
|
||||
$sub->save();
|
||||
|
||||
$sub = SubscriptionFactory::create($company->id, $user->id);
|
||||
$sub->name = 'Free Plan';
|
||||
$sub->name = "Free Plan";
|
||||
$sub->group_id = $gs->id;
|
||||
$sub->recurring_product_ids = "{$p3->hashed_id}";
|
||||
$sub->webhook_configuration = $webhook_config;
|
||||
@ -323,28 +324,28 @@ class CreateSingleAccount extends Command
|
||||
|
||||
// });
|
||||
$client = Client::factory()->create([
|
||||
'user_id' => $user->id,
|
||||
'company_id' => $company->id,
|
||||
]);
|
||||
'user_id' => $user->id,
|
||||
'company_id' => $company->id,
|
||||
]);
|
||||
|
||||
ClientContact::factory()->create([
|
||||
'user_id' => $user->id,
|
||||
'client_id' => $client->id,
|
||||
'company_id' => $company->id,
|
||||
'is_primary' => 1,
|
||||
'email' => 'user@example.com',
|
||||
]);
|
||||
'user_id' => $user->id,
|
||||
'client_id' => $client->id,
|
||||
'company_id' => $company->id,
|
||||
'is_primary' => 1,
|
||||
'email' => 'user@example.com'
|
||||
]);
|
||||
|
||||
ClientContact::factory()->count(rand(1, 2))->create([
|
||||
'user_id' => $user->id,
|
||||
'client_id' => $client->id,
|
||||
'company_id' => $company->id,
|
||||
]);
|
||||
'user_id' => $user->id,
|
||||
'client_id' => $client->id,
|
||||
'company_id' => $company->id,
|
||||
]);
|
||||
|
||||
$client->number = $this->getNextClientNumber($client);
|
||||
|
||||
$settings = $client->settings;
|
||||
$settings->currency_id = '1';
|
||||
$settings->currency_id = "1";
|
||||
// $settings->use_credits_payment = "always";
|
||||
|
||||
$client->settings = $settings;
|
||||
@ -358,48 +359,49 @@ class CreateSingleAccount extends Command
|
||||
private function createExpense($client)
|
||||
{
|
||||
Expense::factory()->count(rand(1, 2))->create([
|
||||
'user_id' => $client->user->id,
|
||||
'client_id' => $client->id,
|
||||
'company_id' => $client->company->id,
|
||||
]);
|
||||
'user_id' => $client->user->id,
|
||||
'client_id' => $client->id,
|
||||
'company_id' => $client->company->id,
|
||||
]);
|
||||
}
|
||||
|
||||
private function createVendor($client)
|
||||
{
|
||||
$vendor = Vendor::factory()->create([
|
||||
'user_id' => $client->user->id,
|
||||
'company_id' => $client->company->id,
|
||||
]);
|
||||
'user_id' => $client->user->id,
|
||||
'company_id' => $client->company->id,
|
||||
]);
|
||||
|
||||
VendorContact::factory()->create([
|
||||
'user_id' => $client->user->id,
|
||||
'vendor_id' => $vendor->id,
|
||||
'company_id' => $client->company->id,
|
||||
'is_primary' => 1,
|
||||
]);
|
||||
'user_id' => $client->user->id,
|
||||
'vendor_id' => $vendor->id,
|
||||
'company_id' => $client->company->id,
|
||||
'is_primary' => 1,
|
||||
]);
|
||||
|
||||
VendorContact::factory()->count(rand(1, 2))->create([
|
||||
'user_id' => $client->user->id,
|
||||
'vendor_id' => $vendor->id,
|
||||
'company_id' => $client->company->id,
|
||||
'is_primary' => 0,
|
||||
]);
|
||||
'user_id' => $client->user->id,
|
||||
'vendor_id' => $vendor->id,
|
||||
'company_id' => $client->company->id,
|
||||
'is_primary' => 0,
|
||||
]);
|
||||
}
|
||||
|
||||
private function createTask($client)
|
||||
{
|
||||
$vendor = Task::factory()->create([
|
||||
'user_id' => $client->user->id,
|
||||
'company_id' => $client->company->id,
|
||||
]);
|
||||
'user_id' => $client->user->id,
|
||||
'company_id' => $client->company->id,
|
||||
]);
|
||||
}
|
||||
|
||||
private function createProject($client)
|
||||
{
|
||||
$vendor = Project::factory()->create([
|
||||
'user_id' => $client->user->id,
|
||||
'company_id' => $client->company->id,
|
||||
]);
|
||||
'user_id' => $client->user->id,
|
||||
'company_id' => $client->company->id,
|
||||
'client_id' => $client->id,
|
||||
]);
|
||||
}
|
||||
|
||||
private function createInvoice($client)
|
||||
@ -429,7 +431,7 @@ class CreateSingleAccount extends Command
|
||||
$invoice->tax_rate3 = 5;
|
||||
}
|
||||
|
||||
$invoice->custom_value1 = $faker->date();
|
||||
$invoice->custom_value1 = $faker->date;
|
||||
$invoice->custom_value2 = rand(0, 1) ? 'yes' : 'no';
|
||||
|
||||
$invoice->save();
|
||||
@ -516,6 +518,7 @@ class CreateSingleAccount extends Command
|
||||
$quote->service()->createInvitations();
|
||||
}
|
||||
|
||||
|
||||
private function buildCreditItem()
|
||||
{
|
||||
$line_items = [];
|
||||
@ -536,9 +539,11 @@ class CreateSingleAccount extends Command
|
||||
|
||||
$line_items[] = $item;
|
||||
|
||||
|
||||
return $line_items;
|
||||
}
|
||||
|
||||
|
||||
private function buildLineItems($count = 1)
|
||||
{
|
||||
$line_items = [];
|
||||
@ -610,6 +615,7 @@ class CreateSingleAccount extends Command
|
||||
private function createGateways($company, $user)
|
||||
{
|
||||
if (config('ninja.testvars.stripe') && ($this->gateway == 'all' || $this->gateway == 'stripe')) {
|
||||
|
||||
$cg = new CompanyGateway;
|
||||
$cg->company_id = $company->id;
|
||||
$cg->user_id = $user->id;
|
||||
@ -628,6 +634,8 @@ class CreateSingleAccount extends Command
|
||||
|
||||
$cg->fees_and_limits = $fees_and_limits;
|
||||
$cg->save();
|
||||
|
||||
|
||||
}
|
||||
|
||||
if (config('ninja.testvars.paypal') && ($this->gateway == 'all' || $this->gateway == 'paypal')) {
|
||||
@ -735,6 +743,7 @@ class CreateSingleAccount extends Command
|
||||
$cg->save();
|
||||
}
|
||||
|
||||
|
||||
if (config('ninja.testvars.paytrace.decrypted') && ($this->gateway == 'all' || $this->gateway == 'paytrace')) {
|
||||
$cg = new CompanyGateway;
|
||||
$cg->company_id = $company->id;
|
||||
@ -748,6 +757,7 @@ class CreateSingleAccount extends Command
|
||||
|
||||
$cg->save();
|
||||
|
||||
|
||||
$gateway_types = $cg->driver()->gatewayTypes();
|
||||
|
||||
$fees_and_limits = new stdClass;
|
||||
@ -827,7 +837,7 @@ class CreateSingleAccount extends Command
|
||||
$invoice->tax_rate3 = 5;
|
||||
}
|
||||
|
||||
$invoice->custom_value1 = $faker->date();
|
||||
$invoice->custom_value1 = $faker->date;
|
||||
$invoice->custom_value2 = rand(0, 1) ? 'yes' : 'no';
|
||||
|
||||
$invoice->status_id = RecurringInvoice::STATUS_ACTIVE;
|
||||
|
@ -97,8 +97,20 @@ class PaymentController extends Controller
|
||||
$client = $invoice ? $invoice->client : auth()->guard('contact')->user()->client;
|
||||
|
||||
// 09-07-2022 catch duplicate responses for invoices that already paid here.
|
||||
if($invoice && $invoice->status_id == Invoice::STATUS_PAID)
|
||||
abort(400, 'Invoice paid. Duplicate submission');
|
||||
if($invoice && $invoice->status_id == Invoice::STATUS_PAID){
|
||||
|
||||
$data = [
|
||||
'invoice' => $invoice,
|
||||
'key' => false
|
||||
];
|
||||
|
||||
if ($request->query('mode') === 'fullscreen') {
|
||||
return render('invoices.show-fullscreen', $data);
|
||||
}
|
||||
|
||||
return $this->render('invoices.show', $data);
|
||||
|
||||
}
|
||||
|
||||
return $gateway
|
||||
->driver($client)
|
||||
|
@ -63,9 +63,6 @@ class UpdateInvoiceRequest extends Request
|
||||
$rules['discount'] = 'sometimes|numeric';
|
||||
$rules['project_id'] = ['bail', 'sometimes', new ValidProjectForClient($this->all())];
|
||||
|
||||
// if($this->input('status_id') != Invoice::STATUS_DRAFT)
|
||||
// $rules['balance'] = new InvoiceBalanceSanity($this->invoice, $this->all());
|
||||
|
||||
return $rules;
|
||||
}
|
||||
|
||||
|
@ -129,7 +129,7 @@ class Request extends FormRequest
|
||||
}
|
||||
}
|
||||
|
||||
if (isset($input['invitations'])) {
|
||||
if (isset($input['invitations']) && is_array($input['invitations'])) {
|
||||
foreach ($input['invitations'] as $key => $value) {
|
||||
if (isset($input['invitations'][$key]['id']) && is_numeric($input['invitations'][$key]['id'])) {
|
||||
unset($input['invitations'][$key]['id']);
|
||||
|
@ -20,6 +20,7 @@ use App\Mail\DownloadInvoices;
|
||||
use App\Models\Company;
|
||||
use App\Models\CreditInvitation;
|
||||
use App\Models\InvoiceInvitation;
|
||||
use App\Models\PurchaseOrderInvitation;
|
||||
use App\Models\QuoteInvitation;
|
||||
use App\Models\RecurringInvoice;
|
||||
use App\Models\RecurringInvoiceInvitation;
|
||||
@ -68,6 +69,7 @@ class CompanyExport implements ShouldQueue
|
||||
*/
|
||||
public function handle()
|
||||
{
|
||||
|
||||
MultiDB::setDb($this->company->db);
|
||||
|
||||
$this->company = Company::where('company_key', $this->company->company_key)->first();
|
||||
@ -76,7 +78,8 @@ class CompanyExport implements ShouldQueue
|
||||
|
||||
$this->export_data['app_version'] = config('ninja.app_version');
|
||||
|
||||
$this->export_data['activities'] = $this->company->all_activities->map(function ($activity) {
|
||||
$this->export_data['activities'] = $this->company->all_activities->map(function ($activity){
|
||||
|
||||
$activity = $this->transformArrayOfKeys($activity, [
|
||||
'user_id',
|
||||
'company_id',
|
||||
@ -94,10 +97,11 @@ class CompanyExport implements ShouldQueue
|
||||
'token_id',
|
||||
'quote_id',
|
||||
'subscription_id',
|
||||
'recurring_invoice_id',
|
||||
'recurring_invoice_id'
|
||||
]);
|
||||
|
||||
return $activity;
|
||||
|
||||
})->makeHidden(['id'])->all();
|
||||
|
||||
// $this->export_data['backups'] = $this->company->all_activities()->with('backup')->cursor()->map(function ($activity){
|
||||
@ -113,276 +117,387 @@ class CompanyExport implements ShouldQueue
|
||||
|
||||
// })->all();
|
||||
|
||||
$this->export_data['users'] = $this->company->users()->withTrashed()->cursor()->map(function ($user) {
|
||||
$this->export_data['users'] = $this->company->users()->withTrashed()->cursor()->map(function ($user){
|
||||
|
||||
$user->account_id = $this->encodePrimaryKey($user->account_id);
|
||||
// $user->id = $this->encodePrimaryKey($user->id);
|
||||
|
||||
return $user->makeVisible(['id']);
|
||||
|
||||
})->all();
|
||||
|
||||
$this->export_data['client_contacts'] = $this->company->client_contacts->map(function ($client_contact) {
|
||||
|
||||
$this->export_data['client_contacts'] = $this->company->client_contacts->map(function ($client_contact){
|
||||
|
||||
$client_contact = $this->transformArrayOfKeys($client_contact, ['company_id', 'user_id', 'client_id']);
|
||||
|
||||
return $client_contact->makeVisible([
|
||||
'password',
|
||||
'remember_token',
|
||||
'user_id',
|
||||
'company_id',
|
||||
'client_id',
|
||||
'google_2fa_secret',
|
||||
'id',
|
||||
'oauth_provider_id',
|
||||
'oauth_user_id',
|
||||
'token',
|
||||
'hashed_id',
|
||||
]);
|
||||
return $client_contact->makeVisible([
|
||||
'password',
|
||||
'remember_token',
|
||||
'user_id',
|
||||
'company_id',
|
||||
'client_id',
|
||||
'google_2fa_secret',
|
||||
'id',
|
||||
'oauth_provider_id',
|
||||
'oauth_user_id',
|
||||
'token',
|
||||
'hashed_id',
|
||||
]);
|
||||
|
||||
})->all();
|
||||
|
||||
$this->export_data['client_gateway_tokens'] = $this->company->client_gateway_tokens->map(function ($client_gateway_token) {
|
||||
|
||||
$this->export_data['client_gateway_tokens'] = $this->company->client_gateway_tokens->map(function ($client_gateway_token){
|
||||
|
||||
$client_gateway_token = $this->transformArrayOfKeys($client_gateway_token, ['company_id', 'client_id', 'company_gateway_id']);
|
||||
|
||||
return $client_gateway_token->makeVisible(['id']);
|
||||
|
||||
})->all();
|
||||
|
||||
$this->export_data['clients'] = $this->company->clients()->orderBy('number', 'DESC')->cursor()->map(function ($client) {
|
||||
|
||||
$this->export_data['clients'] = $this->company->clients()->orderBy('number', 'DESC')->cursor()->map(function ($client){
|
||||
|
||||
$client = $this->transformArrayOfKeys($client, ['company_id', 'user_id', 'assigned_user_id', 'group_settings_id']);
|
||||
|
||||
return $client->makeVisible(['id', 'private_notes', 'user_id', 'company_id', 'last_login', 'hashed_id']);
|
||||
return $client->makeVisible(['id','private_notes','user_id','company_id','last_login','hashed_id']);
|
||||
|
||||
})->all();
|
||||
|
||||
|
||||
$this->export_data['company'] = $this->company->toArray();
|
||||
|
||||
$this->export_data['company_gateways'] = $this->company->company_gateways()->withTrashed()->cursor()->map(function ($company_gateway) {
|
||||
$this->export_data['company_gateways'] = $this->company->company_gateways()->withTrashed()->cursor()->map(function ($company_gateway){
|
||||
|
||||
$company_gateway = $this->transformArrayOfKeys($company_gateway, ['company_id', 'user_id']);
|
||||
$company_gateway->config = decrypt($company_gateway->config);
|
||||
|
||||
|
||||
return $company_gateway->makeVisible(['id']);
|
||||
|
||||
})->all();
|
||||
|
||||
$this->export_data['company_tokens'] = $this->company->tokens->map(function ($token) {
|
||||
$this->export_data['company_tokens'] = $this->company->tokens->map(function ($token){
|
||||
|
||||
$token = $this->transformArrayOfKeys($token, ['company_id', 'account_id', 'user_id']);
|
||||
|
||||
return $token;
|
||||
|
||||
})->all();
|
||||
|
||||
$this->export_data['company_ledger'] = $this->company->ledger->map(function ($ledger) {
|
||||
$ledger = $this->transformArrayOfKeys($ledger, ['activity_id', 'client_id', 'company_id', 'account_id', 'user_id', 'company_ledgerable_id']);
|
||||
$this->export_data['company_ledger'] = $this->company->ledger->map(function ($ledger){
|
||||
|
||||
$ledger = $this->transformArrayOfKeys($ledger, ['activity_id', 'client_id', 'company_id', 'account_id', 'user_id','company_ledgerable_id']);
|
||||
|
||||
return $ledger;
|
||||
|
||||
})->all();
|
||||
|
||||
$this->export_data['company_users'] = $this->company->company_users()->without(['user', 'account'])->cursor()->map(function ($company_user) {
|
||||
$this->export_data['company_users'] = $this->company->company_users()->without(['user','account'])->cursor()->map(function ($company_user){
|
||||
|
||||
$company_user = $this->transformArrayOfKeys($company_user, ['company_id', 'account_id', 'user_id']);
|
||||
|
||||
return $company_user;
|
||||
|
||||
})->all();
|
||||
|
||||
$this->export_data['credits'] = $this->company->credits()->orderBy('number', 'DESC')->cursor()->map(function ($credit) {
|
||||
$this->export_data['credits'] = $this->company->credits()->orderBy('number', 'DESC')->cursor()->map(function ($credit){
|
||||
|
||||
$credit = $this->transformBasicEntities($credit);
|
||||
$credit = $this->transformArrayOfKeys($credit, ['recurring_id', 'client_id', 'vendor_id', 'project_id', 'design_id', 'subscription_id', 'invoice_id']);
|
||||
$credit = $this->transformArrayOfKeys($credit, ['recurring_id','client_id', 'vendor_id', 'project_id', 'design_id', 'subscription_id','invoice_id']);
|
||||
|
||||
return $credit->makeVisible(['id']);
|
||||
|
||||
})->all();
|
||||
|
||||
$this->export_data['credit_invitations'] = CreditInvitation::where('company_id', $this->company->id)->withTrashed()->cursor()->map(function ($credit) {
|
||||
|
||||
$this->export_data['credit_invitations'] = CreditInvitation::where('company_id', $this->company->id)->withTrashed()->cursor()->map(function ($credit){
|
||||
|
||||
$credit = $this->transformArrayOfKeys($credit, ['company_id', 'user_id', 'client_contact_id', 'credit_id']);
|
||||
|
||||
return $credit->makeVisible(['id']);
|
||||
|
||||
})->all();
|
||||
|
||||
$this->export_data['designs'] = $this->company->user_designs->makeHidden(['id'])->all();
|
||||
|
||||
$this->export_data['documents'] = $this->company->all_documents->map(function ($document) {
|
||||
$document = $this->transformArrayOfKeys($document, ['user_id', 'assigned_user_id', 'company_id', 'project_id', 'vendor_id', 'documentable_id']);
|
||||
$this->export_data['documents'] = $this->company->all_documents->map(function ($document){
|
||||
|
||||
$document = $this->transformArrayOfKeys($document, ['user_id', 'assigned_user_id', 'company_id', 'project_id', 'vendor_id','documentable_id']);
|
||||
$document->hashed_id = $this->encodePrimaryKey($document->id);
|
||||
|
||||
return $document->makeVisible(['id']);
|
||||
|
||||
})->all();
|
||||
|
||||
$this->export_data['expense_categories'] = $this->company->expense_categories->map(function ($expense_category) {
|
||||
$this->export_data['expense_categories'] = $this->company->expense_categories->map(function ($expense_category){
|
||||
|
||||
$expense_category = $this->transformArrayOfKeys($expense_category, ['user_id', 'company_id']);
|
||||
|
||||
|
||||
return $expense_category->makeVisible(['id']);
|
||||
|
||||
})->all();
|
||||
|
||||
$this->export_data['expenses'] = $this->company->expenses()->orderBy('number', 'DESC')->cursor()->map(function ($expense) {
|
||||
|
||||
$this->export_data['expenses'] = $this->company->expenses()->orderBy('number', 'DESC')->cursor()->map(function ($expense){
|
||||
|
||||
$expense = $this->transformBasicEntities($expense);
|
||||
$expense = $this->transformArrayOfKeys($expense, ['vendor_id', 'invoice_id', 'client_id', 'category_id', 'recurring_expense_id', 'project_id']);
|
||||
$expense = $this->transformArrayOfKeys($expense, ['vendor_id', 'invoice_id', 'client_id', 'category_id', 'recurring_expense_id','project_id']);
|
||||
|
||||
return $expense->makeVisible(['id']);
|
||||
|
||||
})->all();
|
||||
|
||||
$this->export_data['group_settings'] = $this->company->group_settings->map(function ($gs) {
|
||||
$this->export_data['group_settings'] = $this->company->group_settings->map(function ($gs){
|
||||
|
||||
$gs = $this->transformArrayOfKeys($gs, ['user_id', 'company_id']);
|
||||
|
||||
return $gs->makeVisible(['id']);
|
||||
|
||||
})->all();
|
||||
|
||||
$this->export_data['invoices'] = $this->company->invoices()->orderBy('number', 'DESC')->cursor()->map(function ($invoice) {
|
||||
|
||||
$this->export_data['invoices'] = $this->company->invoices()->orderBy('number', 'DESC')->cursor()->map(function ($invoice){
|
||||
|
||||
$invoice = $this->transformBasicEntities($invoice);
|
||||
$invoice = $this->transformArrayOfKeys($invoice, ['recurring_id', 'client_id', 'vendor_id', 'project_id', 'design_id', 'subscription_id', 'project_id']);
|
||||
$invoice = $this->transformArrayOfKeys($invoice, ['recurring_id','client_id', 'vendor_id', 'project_id', 'design_id', 'subscription_id','project_id']);
|
||||
|
||||
return $invoice->makeVisible(['id',
|
||||
'private_notes',
|
||||
'user_id',
|
||||
'client_id',
|
||||
'company_id', ]);
|
||||
'private_notes',
|
||||
'user_id',
|
||||
'client_id',
|
||||
'company_id',]);
|
||||
|
||||
})->all();
|
||||
|
||||
$this->export_data['invoice_invitations'] = InvoiceInvitation::where('company_id', $this->company->id)->withTrashed()->cursor()->map(function ($invoice) {
|
||||
|
||||
$this->export_data['invoice_invitations'] = InvoiceInvitation::where('company_id', $this->company->id)->withTrashed()->cursor()->map(function ($invoice){
|
||||
|
||||
$invoice = $this->transformArrayOfKeys($invoice, ['company_id', 'user_id', 'client_contact_id', 'invoice_id']);
|
||||
|
||||
return $invoice->makeVisible(['id']);
|
||||
|
||||
})->all();
|
||||
|
||||
$this->export_data['payment_terms'] = $this->company->user_payment_terms->map(function ($term) {
|
||||
$this->export_data['payment_terms'] = $this->company->user_payment_terms->map(function ($term){
|
||||
|
||||
$term = $this->transformArrayOfKeys($term, ['user_id', 'company_id']);
|
||||
|
||||
return $term;
|
||||
|
||||
})->makeHidden(['id'])->all();
|
||||
|
||||
$this->export_data['payments'] = $this->company->payments()->orderBy('number', 'DESC')->cursor()->map(function ($payment) {
|
||||
|
||||
$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']);
|
||||
|
||||
$payment->paymentables = $this->transformPaymentable($payment);
|
||||
|
||||
return $payment->makeVisible(['id']);
|
||||
|
||||
})->all();
|
||||
|
||||
$this->export_data['products'] = $this->company->products->map(function ($product) {
|
||||
$this->export_data['products'] = $this->company->products->map(function ($product){
|
||||
|
||||
$product = $this->transformBasicEntities($product);
|
||||
$product = $this->transformArrayOfKeys($product, ['vendor_id', 'project_id']);
|
||||
$product = $this->transformArrayOfKeys($product, ['vendor_id','project_id']);
|
||||
|
||||
return $product->makeVisible(['id']);
|
||||
|
||||
})->all();
|
||||
|
||||
$this->export_data['projects'] = $this->company->projects()->orderBy('number', 'DESC')->cursor()->map(function ($project) {
|
||||
$this->export_data['projects'] = $this->company->projects()->orderBy('number', 'DESC')->cursor()->map(function ($project){
|
||||
|
||||
$project = $this->transformBasicEntities($project);
|
||||
$project = $this->transformArrayOfKeys($project, ['client_id']);
|
||||
|
||||
return $project->makeVisible(['id']);
|
||||
|
||||
})->all();
|
||||
|
||||
$this->export_data['quotes'] = $this->company->quotes()->orderBy('number', 'DESC')->cursor()->map(function ($quote) {
|
||||
$this->export_data['quotes'] = $this->company->quotes()->orderBy('number', 'DESC')->cursor()->map(function ($quote){
|
||||
|
||||
$quote = $this->transformBasicEntities($quote);
|
||||
$quote = $this->transformArrayOfKeys($quote, ['invoice_id', 'recurring_id', 'client_id', 'vendor_id', 'project_id', 'design_id', 'subscription_id']);
|
||||
$quote = $this->transformArrayOfKeys($quote, ['invoice_id','recurring_id','client_id', 'vendor_id', 'project_id', 'design_id', 'subscription_id']);
|
||||
|
||||
return $quote->makeVisible(['id']);
|
||||
|
||||
})->all();
|
||||
|
||||
$this->export_data['quote_invitations'] = QuoteInvitation::where('company_id', $this->company->id)->withTrashed()->cursor()->map(function ($quote) {
|
||||
|
||||
$this->export_data['quote_invitations'] = QuoteInvitation::where('company_id', $this->company->id)->withTrashed()->cursor()->map(function ($quote){
|
||||
|
||||
$quote = $this->transformArrayOfKeys($quote, ['company_id', 'user_id', 'client_contact_id', 'quote_id']);
|
||||
|
||||
return $quote->makeVisible(['id']);
|
||||
|
||||
})->all();
|
||||
|
||||
$this->export_data['recurring_expenses'] = $this->company->recurring_expenses()->orderBy('number', 'DESC')->cursor()->map(function ($expense) {
|
||||
$this->export_data['recurring_expenses'] = $this->company->recurring_expenses()->orderBy('number', 'DESC')->cursor()->map(function ($expense){
|
||||
|
||||
$expense = $this->transformBasicEntities($expense);
|
||||
$expense = $this->transformArrayOfKeys($expense, ['vendor_id', 'invoice_id', 'client_id', 'category_id', 'project_id']);
|
||||
|
||||
return $expense->makeVisible(['id']);
|
||||
|
||||
})->all();
|
||||
|
||||
$this->export_data['recurring_invoices'] = $this->company->recurring_invoices()->orderBy('number', 'DESC')->cursor()->map(function ($ri) {
|
||||
$this->export_data['recurring_invoices'] = $this->company->recurring_invoices()->orderBy('number', 'DESC')->cursor()->map(function ($ri){
|
||||
|
||||
$ri = $this->transformBasicEntities($ri);
|
||||
$ri = $this->transformArrayOfKeys($ri, ['client_id', 'vendor_id', 'project_id', 'design_id', 'subscription_id']);
|
||||
|
||||
|
||||
return $ri->makeVisible(['id']);
|
||||
|
||||
})->all();
|
||||
|
||||
$this->export_data['recurring_invoice_invitations'] = RecurringInvoiceInvitation::where('company_id', $this->company->id)->withTrashed()->cursor()->map(function ($ri) {
|
||||
|
||||
$this->export_data['recurring_invoice_invitations'] = RecurringInvoiceInvitation::where('company_id', $this->company->id)->withTrashed()->cursor()->map(function ($ri){
|
||||
|
||||
$ri = $this->transformArrayOfKeys($ri, ['company_id', 'user_id', 'client_contact_id', 'recurring_invoice_id']);
|
||||
|
||||
return $ri;
|
||||
|
||||
})->all();
|
||||
|
||||
$this->export_data['subscriptions'] = $this->company->subscriptions->map(function ($subscription) {
|
||||
$this->export_data['subscriptions'] = $this->company->subscriptions->map(function ($subscription){
|
||||
|
||||
$subscription = $this->transformBasicEntities($subscription);
|
||||
$subscription->group_id = $this->encodePrimaryKey($subscription->group_id);
|
||||
|
||||
return $subscription->makeVisible(['id',
|
||||
'user_id',
|
||||
'assigned_user_id',
|
||||
'company_id',
|
||||
'product_ids',
|
||||
'recurring_product_ids',
|
||||
'group_id', ]);
|
||||
return $subscription->makeVisible([ 'id',
|
||||
'user_id',
|
||||
'assigned_user_id',
|
||||
'company_id',
|
||||
'product_ids',
|
||||
'recurring_product_ids',
|
||||
'group_id']);
|
||||
|
||||
})->all();
|
||||
|
||||
$this->export_data['system_logs'] = $this->company->system_logs->map(function ($log) {
|
||||
|
||||
$this->export_data['system_logs'] = $this->company->system_logs->map(function ($log){
|
||||
|
||||
$log->client_id = $this->encodePrimaryKey($log->client_id);
|
||||
$log->company_id = $this->encodePrimaryKey($log->company_id);
|
||||
|
||||
return $log;
|
||||
|
||||
})->makeHidden(['id'])->all();
|
||||
|
||||
$this->export_data['tasks'] = $this->company->tasks()->orderBy('number', 'DESC')->cursor()->map(function ($task) {
|
||||
$this->export_data['tasks'] = $this->company->tasks()->orderBy('number', 'DESC')->cursor()->map(function ($task){
|
||||
|
||||
$task = $this->transformBasicEntities($task);
|
||||
$task = $this->transformArrayOfKeys($task, ['client_id', 'invoice_id', 'project_id', 'status_id']);
|
||||
|
||||
return $task->makeVisible(['id']);
|
||||
|
||||
})->all();
|
||||
|
||||
$this->export_data['task_statuses'] = $this->company->task_statuses->map(function ($status) {
|
||||
$this->export_data['task_statuses'] = $this->company->task_statuses->map(function ($status){
|
||||
|
||||
$status->id = $this->encodePrimaryKey($status->id);
|
||||
$status->user_id = $this->encodePrimaryKey($status->user_id);
|
||||
$status->company_id = $this->encodePrimaryKey($status->company_id);
|
||||
|
||||
return $status;
|
||||
|
||||
})->all();
|
||||
|
||||
$this->export_data['tax_rates'] = $this->company->tax_rates->map(function ($rate) {
|
||||
$this->export_data['tax_rates'] = $this->company->tax_rates->map(function ($rate){
|
||||
|
||||
$rate->company_id = $this->encodePrimaryKey($rate->company_id);
|
||||
$rate->user_id = $this->encodePrimaryKey($rate->user_id);
|
||||
|
||||
return $rate;
|
||||
|
||||
})->makeHidden(['id'])->all();
|
||||
|
||||
$this->export_data['vendors'] = $this->company->vendors()->orderBy('number', 'DESC')->cursor()->map(function ($vendor) {
|
||||
$this->export_data['vendors'] = $this->company->vendors()->orderBy('number', 'DESC')->cursor()->map(function ($vendor){
|
||||
|
||||
return $this->transformBasicEntities($vendor)->makeVisible(['id']);
|
||||
|
||||
})->all();
|
||||
|
||||
$this->export_data['vendor_contacts'] = VendorContact::where('company_id', $this->company->id)->withTrashed()->cursor()->map(function ($vendor) {
|
||||
|
||||
$this->export_data['vendor_contacts'] = VendorContact::where('company_id', $this->company->id)->withTrashed()->cursor()->map(function ($vendor){
|
||||
|
||||
$vendor = $this->transformBasicEntities($vendor);
|
||||
$vendor->vendor_id = $this->encodePrimaryKey($vendor->vendor_id);
|
||||
$vendor = $this->transformArrayOfKeys($vendor, ['vendor_id']);
|
||||
|
||||
return $vendor->makeVisible(['id','user_id']);
|
||||
|
||||
return $vendor->makeVisible(['id']);
|
||||
})->all();
|
||||
|
||||
$this->export_data['webhooks'] = $this->company->webhooks->map(function ($hook) {
|
||||
$this->export_data['webhooks'] = $this->company->webhooks->map(function ($hook){
|
||||
|
||||
$hook->user_id = $this->encodePrimaryKey($hook->user_id);
|
||||
$hook->company_id = $this->encodePrimaryKey($hook->company_id);
|
||||
|
||||
return $hook;
|
||||
|
||||
})->makeHidden(['id'])->all();
|
||||
|
||||
$this->export_data['purchase_orders'] = $this->company->purchase_orders()->orderBy('number', 'DESC')->cursor()->map(function ($purchase_order){
|
||||
|
||||
$purchase_order = $this->transformBasicEntities($purchase_order);
|
||||
$purchase_order = $this->transformArrayOfKeys($purchase_order, ['expense_id','client_id', 'vendor_id', 'project_id', 'design_id', 'subscription_id','project_id']);
|
||||
|
||||
return $purchase_order->makeVisible(['id',
|
||||
'private_notes',
|
||||
'user_id',
|
||||
'client_id',
|
||||
'vendor_id',
|
||||
'company_id',]);
|
||||
|
||||
})->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']);
|
||||
|
||||
return $purchase_order->makeVisible(['id']);
|
||||
|
||||
})->all();
|
||||
|
||||
|
||||
|
||||
//write to tmp and email to owner();
|
||||
|
||||
$this->zipAndSend();
|
||||
|
||||
$this->zipAndSend();
|
||||
|
||||
return true;
|
||||
return true;
|
||||
}
|
||||
|
||||
private function transformBasicEntities($model)
|
||||
{
|
||||
|
||||
return $this->transformArrayOfKeys($model, ['user_id', 'assigned_user_id', 'company_id']);
|
||||
|
||||
}
|
||||
|
||||
private function transformArrayOfKeys($model, $keys)
|
||||
{
|
||||
foreach ($keys as $key) {
|
||||
|
||||
foreach($keys as $key){
|
||||
$model->{$key} = $this->encodePrimaryKey($model->{$key});
|
||||
}
|
||||
|
||||
return $model;
|
||||
|
||||
}
|
||||
|
||||
private function transformPaymentable($payment)
|
||||
{
|
||||
|
||||
$new_arr = [];
|
||||
|
||||
foreach ($payment->paymentables as $paymentable) {
|
||||
foreach($payment->paymentables as $paymentable)
|
||||
{
|
||||
|
||||
$paymentable->payment_id = $this->encodePrimaryKey($paymentable->payment_id);
|
||||
$paymentable->paymentable_id = $this->encodePrimaryKey($paymentable->paymentable_id);
|
||||
|
||||
@ -390,29 +505,30 @@ class CompanyExport implements ShouldQueue
|
||||
}
|
||||
|
||||
return $new_arr;
|
||||
|
||||
}
|
||||
|
||||
private function zipAndSend()
|
||||
{
|
||||
$file_name = date('Y-m-d').'_'.str_replace([' ', '/'], ['_', ''], $this->company->present()->name().'_'.$this->company->company_key.'.zip');
|
||||
|
||||
$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)) {
|
||||
|
||||
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();
|
||||
|
||||
if ($zip->open($zip_path, \ZipArchive::CREATE) !== true) {
|
||||
if ($zip->open($zip_path, \ZipArchive::CREATE)!==TRUE) {
|
||||
nlog("cannot open {$zip_path}");
|
||||
}
|
||||
|
||||
$zip->addFromString('backup.json', json_encode($this->export_data));
|
||||
$zip->addFromString("backup.json", json_encode($this->export_data));
|
||||
$zip->close();
|
||||
|
||||
if (Ninja::isHosted()) {
|
||||
if(Ninja::isHosted()) {
|
||||
Storage::disk(config('filesystems.default'))->put('backups/'.$file_name, file_get_contents($zip_path));
|
||||
}
|
||||
|
||||
@ -422,19 +538,20 @@ class CompanyExport implements ShouldQueue
|
||||
$t = app('translator');
|
||||
$t->replace(Ninja::transformTranslations($this->company->settings));
|
||||
|
||||
$company_reference = Company::find($this->company->id);
|
||||
$company_reference = Company::find($this->company->id);;
|
||||
|
||||
$nmo = new NinjaMailerObject;
|
||||
$nmo->mailable = new DownloadBackup($storage_file_path, $company_reference);
|
||||
$nmo->to_user = $this->user;
|
||||
$nmo->company = $company_reference;
|
||||
$nmo->settings = $this->company->settings;
|
||||
|
||||
|
||||
NinjaMailerJob::dispatch($nmo, true);
|
||||
|
||||
if (Ninja::isHosted()) {
|
||||
if(Ninja::isHosted()){
|
||||
sleep(3);
|
||||
unlink($zip_path);
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
@ -45,6 +45,8 @@ use App\Models\PaymentTerm;
|
||||
use App\Models\Paymentable;
|
||||
use App\Models\Product;
|
||||
use App\Models\Project;
|
||||
use App\Models\PurchaseOrder;
|
||||
use App\Models\PurchaseOrderInvitation;
|
||||
use App\Models\Quote;
|
||||
use App\Models\QuoteInvitation;
|
||||
use App\Models\RecurringExpense;
|
||||
@ -74,7 +76,6 @@ use Illuminate\Support\Str;
|
||||
use JsonMachine\JsonDecoder\ExtJsonDecoder;
|
||||
use JsonMachine\JsonMachine;
|
||||
use ZipArchive;
|
||||
|
||||
use function GuzzleHttp\json_encode;
|
||||
|
||||
class CompanyImport implements ShouldQueue
|
||||
@ -122,6 +123,7 @@ class CompanyImport implements ShouldQueue
|
||||
'clients',
|
||||
'client_contacts',
|
||||
'vendors',
|
||||
'vendor_contacts',
|
||||
'projects',
|
||||
'products',
|
||||
'company_gateways',
|
||||
@ -147,6 +149,8 @@ class CompanyImport implements ShouldQueue
|
||||
'documents',
|
||||
'webhooks',
|
||||
'system_logs',
|
||||
'purchase_orders',
|
||||
'purchase_order_invitations'
|
||||
];
|
||||
|
||||
private $company_properties = [
|
||||
@ -454,7 +458,7 @@ class CompanyImport implements ShouldQueue
|
||||
$settings->ticket_number_counter = 1;
|
||||
$settings->payment_number_counter = 1;
|
||||
$settings->project_number_counter = 1;
|
||||
|
||||
$settings->purchase_order_counter = 1;
|
||||
$this->company->settings = $co->settings;
|
||||
// $this->company->settings = $this->backup_file->company->settings;
|
||||
$this->company->save();
|
||||
@ -471,6 +475,7 @@ class CompanyImport implements ShouldQueue
|
||||
$this->company->vendors()->forceDelete();
|
||||
$this->company->expenses()->forceDelete();
|
||||
$this->company->subscriptions()->forceDelete();
|
||||
$this->company->purchase_orders()->forceDelete();
|
||||
|
||||
$this->company->save();
|
||||
|
||||
@ -649,6 +654,19 @@ class CompanyImport implements ShouldQueue
|
||||
return $this;
|
||||
}
|
||||
|
||||
private function import_vendor_contacts()
|
||||
{
|
||||
|
||||
$this->genericImport(VendorContact::class,
|
||||
['user_id', 'company_id', 'id', 'hashed_id','company','assigned_user_id'],
|
||||
[['users' => 'user_id'], ['vendors' => 'vendor_id']],
|
||||
'vendor_contacts',
|
||||
'email');
|
||||
|
||||
return $this;
|
||||
|
||||
}
|
||||
|
||||
private function import_projects()
|
||||
{
|
||||
|
||||
@ -796,6 +814,42 @@ class CompanyImport implements ShouldQueue
|
||||
return $this;
|
||||
}
|
||||
|
||||
private function import_purchase_orders()
|
||||
{
|
||||
|
||||
$this->genericImport(PurchaseOrder::class,
|
||||
['user_id', 'company_id', 'id', 'hashed_id', 'recurring_id','status', 'vendor_id', 'subscription_id','client_id'],
|
||||
[
|
||||
['users' => 'user_id'],
|
||||
['users' => 'assigned_user_id'],
|
||||
['recurring_invoices' => 'recurring_id'],
|
||||
['projects' => 'project_id'],
|
||||
['vendors' => 'vendor_id'],
|
||||
],
|
||||
'purchase_orders',
|
||||
'number');
|
||||
|
||||
return $this;
|
||||
}
|
||||
|
||||
private function import_purchase_order_invitations()
|
||||
{
|
||||
|
||||
|
||||
$this->genericImport(PurchaseOrderInvitation::class,
|
||||
['user_id', 'vendor_contact_id', 'company_id', 'id', 'hashed_id', 'purchase_order_id'],
|
||||
[
|
||||
['users' => 'user_id'],
|
||||
['purchase_orders' => 'purchase_order_id'],
|
||||
['vendor_contacts' => 'vendor_contact_id'],
|
||||
],
|
||||
'purchase_order_invitations',
|
||||
'key');
|
||||
|
||||
return $this;
|
||||
}
|
||||
|
||||
|
||||
private function import_quotes()
|
||||
{
|
||||
|
||||
@ -1425,6 +1479,13 @@ class CompanyImport implements ShouldQueue
|
||||
$new_obj->save(['timestamps' => false]);
|
||||
$new_obj->number = $this->getNextInvoiceNumber($client = Client::withTrashed()->find($obj_array['client_id']),$new_obj);
|
||||
}
|
||||
elseif($class == 'App\Models\PurchaseOrder' && is_null($obj->{$match_key})){
|
||||
$new_obj = new PurchaseOrder();
|
||||
$new_obj->company_id = $this->company->id;
|
||||
$new_obj->fill($obj_array);
|
||||
$new_obj->save(['timestamps' => false]);
|
||||
$new_obj->number = $this->getNextPurchaseOrderNumber($new_obj);
|
||||
}
|
||||
elseif($class == 'App\Models\Payment' && is_null($obj->{$match_key})){
|
||||
$new_obj = new Payment();
|
||||
$new_obj->company_id = $this->company->id;
|
||||
@ -1445,6 +1506,12 @@ class CompanyImport implements ShouldQueue
|
||||
$new_obj->fill($obj_array);
|
||||
$new_obj->save(['timestamps' => false]);
|
||||
}
|
||||
elseif($class == 'App\Models\VendorContact'){
|
||||
$new_obj = new VendorContact();
|
||||
$new_obj->company_id = $this->company->id;
|
||||
$new_obj->fill($obj_array);
|
||||
$new_obj->save(['timestamps' => false]);
|
||||
}
|
||||
elseif($class == 'App\Models\RecurringExpense' && is_null($obj->{$match_key})){
|
||||
$new_obj = new RecurringExpense();
|
||||
$new_obj->company_id = $this->company->id;
|
||||
@ -1466,6 +1533,13 @@ class CompanyImport implements ShouldQueue
|
||||
$new_obj->save(['timestamps' => false]);
|
||||
$new_obj->number = $this->getNextTaskNumber($new_obj);
|
||||
}
|
||||
elseif($class == 'App\Models\Vendor' && is_null($obj->{$match_key})){
|
||||
$new_obj = new Vendor();
|
||||
$new_obj->company_id = $this->company->id;
|
||||
$new_obj->fill($obj_array);
|
||||
$new_obj->save(['timestamps' => false]);
|
||||
$new_obj->number = $this->getNextVendorNumber($new_obj);
|
||||
}
|
||||
elseif($class == 'App\Models\CompanyLedger'){
|
||||
$new_obj = $class::firstOrNew(
|
||||
[$match_key => $obj->{$match_key}, 'company_id' => $this->company->id],
|
||||
|
@ -498,8 +498,15 @@ class Account extends BaseModel
|
||||
|
||||
$plan_expires = Carbon::parse($this->plan_expires);
|
||||
|
||||
if(!$this->payment_id && $plan_expires->gt(now()))
|
||||
return $plan_expires->diffInDays();
|
||||
if(!$this->payment_id && $plan_expires->gt(now())){
|
||||
|
||||
$diff = $plan_expires->diffInDays();
|
||||
|
||||
if($diff > 14);
|
||||
return 0;
|
||||
|
||||
return $diff;
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
@ -23,10 +23,13 @@ use Illuminate\Support\Carbon;
|
||||
use Illuminate\Support\Facades\Storage;
|
||||
use Illuminate\Support\Str;
|
||||
|
||||
|
||||
/**
|
||||
* Class BaseModel
|
||||
*
|
||||
* @method scope() static
|
||||
*
|
||||
* @package App\Models
|
||||
*/
|
||||
class BaseModel extends Model
|
||||
{
|
||||
@ -187,17 +190,23 @@ class BaseModel extends Model
|
||||
|
||||
public function numberFormatter()
|
||||
{
|
||||
$number = strlen($this->number) >= 1 ? $this->number : class_basename($this).'_'.Str::random(5);
|
||||
$number = strlen($this->number) >= 1 ? $this->number : class_basename($this) . "_" . Str::random(5);
|
||||
|
||||
$formatted_number = mb_ereg_replace("([^\w\s\d\-_~,;\[\]\(\).])", '', $number);
|
||||
$formatted_number = mb_ereg_replace("([^\w\s\d\-_~,;\[\]\(\).])", '', $number);
|
||||
// Remove any runs of periods (thanks falstro!)
|
||||
$formatted_number = mb_ereg_replace("([\.]{2,})", '', $formatted_number);
|
||||
|
||||
// $formatted_number = str_replace(" ", "_", $formatted_number);
|
||||
|
||||
|
||||
//11-01-2021 fixes for multiple spaces
|
||||
$formatted_number = preg_replace('/\s+/', '_', $formatted_number);
|
||||
|
||||
return $formatted_number;
|
||||
}
|
||||
|
||||
public function translate_entity()
|
||||
{
|
||||
return ctrans('texts.item');
|
||||
}
|
||||
|
||||
}
|
||||
|
@ -32,7 +32,6 @@ class PurchaseOrder extends BaseModel
|
||||
protected $fillable = [
|
||||
'number',
|
||||
'discount',
|
||||
'company_id',
|
||||
'status_id',
|
||||
'last_sent_date',
|
||||
'is_deleted',
|
||||
@ -272,4 +271,8 @@ class PurchaseOrder extends BaseModel
|
||||
return $purchase_order_calc->build();
|
||||
}
|
||||
|
||||
public function translate_entity()
|
||||
{
|
||||
return ctrans('texts.purchase_order');
|
||||
}
|
||||
}
|
||||
|
@ -309,7 +309,6 @@ class BaseRepository
|
||||
$model->client->service()->updateBalance(($state['finished_amount'] - $state['starting_amount']))->save();
|
||||
$model->ledger()->updateInvoiceBalance(($state['finished_amount'] - $state['starting_amount']), "Update adjustment for invoice {$model->number}");
|
||||
|
||||
|
||||
}
|
||||
|
||||
if (! $model->design_id)
|
||||
|
@ -5978,6 +5978,10 @@ google_sign_in_platform_interface
|
||||
google_sign_in_web
|
||||
image_picker_for_web
|
||||
image_picker_platform_interface
|
||||
in_app_purchase
|
||||
in_app_purchase_android
|
||||
in_app_purchase_platform_interface
|
||||
in_app_purchase_storekit
|
||||
local_auth
|
||||
package_info
|
||||
path_provider
|
||||
|
68
public/flutter_service_worker.js
vendored
68
public/flutter_service_worker.js
vendored
@ -3,43 +3,43 @@ const MANIFEST = 'flutter-app-manifest';
|
||||
const TEMP = 'flutter-temp-cache';
|
||||
const CACHE_NAME = 'flutter-app-cache';
|
||||
const RESOURCES = {
|
||||
"favicon.png": "dca91c54388f52eded692718d5a98b8b",
|
||||
"canvaskit/canvaskit.js": "c2b4e5f3d7a3d82aed024e7249a78487",
|
||||
"canvaskit/profiling/canvaskit.js": "ae2949af4efc61d28a4a80fffa1db900",
|
||||
"canvaskit/profiling/canvaskit.wasm": "95e736ab31147d1b2c7b25f11d4c32cd",
|
||||
"canvaskit/canvaskit.wasm": "4b83d89d9fecbea8ca46f2f760c5a9ba",
|
||||
"/": "d0d0d12e2fe41ff93c6effa315b26755",
|
||||
"favicon.ico": "51636d3a390451561744c42188ccd628",
|
||||
"manifest.json": "ef43d90e57aa7682d7e2cfba2f484a40",
|
||||
"assets/assets/images/logo_light.png": "e5f46d5a78e226e7a9553d4ca6f69219",
|
||||
"assets/assets/images/payment_types/paypal.png": "8e06c094c1871376dfea1da8088c29d1",
|
||||
"assets/assets/images/payment_types/visa.png": "3ddc4a4d25c946e8ad7e6998f30fd4e3",
|
||||
"assets/assets/images/payment_types/solo.png": "2030c3ccaccf5d5e87916a62f5b084d6",
|
||||
"assets/assets/images/payment_types/mastercard.png": "6f6cdc29ee2e22e06b1ac029cb52ef71",
|
||||
"assets/assets/images/payment_types/discover.png": "6c0a386a00307f87db7bea366cca35f5",
|
||||
"assets/assets/images/payment_types/maestro.png": "e533b92bfb50339fdbfa79e3dfe81f08",
|
||||
"assets/assets/images/payment_types/carteblanche.png": "d936e11fa3884b8c9f1bd5c914be8629",
|
||||
"assets/assets/images/payment_types/dinerscard.png": "06d85186ba858c18ab7c9caa42c92024",
|
||||
"assets/assets/images/payment_types/amex.png": "c49a4247984b3732a4af50a3390aa978",
|
||||
"assets/assets/images/payment_types/unionpay.png": "7002f52004e0ab8cc0b7450b0208ccb2",
|
||||
"assets/assets/images/payment_types/jcb.png": "07e0942d16c5592118b72e74f2f7198c",
|
||||
"assets/assets/images/payment_types/other.png": "d936e11fa3884b8c9f1bd5c914be8629",
|
||||
"assets/assets/images/payment_types/switch.png": "4fa11c45327f5fdc20205821b2cfd9cc",
|
||||
"assets/assets/images/payment_types/ach.png": "7433f0aff779dc98a649b7a2daf777cf",
|
||||
"assets/assets/images/payment_types/laser.png": "b4e6e93dd35517ac429301119ff05868",
|
||||
"assets/assets/images/google_logo.png": "0f118259ce403274f407f5e982e681c3",
|
||||
"assets/assets/images/logo_dark.png": "a233ed1d4d0f7414bf97a9a10f11fb0a",
|
||||
"assets/assets/images/icon.png": "090f69e23311a4b6d851b3880ae52541",
|
||||
"assets/packages/material_design_icons_flutter/lib/fonts/materialdesignicons-webfont.ttf": "b62641afc9ab487008e996a5c5865e56",
|
||||
"assets/NOTICES": "c6e3ca05e75eaf4b48a1de0f34708ab4",
|
||||
"assets/AssetManifest.json": "38d9aea341601f3a5c6fa7b5a1216ea5",
|
||||
"assets/FontManifest.json": "cf3c681641169319e61b61bd0277378f",
|
||||
"assets/fonts/MaterialIcons-Regular.otf": "95db9098c58fd6db106f1116bae85a0b",
|
||||
"version.json": "4dfad0f7098e523184a2f58aff0e3940",
|
||||
"flutter.js": "eb2682e33f25cd8f1fc59011497c35f8",
|
||||
"icons/Icon-512.png": "0f9aff01367f0a0c69773d25ca16ef35",
|
||||
"icons/Icon-192.png": "bb1cf5f6982006952211c7c8404ffbed",
|
||||
"manifest.json": "ef43d90e57aa7682d7e2cfba2f484a40",
|
||||
"version.json": "4dfad0f7098e523184a2f58aff0e3940",
|
||||
"favicon.ico": "51636d3a390451561744c42188ccd628",
|
||||
"assets/FontManifest.json": "cf3c681641169319e61b61bd0277378f",
|
||||
"assets/fonts/MaterialIcons-Regular.otf": "95db9098c58fd6db106f1116bae85a0b",
|
||||
"assets/AssetManifest.json": "38d9aea341601f3a5c6fa7b5a1216ea5",
|
||||
"assets/assets/images/icon.png": "090f69e23311a4b6d851b3880ae52541",
|
||||
"assets/assets/images/google_logo.png": "0f118259ce403274f407f5e982e681c3",
|
||||
"assets/assets/images/logo_light.png": "e5f46d5a78e226e7a9553d4ca6f69219",
|
||||
"assets/assets/images/logo_dark.png": "a233ed1d4d0f7414bf97a9a10f11fb0a",
|
||||
"assets/assets/images/payment_types/jcb.png": "07e0942d16c5592118b72e74f2f7198c",
|
||||
"assets/assets/images/payment_types/amex.png": "c49a4247984b3732a4af50a3390aa978",
|
||||
"assets/assets/images/payment_types/visa.png": "3ddc4a4d25c946e8ad7e6998f30fd4e3",
|
||||
"assets/assets/images/payment_types/mastercard.png": "6f6cdc29ee2e22e06b1ac029cb52ef71",
|
||||
"assets/assets/images/payment_types/maestro.png": "e533b92bfb50339fdbfa79e3dfe81f08",
|
||||
"assets/assets/images/payment_types/ach.png": "7433f0aff779dc98a649b7a2daf777cf",
|
||||
"assets/assets/images/payment_types/discover.png": "6c0a386a00307f87db7bea366cca35f5",
|
||||
"assets/assets/images/payment_types/solo.png": "2030c3ccaccf5d5e87916a62f5b084d6",
|
||||
"assets/assets/images/payment_types/laser.png": "b4e6e93dd35517ac429301119ff05868",
|
||||
"assets/assets/images/payment_types/paypal.png": "8e06c094c1871376dfea1da8088c29d1",
|
||||
"assets/assets/images/payment_types/carteblanche.png": "d936e11fa3884b8c9f1bd5c914be8629",
|
||||
"assets/assets/images/payment_types/switch.png": "4fa11c45327f5fdc20205821b2cfd9cc",
|
||||
"assets/assets/images/payment_types/unionpay.png": "7002f52004e0ab8cc0b7450b0208ccb2",
|
||||
"assets/assets/images/payment_types/dinerscard.png": "06d85186ba858c18ab7c9caa42c92024",
|
||||
"assets/assets/images/payment_types/other.png": "d936e11fa3884b8c9f1bd5c914be8629",
|
||||
"assets/packages/material_design_icons_flutter/lib/fonts/materialdesignicons-webfont.ttf": "b62641afc9ab487008e996a5c5865e56",
|
||||
"assets/NOTICES": "e998160e43be5ffa6f6f6e39b398e093",
|
||||
"main.dart.js": "4523275a206508c0bf5d6e8ef219cb78"
|
||||
"canvaskit/canvaskit.wasm": "4b83d89d9fecbea8ca46f2f760c5a9ba",
|
||||
"canvaskit/canvaskit.js": "c2b4e5f3d7a3d82aed024e7249a78487",
|
||||
"canvaskit/profiling/canvaskit.wasm": "95e736ab31147d1b2c7b25f11d4c32cd",
|
||||
"canvaskit/profiling/canvaskit.js": "ae2949af4efc61d28a4a80fffa1db900",
|
||||
"/": "f0472d186e41814a028b5ca7814378c4",
|
||||
"favicon.png": "dca91c54388f52eded692718d5a98b8b",
|
||||
"main.dart.js": "fe987ef50f1a627038a89c1f4f1dabb0"
|
||||
};
|
||||
|
||||
// The application shell files that are downloaded before a service worker can
|
||||
|
188167
public/main.dart.js
vendored
188167
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
172403
public/main.foss.dart.js
vendored
172403
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
10755
public/main.profile.dart.js
vendored
10755
public/main.profile.dart.js
vendored
File diff suppressed because one or more lines are too long
Loading…
x
Reference in New Issue
Block a user