mirror of
https://github.com/invoiceninja/invoiceninja.git
synced 2025-06-05 21:54:35 -04:00
commit
4d3200fad2
@ -1 +1 @@
|
||||
5.5.43
|
||||
5.5.44
|
@ -54,6 +54,7 @@ class RecurringInvoiceExport extends BaseExport
|
||||
'po_number' => 'po_number',
|
||||
'private_notes' => 'private_notes',
|
||||
'public_notes' => 'public_notes',
|
||||
'next_send_date' => 'next_send_date',
|
||||
'status' => 'status_id',
|
||||
'tax_name1' => 'tax_name1',
|
||||
'tax_name2' => 'tax_name2',
|
||||
@ -66,6 +67,7 @@ class RecurringInvoiceExport extends BaseExport
|
||||
'currency' => 'currency_id',
|
||||
'vendor' => 'vendor_id',
|
||||
'project' => 'project_id',
|
||||
'frequency' => 'frequency_id'
|
||||
];
|
||||
|
||||
private array $decorate_keys = [
|
||||
@ -162,6 +164,8 @@ class RecurringInvoiceExport extends BaseExport
|
||||
$entity['vendor'] = $invoice->vendor ? $invoice->vendor->name : '';
|
||||
}
|
||||
|
||||
$entity['frequency'] = $invoice->frequencyForKey($invoice->frequency_id);
|
||||
|
||||
return $entity;
|
||||
}
|
||||
}
|
||||
|
@ -11,6 +11,7 @@
|
||||
|
||||
namespace App\Filters;
|
||||
|
||||
use App\Models\Company;
|
||||
use App\Models\User;
|
||||
use Illuminate\Database\Eloquent\Builder;
|
||||
|
||||
@ -54,6 +55,15 @@ class DocumentFilters extends QueryFilters
|
||||
return $this->builder->orderBy($sort_col[0], $sort_col[1]);
|
||||
}
|
||||
|
||||
|
||||
public function company_documents($value = 'false')
|
||||
{
|
||||
if($value == 'true')
|
||||
return $this->builder->where('documentable_type', Company::class);
|
||||
|
||||
return $this->builder;
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the base query.
|
||||
*
|
||||
|
@ -131,8 +131,6 @@ class EmailController extends BaseController
|
||||
if(Ninja::isHosted() && !$entity_obj->company->account->account_sms_verified)
|
||||
return response(['message' => 'Please verify your account to send emails.'], 400);
|
||||
|
||||
nlog($entity);
|
||||
|
||||
if($entity == 'purchaseOrder' || $entity == 'purchase_order' || $template == 'purchase_order' || $entity == 'App\Models\PurchaseOrder'){
|
||||
return $this->sendPurchaseOrder($entity_obj, $data, $template);
|
||||
}
|
||||
@ -141,7 +139,7 @@ class EmailController extends BaseController
|
||||
if (! $invitation->contact->trashed() && $invitation->contact->email) {
|
||||
$entity_obj->service()->markSent()->save();
|
||||
|
||||
EmailEntity::dispatch($invitation->fresh(), $invitation->company, $template, $data);
|
||||
EmailEntity::dispatch($invitation->fresh(), $invitation->company, $template, $data)->delay(now()->addSeconds(2));
|
||||
}
|
||||
});
|
||||
|
||||
@ -194,7 +192,7 @@ class EmailController extends BaseController
|
||||
|
||||
$data['template'] = $template;
|
||||
|
||||
PurchaseOrderEmail::dispatch($entity_obj, $entity_obj->company, $data);
|
||||
PurchaseOrderEmail::dispatch($entity_obj, $entity_obj->company, $data)->delay(now()->addSeconds(2));
|
||||
|
||||
return $this->itemResponse($entity_obj);
|
||||
|
||||
|
@ -136,6 +136,8 @@ class ImportController extends Controller
|
||||
}
|
||||
|
||||
$csv = Reader::createFromString($csvfile);
|
||||
$csvdelimiter = self::detectDelimiter($csvfile);
|
||||
$csv->setDelimiter($csvdelimiter);
|
||||
$stmt = new Statement();
|
||||
$data = iterator_to_array($stmt->process($csv));
|
||||
|
||||
@ -156,4 +158,17 @@ class ImportController extends Controller
|
||||
|
||||
return $data;
|
||||
}
|
||||
|
||||
public function detectDelimiter($csvfile)
|
||||
{
|
||||
$delimiters = array(',', '.', ';');
|
||||
$bestDelimiter = false;
|
||||
$count = 0;
|
||||
foreach ($delimiters as $delimiter)
|
||||
if (substr_count($csvfile, $delimiter) > $count) {
|
||||
$count = substr_count($csvfile, $delimiter);
|
||||
$bestDelimiter = $delimiter;
|
||||
}
|
||||
return $bestDelimiter;
|
||||
}
|
||||
}
|
||||
|
@ -26,7 +26,7 @@
|
||||
* @OA\Property(property="city", type="string", example="", description="________"),
|
||||
* @OA\Property(property="state", type="string", example="", description="________"),
|
||||
* @OA\Property(property="postal_code", type="string", example="", description="________"),
|
||||
* @OA\Property(property="work_phone", type="string", example="555-3434-3434", description="The client phone number"),
|
||||
* @OA\Property(property="phone", type="string", example="555-3434-3434", description="The client phone number"),
|
||||
* @OA\Property(property="country_id", type="string", example="", description="________"),
|
||||
* @OA\Property(property="currency_id", type="string", example="4", description="________"),
|
||||
* @OA\Property(property="custom_value1", type="string", example="", description="________"),
|
||||
|
@ -44,7 +44,7 @@ class StoreBankIntegrationRequest extends Request
|
||||
{
|
||||
$input = $this->all();
|
||||
|
||||
if(!array_key_exists('provider_name', $input) || strlen($input['provider_name']) == 0 && array_key_exists('bank_account_name', $input))
|
||||
if((!array_key_exists('provider_name', $input) || strlen($input['provider_name']) == 0) && array_key_exists('bank_account_name', $input))
|
||||
$input['provider_name'] = $input['bank_account_name'];
|
||||
|
||||
$this->replace($input);
|
||||
|
@ -34,8 +34,7 @@ class StoreBankTransactionRequest extends Request
|
||||
|
||||
$rules = [];
|
||||
|
||||
if(isset($this->bank_integration_id))
|
||||
$rules['bank_integration_id'] = 'bail|required|exists:bank_integrations,id,company_id,'.auth()->user()->company()->id.',is_deleted,0';
|
||||
$rules['bank_integration_id'] = 'bail|required|exists:bank_integrations,id,company_id,'.auth()->user()->company()->id.',is_deleted,0';
|
||||
|
||||
return $rules;
|
||||
}
|
||||
@ -44,7 +43,9 @@ class StoreBankTransactionRequest extends Request
|
||||
{
|
||||
$input = $this->all();
|
||||
|
||||
if(array_key_exists('bank_integration_id', $input) && strlen($input['bank_integration_id']) > 1 && !is_numeric($input['bank_integration_id']))
|
||||
if(array_key_exists('bank_integration_id', $input) && $input['bank_integration_id'] == "")
|
||||
unset($input['bank_integration_id']);
|
||||
elseif(array_key_exists('bank_integration_id', $input) && strlen($input['bank_integration_id']) > 1 && !is_numeric($input['bank_integration_id']))
|
||||
$input['bank_integration_id'] = $this->decodePrimaryKey($input['bank_integration_id']);
|
||||
|
||||
$this->replace($input);
|
||||
|
@ -45,8 +45,7 @@ class UpdateBankTransactionRequest extends Request
|
||||
if(isset($this->expense_id))
|
||||
$rules['expense_id'] = 'bail|required|exists:expenses,id,company_id,'.auth()->user()->company()->id.',is_deleted,0';
|
||||
|
||||
if(isset($this->bank_integration_id))
|
||||
$rules['bank_integration_id'] = 'bail|required|exists:bank_integrations,id,company_id,'.auth()->user()->company()->id.',is_deleted,0';
|
||||
$rules['bank_integration_id'] = 'bail|required|exists:bank_integrations,id,company_id,'.auth()->user()->company()->id.',is_deleted,0';
|
||||
|
||||
|
||||
return $rules;
|
||||
@ -69,7 +68,9 @@ class UpdateBankTransactionRequest extends Request
|
||||
if(array_key_exists('ninja_category_id', $input) && strlen($input['ninja_category_id']) > 1)
|
||||
$input['ninja_category_id'] = $this->decodePrimaryKey($input['ninja_category_id']);
|
||||
|
||||
if(array_key_exists('bank_integration_id', $input) && strlen($input['bank_integration_id']) > 1)
|
||||
if(array_key_exists('bank_integration_id', $input) && $input['bank_integration_id'] == "")
|
||||
unset($input['bank_integration_id']);
|
||||
elseif(array_key_exists('bank_integration_id', $input) && strlen($input['bank_integration_id']) > 1)
|
||||
$input['bank_integration_id'] = $this->decodePrimaryKey($input['bank_integration_id']);
|
||||
|
||||
$this->replace($input);
|
||||
|
@ -45,6 +45,8 @@ class StoreExpenseRequest extends Request
|
||||
$rules['client_id'] = 'bail|sometimes|exists:clients,id,company_id,'.auth()->user()->company()->id;
|
||||
}
|
||||
|
||||
$rules['category_id'] = 'bail|nullable|sometimes|exists:expense_categories,id,company_id,'.auth()->user()->company()->id.',is_deleted,0';
|
||||
|
||||
return $this->globalRules($rules);
|
||||
}
|
||||
|
||||
@ -54,10 +56,6 @@ class StoreExpenseRequest extends Request
|
||||
|
||||
$input = $this->decodePrimaryKeys($input);
|
||||
|
||||
if (array_key_exists('category_id', $input) && is_string($input['category_id'])) {
|
||||
$input['category_id'] = $this->decodePrimaryKey($input['category_id']);
|
||||
}
|
||||
|
||||
if (! array_key_exists('currency_id', $input) || strlen($input['currency_id']) == 0) {
|
||||
$input['currency_id'] = (string) auth()->user()->company()->settings->currency_id;
|
||||
}
|
||||
@ -66,7 +64,6 @@ class StoreExpenseRequest extends Request
|
||||
$input['color'] = '';
|
||||
}
|
||||
|
||||
|
||||
/* Ensure the project is related */
|
||||
if (array_key_exists('project_id', $input) && isset($input['project_id'])) {
|
||||
$project = Project::withTrashed()->where('id', $input['project_id'])->company()->first();
|
||||
|
@ -41,6 +41,8 @@ class UpdateExpenseRequest extends Request
|
||||
$rules['number'] = Rule::unique('expenses')->where('company_id', auth()->user()->company()->id)->ignore($this->expense->id);
|
||||
}
|
||||
|
||||
$rules['category_id'] = 'bail|sometimes|nullable|exists:expense_categories,id,company_id,'.auth()->user()->company()->id.',is_deleted,0';
|
||||
|
||||
return $this->globalRules($rules);
|
||||
}
|
||||
|
||||
@ -50,10 +52,6 @@ class UpdateExpenseRequest extends Request
|
||||
|
||||
$input = $this->decodePrimaryKeys($input);
|
||||
|
||||
if (array_key_exists('category_id', $input) && is_string($input['category_id'])) {
|
||||
$input['category_id'] = $this->decodePrimaryKey($input['category_id']);
|
||||
}
|
||||
|
||||
if (array_key_exists('documents', $input)) {
|
||||
unset($input['documents']);
|
||||
}
|
||||
|
@ -39,6 +39,6 @@ class ValidCompanyQuantity implements Rule
|
||||
*/
|
||||
public function message()
|
||||
{
|
||||
return ctrans('texts.company_limit_reached');
|
||||
return ctrans('texts.company_limit_reached', ['limit' => Ninja::isSelfHost() ? 10 : auth()->user()->company()->account->hosted_company_count]);
|
||||
}
|
||||
}
|
||||
|
@ -38,7 +38,7 @@ class ClientTransformer extends BaseTransformer
|
||||
return [
|
||||
'company_id' => $this->company->id,
|
||||
'name' => $this->getString($data, 'client.name'),
|
||||
'work_phone' => $this->getString($data, 'client.phone'),
|
||||
'phone' => $this->getString($data, 'client.phone'),
|
||||
'address1' => $this->getString($data, 'client.address1'),
|
||||
'address2' => $this->getString($data, 'client.address2'),
|
||||
'postal_code' => $this->getString($data, 'client.postal_code'),
|
||||
|
@ -42,7 +42,7 @@ class ClientTransformer extends BaseTransformer
|
||||
'company_id' => $this->company->id,
|
||||
'name' => $this->getString($data, 'customer_name'),
|
||||
'number' => $this->getValueOrNull($data, 'account_number'),
|
||||
'work_phone' => $this->getString($data, 'phone'),
|
||||
'phone' => $this->getString($data, 'phone'),
|
||||
'website' => $this->getString($data, 'website'),
|
||||
'country_id' => ! empty($data['country']) ? $this->getCountryId($data['country']) : null,
|
||||
'state' => $this->getString($data, 'province/state'),
|
||||
|
@ -35,7 +35,7 @@ class ClientTransformer extends BaseTransformer
|
||||
return [
|
||||
'company_id' => $this->maps['company']->id,
|
||||
'name' => $this->getString($data, 'client.name'),
|
||||
'work_phone' => $this->getString($data, 'client.phone'),
|
||||
'phone' => $this->getString($data, 'client.phone'),
|
||||
'address1' => $this->getString($data, 'client.address1'),
|
||||
'address2' => $this->getString($data, 'client.address2'),
|
||||
'city' => $this->getString($data, 'client.city'),
|
||||
|
@ -37,7 +37,7 @@ class ClientTransformer extends BaseTransformer
|
||||
return [
|
||||
'company_id' => $this->maps['company']->id,
|
||||
'name' => $this->getString($data, 'client.name'),
|
||||
'work_phone' => $this->getString($data, 'client.phone'),
|
||||
'phone' => $this->getString($data, 'client.phone'),
|
||||
'address1' => $this->getString($data, 'client.address1'),
|
||||
'address2' => $this->getString($data, 'client.address2'),
|
||||
'postal_code' => $this->getString($data, 'client.postal_code'),
|
||||
|
@ -34,7 +34,7 @@ class ClientTransformer extends BaseTransformer
|
||||
return [
|
||||
'company_id' => $this->maps['company']->id,
|
||||
'name' => $this->getString($data, 'Organization'),
|
||||
'work_phone' => $this->getString($data, 'Phone'),
|
||||
'phone' => $this->getString($data, 'Phone'),
|
||||
'address1' => $this->getString($data, 'Street'),
|
||||
'city' => $this->getString($data, 'City'),
|
||||
'state' => $this->getString($data, 'Province/State'),
|
||||
|
@ -34,7 +34,7 @@ class ClientTransformer extends BaseTransformer
|
||||
return [
|
||||
'company_id' => $this->maps['company']->id,
|
||||
'name' => $this->getString($data, 'Client Name'),
|
||||
'work_phone' => $this->getString($data, 'Phone'),
|
||||
'phone' => $this->getString($data, 'Phone'),
|
||||
'country_id' => isset($data['Country']) ? $this->getCountryIdBy2($data['Country']) : null,
|
||||
'credit_balance' => 0,
|
||||
'settings' => new \stdClass,
|
||||
|
@ -42,7 +42,7 @@ class ClientTransformer extends BaseTransformer
|
||||
'company_id' => $this->maps['company']->id,
|
||||
'name' => $this->getString($data, 'customer_name'),
|
||||
'number' => $this->getString($data, 'account_number'),
|
||||
'work_phone' => $this->getString($data, 'phone'),
|
||||
'phone' => $this->getString($data, 'phone'),
|
||||
'website' => $this->getString($data, 'website'),
|
||||
'country_id' => ! empty($data['country']) ? $this->getCountryId($data['country']) : null,
|
||||
'state' => $this->getString($data, 'province/state'),
|
||||
|
@ -41,7 +41,7 @@ class ClientTransformer extends BaseTransformer
|
||||
return [
|
||||
'company_id' => $this->maps['company']->id,
|
||||
'name' => $this->getString($data, 'Company Name'),
|
||||
'work_phone' => $this->getString($data, 'Phone'),
|
||||
'phone' => $this->getString($data, 'Phone'),
|
||||
'private_notes' => $this->getString($data, 'Notes'),
|
||||
'website' => $this->getString($data, 'Website'),
|
||||
'id_number' => $this->getString($data, 'Customer ID'),
|
||||
|
@ -266,7 +266,7 @@ class MatchBankTransactions implements ShouldQueue
|
||||
/* Create Payment */
|
||||
$payment = PaymentFactory::create($this->invoice->company_id, $this->invoice->user_id);
|
||||
|
||||
$payment->amount = $amount;
|
||||
$payment->amount = $this->bt->amount;
|
||||
$payment->applied = $this->applied_amount;
|
||||
$payment->status_id = Payment::STATUS_COMPLETED;
|
||||
$payment->client_id = $this->invoice->client_id;
|
||||
@ -315,7 +315,7 @@ class MatchBankTransactions implements ShouldQueue
|
||||
$this->invoice
|
||||
->client
|
||||
->service()
|
||||
->updateBalanceAndPaidToDate($amount*-1, $amount)
|
||||
->updateBalanceAndPaidToDate($this->applied_amount*-1, $amount)
|
||||
->save();
|
||||
|
||||
$this->invoice = $this->invoice
|
||||
|
@ -11,6 +11,7 @@
|
||||
|
||||
namespace App\Mail\Engine;
|
||||
|
||||
use App\Jobs\Entity\CreateRawPdf;
|
||||
use App\Models\Account;
|
||||
use App\Utils\HtmlEngine;
|
||||
use App\Utils\Ninja;
|
||||
@ -117,11 +118,17 @@ class CreditEmailEngine extends BaseEmailEngine
|
||||
->setTextBody($text_body);
|
||||
|
||||
if ($this->client->getSetting('pdf_email_attachment') !== false && $this->credit->company->account->hasFeature(Account::FEATURE_PDF_ATTACHMENT)) {
|
||||
if (Ninja::isHosted()) {
|
||||
$this->setAttachments([$this->credit->pdf_file_path($this->invitation, 'url', true)]);
|
||||
} else {
|
||||
$this->setAttachments([$this->credit->pdf_file_path($this->invitation)]);
|
||||
}
|
||||
// if (Ninja::isHosted()) {
|
||||
// $this->setAttachments([$this->credit->pdf_file_path($this->invitation, 'url', true)]);
|
||||
// } else {
|
||||
// $this->setAttachments([$this->credit->pdf_file_path($this->invitation)]);
|
||||
// }
|
||||
|
||||
$pdf = ((new CreateRawPdf($this->invitation, $this->invitation->company->db))->handle());
|
||||
|
||||
$this->setAttachments([['file' => base64_encode($pdf), 'name' => $this->credit->numberFormatter().'.pdf']]);
|
||||
|
||||
|
||||
}
|
||||
|
||||
//attach third party documents
|
||||
@ -129,11 +136,11 @@ class CreditEmailEngine extends BaseEmailEngine
|
||||
|
||||
// Storage::url
|
||||
foreach ($this->credit->documents as $document) {
|
||||
$this->setAttachments([['path' => $document->filePath(), 'name' => $document->name, 'mime' => null]]);
|
||||
$this->setAttachments([['path' => $document->filePath(), 'name' => $document->name, 'mime' => NULL, 'file' => base64_encode($document->getFile())]]);
|
||||
}
|
||||
|
||||
foreach ($this->credit->company->documents as $document) {
|
||||
$this->setAttachments([['path' => $document->filePath(), 'name' => $document->name, 'mime' => null]]);
|
||||
$this->setAttachments([['path' => $document->filePath(), 'name' => $document->name, 'mime' => NULL, 'file' => base64_encode($document->getFile())]]);
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -13,6 +13,7 @@ namespace App\Mail\Engine;
|
||||
|
||||
use App\DataMapper\EmailTemplateDefaults;
|
||||
use App\Jobs\Entity\CreateEntityPdf;
|
||||
use App\Jobs\Entity\CreateRawPdf;
|
||||
use App\Models\Account;
|
||||
use App\Models\Expense;
|
||||
use App\Models\Task;
|
||||
@ -126,11 +127,15 @@ class InvoiceEmailEngine extends BaseEmailEngine
|
||||
->setTextBody($text_body);
|
||||
|
||||
if ($this->client->getSetting('pdf_email_attachment') !== false && $this->invoice->company->account->hasFeature(Account::FEATURE_PDF_ATTACHMENT)) {
|
||||
if (Ninja::isHosted()) {
|
||||
$this->setAttachments([$this->invoice->pdf_file_path($this->invitation, 'url', true)]);
|
||||
} else {
|
||||
$this->setAttachments([$this->invoice->pdf_file_path($this->invitation)]);
|
||||
}
|
||||
// if (Ninja::isHosted()) {
|
||||
// $this->setAttachments([$this->invoice->pdf_file_path($this->invitation, 'url', true)]);
|
||||
// } else {
|
||||
// $this->setAttachments([$this->invoice->pdf_file_path($this->invitation)]);
|
||||
// }
|
||||
// $file = (new CreateRawPdf($invitation, $invitation->company->db))->handle();
|
||||
$pdf = ((new CreateRawPdf($this->invitation, $this->invitation->company->db))->handle());
|
||||
|
||||
$this->setAttachments([['file' => base64_encode($pdf), 'name' => $this->invoice->numberFormatter().'.pdf']]);
|
||||
}
|
||||
|
||||
//attach third party documents
|
||||
@ -138,11 +143,11 @@ class InvoiceEmailEngine extends BaseEmailEngine
|
||||
|
||||
// Storage::url
|
||||
foreach ($this->invoice->documents as $document) {
|
||||
$this->setAttachments([['path' => $document->filePath(), 'name' => $document->name, 'mime' => NULL]]);
|
||||
$this->setAttachments([['path' => $document->filePath(), 'name' => $document->name, 'mime' => NULL, ]]);
|
||||
}
|
||||
|
||||
foreach ($this->invoice->company->documents as $document) {
|
||||
$this->setAttachments([['path' => $document->filePath(), 'name' => $document->name, 'mime' => NULL]]);
|
||||
$this->setAttachments([['path' => $document->filePath(), 'name' => $document->name, 'mime' => NULL, ]]);
|
||||
}
|
||||
|
||||
$line_items = $this->invoice->line_items;
|
||||
@ -160,7 +165,7 @@ class InvoiceEmailEngine extends BaseEmailEngine
|
||||
->cursor()
|
||||
->each(function ($expense) {
|
||||
foreach ($expense->documents as $document) {
|
||||
$this->setAttachments([['path' => $document->filePath(), 'name' => $document->name, 'mime' => NULL]]);
|
||||
$this->setAttachments([['path' => $document->filePath(), 'name' => $document->name, 'mime' => NULL, ]]);
|
||||
}
|
||||
});
|
||||
}
|
||||
@ -176,7 +181,7 @@ class InvoiceEmailEngine extends BaseEmailEngine
|
||||
->cursor()
|
||||
->each(function ($task) {
|
||||
foreach ($task->documents as $document) {
|
||||
$this->setAttachments([['path' => $document->filePath(), 'name' => $document->name, 'mime' => NULL]]);
|
||||
$this->setAttachments([['path' => $document->filePath(), 'name' => $document->name, 'mime' => NULL, ]]);
|
||||
}
|
||||
});
|
||||
}
|
||||
|
@ -12,6 +12,7 @@
|
||||
namespace App\Mail\Engine;
|
||||
|
||||
use App\DataMapper\EmailTemplateDefaults;
|
||||
use App\Jobs\Entity\CreateRawPdf;
|
||||
use App\Models\Account;
|
||||
use App\Utils\Helpers;
|
||||
use App\Utils\Ninja;
|
||||
@ -89,11 +90,15 @@ class PaymentEmailEngine extends BaseEmailEngine
|
||||
|
||||
if ($this->client->getSetting('pdf_email_attachment') !== false && $this->company->account->hasFeature(Account::FEATURE_PDF_ATTACHMENT)) {
|
||||
$this->payment->invoices->each(function ($invoice) {
|
||||
if (Ninja::isHosted()) {
|
||||
$this->setAttachments([$invoice->pdf_file_path($invoice->invitations->first(), 'url', true)]);
|
||||
} else {
|
||||
$this->setAttachments([$invoice->pdf_file_path($invoice->invitations->first())]);
|
||||
}
|
||||
// if (Ninja::isHosted()) {
|
||||
// $this->setAttachments([$invoice->pdf_file_path($invoice->invitations->first(), 'url', true)]);
|
||||
// } else {
|
||||
// $this->setAttachments([$invoice->pdf_file_path($invoice->invitations->first())]);
|
||||
// }
|
||||
$pdf = ((new CreateRawPdf($invoice->invitations->first(), $invoice->company->db))->handle());
|
||||
|
||||
$this->setAttachments([['file' => base64_encode($pdf), 'name' => $invoice->numberFormatter().'.pdf']]);
|
||||
|
||||
});
|
||||
}
|
||||
|
||||
|
@ -13,6 +13,7 @@ namespace App\Mail\Engine;
|
||||
|
||||
use App\DataMapper\EmailTemplateDefaults;
|
||||
use App\Jobs\Entity\CreateEntityPdf;
|
||||
use App\Jobs\Vendor\CreatePurchaseOrderPdf;
|
||||
use App\Models\Account;
|
||||
use App\Models\Expense;
|
||||
use App\Models\PurchaseOrder;
|
||||
@ -125,11 +126,16 @@ class PurchaseOrderEmailEngine extends BaseEmailEngine
|
||||
->setTextBody($text_body);
|
||||
|
||||
if ($this->vendor->getSetting('pdf_email_attachment') !== false && $this->purchase_order->company->account->hasFeature(Account::FEATURE_PDF_ATTACHMENT)) {
|
||||
if (Ninja::isHosted()) {
|
||||
$this->setAttachments([$this->purchase_order->pdf_file_path($this->invitation, 'url', true)]);
|
||||
} else {
|
||||
$this->setAttachments([$this->purchase_order->pdf_file_path($this->invitation)]);
|
||||
}
|
||||
// if (Ninja::isHosted()) {
|
||||
// $this->setAttachments([$this->purchase_order->pdf_file_path($this->invitation, 'url', true)]);
|
||||
// } else {
|
||||
// $this->setAttachments([$this->purchase_order->pdf_file_path($this->invitation)]);
|
||||
// }
|
||||
|
||||
$pdf = (new CreatePurchaseOrderPdf($this->invitation))->rawPdf();
|
||||
|
||||
$this->setAttachments([['file' => base64_encode($pdf), 'name' => $this->purchase_order->numberFormatter().'.pdf']]);
|
||||
|
||||
}
|
||||
|
||||
//attach third party documents
|
||||
@ -138,10 +144,12 @@ class PurchaseOrderEmailEngine extends BaseEmailEngine
|
||||
// Storage::url
|
||||
foreach ($this->purchase_order->documents as $document) {
|
||||
$this->setAttachments([['path' => $document->filePath(), 'name' => $document->name, 'mime' => null]]);
|
||||
// $this->setAttachments([['path' => $document->filePath(), 'name' => $document->name, 'mime' => NULL, 'file' => base64_encode($document->getFile())]]);
|
||||
}
|
||||
|
||||
foreach ($this->purchase_order->company->documents as $document) {
|
||||
$this->setAttachments([['path' => $document->filePath(), 'name' => $document->name, 'mime' => null]]);
|
||||
// $this->setAttachments([['path' => $document->filePath(), 'name' => $document->name, 'mime' => NULL, 'file' => base64_encode($document->getFile())]]);
|
||||
}
|
||||
|
||||
}
|
||||
|
@ -11,6 +11,7 @@
|
||||
|
||||
namespace App\Mail\Engine;
|
||||
|
||||
use App\Jobs\Entity\CreateRawPdf;
|
||||
use App\Models\Account;
|
||||
use App\Utils\HtmlEngine;
|
||||
use App\Utils\Ninja;
|
||||
@ -116,11 +117,15 @@ class QuoteEmailEngine extends BaseEmailEngine
|
||||
->setTextBody($text_body);
|
||||
|
||||
if ($this->client->getSetting('pdf_email_attachment') !== false && $this->quote->company->account->hasFeature(Account::FEATURE_PDF_ATTACHMENT)) {
|
||||
if (Ninja::isHosted()) {
|
||||
$this->setAttachments([$this->quote->pdf_file_path($this->invitation, 'url', true)]);
|
||||
} else {
|
||||
$this->setAttachments([$this->quote->pdf_file_path($this->invitation)]);
|
||||
}
|
||||
// if (Ninja::isHosted()) {
|
||||
// $this->setAttachments([$this->quote->pdf_file_path($this->invitation, 'url', true)]);
|
||||
// } else {
|
||||
// $this->setAttachments([$this->quote->pdf_file_path($this->invitation)]);
|
||||
// }
|
||||
|
||||
$pdf = ((new CreateRawPdf($this->invitation, $this->invitation->company->db))->handle());
|
||||
|
||||
$this->setAttachments([['file' => base64_encode($pdf), 'name' => $this->quote->numberFormatter().'.pdf']]);
|
||||
}
|
||||
|
||||
//attach third party documents
|
||||
@ -128,11 +133,11 @@ class QuoteEmailEngine extends BaseEmailEngine
|
||||
|
||||
// Storage::url
|
||||
foreach ($this->quote->documents as $document) {
|
||||
$this->setAttachments([['path' => $document->filePath(), 'name' => $document->name, 'mime' => null]]);
|
||||
$this->setAttachments([['path' => $document->filePath(), 'name' => $document->name, 'mime' => NULL, ]]);
|
||||
}
|
||||
|
||||
foreach ($this->quote->company->documents as $document) {
|
||||
$this->setAttachments([['path' => $document->filePath(), 'name' => $document->name, 'mime' => null]]);
|
||||
$this->setAttachments([['path' => $document->filePath(), 'name' => $document->name, 'mime' => NULL, ]]);
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -120,45 +120,53 @@ class TemplateEmail extends Mailable
|
||||
|
||||
/*In the hosted platform we need to slow things down a little for Storage to catch up.*/
|
||||
|
||||
if(Ninja::isHosted() && $this->invitation){
|
||||
// if(Ninja::isHosted() && $this->invitation){
|
||||
|
||||
$path = false;
|
||||
// $path = false;
|
||||
|
||||
if($this->invitation->invoice)
|
||||
$path = $this->client->invoice_filepath($this->invitation).$this->invitation->invoice->numberFormatter().'.pdf';
|
||||
elseif($this->invitation->quote)
|
||||
$path = $this->client->quote_filepath($this->invitation).$this->invitation->quote->numberFormatter().'.pdf';
|
||||
elseif($this->invitation->credit)
|
||||
$path = $this->client->credit_filepath($this->invitation).$this->invitation->credit->numberFormatter().'.pdf';
|
||||
// if($this->invitation->invoice)
|
||||
// $path = $this->client->invoice_filepath($this->invitation).$this->invitation->invoice->numberFormatter().'.pdf';
|
||||
// elseif($this->invitation->quote)
|
||||
// $path = $this->client->quote_filepath($this->invitation).$this->invitation->quote->numberFormatter().'.pdf';
|
||||
// elseif($this->invitation->credit)
|
||||
// $path = $this->client->credit_filepath($this->invitation).$this->invitation->credit->numberFormatter().'.pdf';
|
||||
|
||||
sleep(1);
|
||||
// sleep(1);
|
||||
|
||||
if($path && !Storage::disk(config('filesystems.default'))->exists($path)){
|
||||
// if($path && !Storage::disk(config('filesystems.default'))->exists($path)){
|
||||
|
||||
sleep(2);
|
||||
// sleep(2);
|
||||
|
||||
if(!Storage::disk(config('filesystems.default'))->exists($path)) {
|
||||
(new CreateEntityPdf($this->invitation))->handle();
|
||||
sleep(2);
|
||||
}
|
||||
// if(!Storage::disk(config('filesystems.default'))->exists($path)) {
|
||||
// (new CreateEntityPdf($this->invitation))->handle();
|
||||
// sleep(2);
|
||||
// }
|
||||
|
||||
}
|
||||
// }
|
||||
|
||||
// }
|
||||
|
||||
// $file = (new CreateRawPdf($invitation, $invitation->company->db))->handle();
|
||||
|
||||
}
|
||||
|
||||
//22-10-2022 - Performance - To improve the performance/reliability of sending emails, attaching as Data is much better, stubs in place
|
||||
foreach ($this->build_email->getAttachments() as $file) {
|
||||
if (is_string($file)) {
|
||||
// nlog($file);
|
||||
// $file_data = file_get_contents($file);
|
||||
// $this->attachData($file_data, basename($file));
|
||||
$this->attach($file);
|
||||
} elseif (is_array($file)) {
|
||||
// nlog($file['path']);
|
||||
// $file_data = file_get_contents($file['path']);
|
||||
// $this->attachData($file_data, $file['name']);
|
||||
// if (is_string($file)) {
|
||||
// // nlog($file);
|
||||
// // $file_data = file_get_contents($file);
|
||||
// // $this->attachData($file_data, basename($file));
|
||||
// $this->attach($file);
|
||||
// } elseif (is_array($file)) {
|
||||
// // nlog($file['path']);
|
||||
// // $file_data = file_get_contents($file['path']);
|
||||
// // $this->attachData($file_data, $file['name']);
|
||||
// $this->attach($file['path'], ['as' => $file['name'], 'mime' => null]);
|
||||
// }
|
||||
if(array_key_exists('file', $file))
|
||||
$this->attachData(base64_decode($file['file']), $file['name']);
|
||||
else
|
||||
$this->attach($file['path'], ['as' => $file['name'], 'mime' => null]);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
if ($this->invitation && $this->invitation->invoice && $settings->ubl_email_attachment && $this->company->account->hasFeature(Account::FEATURE_PDF_ATTACHMENT)) {
|
||||
|
@ -110,40 +110,39 @@ class VendorTemplateEmail extends Mailable
|
||||
'whitelabel' => $this->vendor->user->account->isPaid() ? true : false,
|
||||
'logo' => $this->company->present()->logo($settings),
|
||||
]);
|
||||
//->withSymfonyMessage(function ($message) {
|
||||
// $message->getHeaders()->addTextHeader('Tag', $this->company->company_key);
|
||||
// $message->invitation = $this->invitation;
|
||||
//});
|
||||
// ->tag($this->company->company_key);
|
||||
|
||||
if(Ninja::isHosted() && $this->invitation){
|
||||
|
||||
$path = false;
|
||||
// if(Ninja::isHosted() && $this->invitation){
|
||||
|
||||
if($this->invitation->purchase_order)
|
||||
$path = $this->vendor->purchase_order_filepath($this->invitation).$this->invitation->purchase_order->numberFormatter().'.pdf';
|
||||
// $path = false;
|
||||
|
||||
sleep(1);
|
||||
// if($this->invitation->purchase_order)
|
||||
// $path = $this->vendor->purchase_order_filepath($this->invitation).$this->invitation->purchase_order->numberFormatter().'.pdf';
|
||||
|
||||
if($path && !Storage::disk(config('filesystems.default'))->exists($path)){
|
||||
// sleep(1);
|
||||
|
||||
sleep(2);
|
||||
// if($path && !Storage::disk(config('filesystems.default'))->exists($path)){
|
||||
|
||||
if(!Storage::disk(config('filesystems.default'))->exists($path)) {
|
||||
(new CreatePurchaseOrderPdf($this->invitation))->handle();
|
||||
sleep(2);
|
||||
}
|
||||
// sleep(2);
|
||||
|
||||
}
|
||||
// if(!Storage::disk(config('filesystems.default'))->exists($path)) {
|
||||
// (new CreatePurchaseOrderPdf($this->invitation))->handle();
|
||||
// sleep(2);
|
||||
// }
|
||||
|
||||
}
|
||||
// }
|
||||
|
||||
// }
|
||||
|
||||
foreach ($this->build_email->getAttachments() as $file) {
|
||||
if (is_string($file)) {
|
||||
$this->attach($file);
|
||||
} elseif (is_array($file)) {
|
||||
$this->attach($file['path'], ['as' => $file['name'], 'mime' => null]);
|
||||
}
|
||||
// if (is_string($file)) {
|
||||
// $this->attach($file);
|
||||
// } elseif (is_array($file)) {
|
||||
// $this->attach($file['path'], ['as' => $file['name'], 'mime' => null]);
|
||||
// }
|
||||
|
||||
$this->attachData(base64_decode($file['file']), $file['name']);
|
||||
|
||||
}
|
||||
|
||||
return $this;
|
||||
|
@ -119,7 +119,7 @@ class CompanyPresenter extends EntityPresenter
|
||||
$str .= e($country->name).'<br/>';
|
||||
}
|
||||
if ($settings->phone) {
|
||||
$str .= ctrans('texts.work_phone').': '.e($settings->phone).'<br/>';
|
||||
$str .= ctrans('texts.phone').': '.e($settings->phone).'<br/>';
|
||||
}
|
||||
if ($settings->email) {
|
||||
$str .= ctrans('texts.work_email').': '.e($settings->email).'<br/>';
|
||||
|
@ -94,8 +94,6 @@ class CreditCard implements MethodInterface
|
||||
|
||||
$customerRequest = $this->checkout->getCustomer();
|
||||
|
||||
nlog($customerRequest);
|
||||
|
||||
$request = $this->bootRequest($gateway_response->token);
|
||||
$request->capture = false;
|
||||
$request->reference = '$1 payment for authorization.';
|
||||
|
@ -34,6 +34,7 @@ use Checkout\CheckoutArgumentException;
|
||||
use Checkout\CheckoutAuthorizationException;
|
||||
use Checkout\CheckoutDefaultSdk;
|
||||
use Checkout\CheckoutFourSdk;
|
||||
use Checkout\Common\Phone;
|
||||
use Checkout\Customers\CustomerRequest;
|
||||
use Checkout\Customers\Four\CustomerRequest as FourCustomerRequest;
|
||||
use Checkout\Environment;
|
||||
@ -300,9 +301,12 @@ class CheckoutComPaymentDriver extends BaseDriver
|
||||
$request = new CustomerRequest();
|
||||
}
|
||||
|
||||
$request->email = $this->client->present()->email();
|
||||
$request->name = $this->client->present()->name();
|
||||
$request->phone = $this->client->present()->phone();
|
||||
$phone = new Phone();
|
||||
$phone->number = $this->client->present()->phone();
|
||||
|
||||
$request->email = $this->client->present()->email();
|
||||
$request->name = $this->client->present()->name();
|
||||
$request->phone = $phone;
|
||||
|
||||
try {
|
||||
$response = $this->gateway->getCustomersClient()->create($request);
|
||||
|
@ -36,6 +36,7 @@ use Stripe\Exception\CardException;
|
||||
use Stripe\Exception\InvalidRequestException;
|
||||
use Stripe\Exception\RateLimitException;
|
||||
use Stripe\PaymentIntent;
|
||||
use App\Utils\Number;
|
||||
|
||||
class ACH
|
||||
{
|
||||
@ -172,9 +173,9 @@ class ACH
|
||||
->first();
|
||||
|
||||
if ($invoice) {
|
||||
$description = "Invoice {$invoice->number} for {$amount} for client {$this->stripe->client->present()->name()}";
|
||||
$description = ctrans('texts.stripe_paymenttext', ['invoicenumber' => $invoice->number, 'amount' => Number::formatMoney($amount, $this->stripe->client), 'client' => $this->stripe->client->present()->name()]);
|
||||
} else {
|
||||
$description = "Payment with no invoice for amount {$amount} for client {$this->stripe->client->present()->name()}";
|
||||
$description = ctrans('text.stripe_paymenttext_without_invoice', ['amount' => Number::formatMoney($amount, $this->stripe->client), 'client' => $this->stripe->client->present()->name()]);
|
||||
}
|
||||
|
||||
|
||||
@ -210,9 +211,9 @@ class ACH
|
||||
->first();
|
||||
|
||||
if ($invoice) {
|
||||
$description = "Invoice {$invoice->number} for {$amount} for client {$this->stripe->client->present()->name()}";
|
||||
$description = ctrans('texts.stripe_paymenttext', ['invoicenumber' => $invoice->number, 'amount' => Number::formatMoney($amount, $this->stripe->client), 'client' => $this->stripe->client->present()->name()]);
|
||||
} else {
|
||||
$description = "Payment with no invoice for amount {$amount} for client {$this->stripe->client->present()->name()}";
|
||||
$description = ctrans('text.stripe_paymenttext_without_invoice', ['amount' => Number::formatMoney($amount, $this->stripe->client), 'client' => $this->stripe->client->present()->name()]);
|
||||
}
|
||||
|
||||
if (substr($cgt->token, 0, 2) === 'pm') {
|
||||
@ -454,9 +455,9 @@ class ACH
|
||||
->first();
|
||||
|
||||
if ($invoice) {
|
||||
$description = "Invoice {$invoice->number} for {$amount} for client {$this->stripe->client->present()->name()}";
|
||||
$description = ctrans('texts.stripe_paymenttext', ['invoicenumber' => $invoice->number, 'amount' => Number::formatMoney($amount, $this->stripe->client), 'client' => $this->stripe->client->present()->name()]);
|
||||
} else {
|
||||
$description = "Payment with no invoice for amount {$amount} for client {$this->stripe->client->present()->name()}";
|
||||
$description = ctrans('text.stripe_paymenttext_without_invoice', ['amount' => Number::formatMoney($amount, $this->stripe->client), 'client' => $this->stripe->client->present()->name()]);
|
||||
}
|
||||
|
||||
if (substr($source->token, 0, 2) === 'pm') {
|
||||
|
@ -32,6 +32,7 @@ use Stripe\Exception\CardException;
|
||||
use Stripe\Exception\InvalidRequestException;
|
||||
use Stripe\Exception\RateLimitException;
|
||||
use Stripe\StripeClient;
|
||||
use App\Utils\Number;
|
||||
|
||||
class Charge
|
||||
{
|
||||
@ -62,9 +63,9 @@ class Charge
|
||||
$invoice = Invoice::whereIn('id', $this->transformKeys(array_column($payment_hash->invoices(), 'invoice_id')))->withTrashed()->first();
|
||||
|
||||
if ($invoice) {
|
||||
$description = "Invoice {$invoice->number} for {$amount} for client {$this->stripe->client->present()->name()}";
|
||||
$description = ctrans('texts.stripe_paymenttext', ['invoicenumber' => $invoice->number, 'amount' => Number::formatMoney($amount, $this->stripe->client), 'client' => $this->stripe->client->present()->name()]);
|
||||
} else {
|
||||
$description = "Payment with no invoice for amount {$amount} for client {$this->stripe->client->present()->name()}";
|
||||
$description = ctrans('text.stripe_paymenttext_without_invoice', ['amount' => Number::formatMoney($amount, $this->stripe->client), 'client' => $this->stripe->client->present()->name()]);
|
||||
}
|
||||
|
||||
$this->stripe->init();
|
||||
|
@ -23,6 +23,7 @@ use App\PaymentDrivers\StripePaymentDriver;
|
||||
use App\PaymentDrivers\Stripe\Jobs\UpdateCustomer;
|
||||
use Stripe\PaymentIntent;
|
||||
use Stripe\PaymentMethod;
|
||||
use App\Utils\Number;
|
||||
|
||||
class CreditCard
|
||||
{
|
||||
@ -62,7 +63,7 @@ class CreditCard
|
||||
|
||||
// $description = $this->stripe->decodeUnicodeString(ctrans('texts.invoices') . ': ' . collect($data['invoices'])->pluck('invoice_number')) . " for client {$this->stripe->client->present()->name()}";
|
||||
$invoice_numbers = collect($data['invoices'])->pluck('invoice_number')->implode(',');
|
||||
$description = "Invoices: {$invoice_numbers} for {$data['total']['amount_with_fee']} for client {$this->stripe->client->present()->name()}";
|
||||
$description = ctrans('texts.stripe_paymenttext', ['invoicenumber' => $invoice_numbers, 'amount' => Number::formatMoney($data['total']['amount_with_fee'], $this->stripe->client), 'client' => $this->stripe->client->present()->name()]);
|
||||
|
||||
$payment_intent_data = [
|
||||
'amount' => $this->stripe->convertToStripeAmount($data['total']['amount_with_fee'], $this->stripe->client->currency()->precision, $this->stripe->client->currency()),
|
||||
|
@ -66,11 +66,9 @@ class PaymentIntentWebhook implements ShouldQueue
|
||||
{
|
||||
$payment = Payment::query()
|
||||
->where('company_id', $company->id)
|
||||
->where(function ($query) use ($transaction) {
|
||||
$query->where('transaction_reference', $transaction['payment_intent'])
|
||||
->orWhere('transaction_reference', $transaction['id']);
|
||||
})
|
||||
->where('transaction_reference', $transaction['payment_intent'])
|
||||
->first();
|
||||
|
||||
}
|
||||
else
|
||||
{
|
||||
|
@ -56,6 +56,8 @@ class ClientRepository extends BaseRepository
|
||||
*/
|
||||
public function save(array $data, Client $client) : ?Client
|
||||
{
|
||||
$contact_data = $data;
|
||||
unset($data['contacts']);
|
||||
|
||||
/* When uploading documents, only the document array is sent, so we must return early*/
|
||||
if (array_key_exists('documents', $data) && count($data['documents']) >= 1) {
|
||||
@ -67,7 +69,7 @@ class ClientRepository extends BaseRepository
|
||||
$client->fill($data);
|
||||
|
||||
if (array_key_exists('settings', $data)) {
|
||||
$client->saveSettings($data['settings'], $client);
|
||||
$client->settings = $client->saveSettings($data['settings'], $client);
|
||||
}
|
||||
|
||||
if (! $client->country_id) {
|
||||
@ -75,19 +77,9 @@ class ClientRepository extends BaseRepository
|
||||
$client->country_id = $company->settings->country_id;
|
||||
}
|
||||
|
||||
try{
|
||||
$client->save();
|
||||
}
|
||||
catch(\Exception $e) {
|
||||
|
||||
nlog("client save failed");
|
||||
nlog($data);
|
||||
|
||||
}
|
||||
$client->save();
|
||||
|
||||
if (! isset($client->number) || empty($client->number) || strlen($client->number) == 0) {
|
||||
// $client->number = $this->getNextClientNumber($client);
|
||||
// $client->save();
|
||||
|
||||
$x = 1;
|
||||
|
||||
@ -111,7 +103,7 @@ class ClientRepository extends BaseRepository
|
||||
$data['name'] = $client->present()->name();
|
||||
}
|
||||
|
||||
$this->contact_repo->save($data, $client);
|
||||
$this->contact_repo->save($contact_data, $client);
|
||||
|
||||
return $client;
|
||||
}
|
||||
|
@ -44,11 +44,12 @@ class HandleRestore extends AbstractService
|
||||
return $this->invoice;
|
||||
}
|
||||
|
||||
//determine whether we need to un-delete payments OR just modify the payment amount /applied balances.
|
||||
|
||||
//cannot restore an invoice with a deleted payment
|
||||
foreach ($this->invoice->payments as $payment) {
|
||||
//restore the payment record
|
||||
$this->invoice->restore();
|
||||
|
||||
if(($this->invoice->paid_to_date == 0) && $payment->is_deleted)
|
||||
return $this->invoice;
|
||||
|
||||
}
|
||||
|
||||
//adjust ledger balance
|
||||
@ -56,8 +57,7 @@ class HandleRestore extends AbstractService
|
||||
|
||||
$this->invoice->client
|
||||
->service()
|
||||
->updateBalance($this->invoice->balance)
|
||||
->updatePaidToDate($this->invoice->paid_to_date)
|
||||
->updateBalanceAndPaidToDate($this->invoice->balance,$this->invoice->paid_to_date)
|
||||
->save();
|
||||
|
||||
$this->windBackInvoiceNumber();
|
||||
@ -120,11 +120,11 @@ class HandleRestore extends AbstractService
|
||||
|
||||
if ($this->adjustment_amount == $this->total_payments) {
|
||||
$this->invoice->payments()->update(['payments.deleted_at' => null, 'payments.is_deleted' => false]);
|
||||
} else {
|
||||
}
|
||||
|
||||
//adjust payments down by the amount applied to the invoice payment.
|
||||
|
||||
$this->invoice->payments->each(function ($payment) {
|
||||
$this->invoice->payments->fresh()->each(function ($payment) {
|
||||
$payment_adjustment = $payment->paymentables
|
||||
->where('paymentable_type', '=', 'invoices')
|
||||
->where('paymentable_id', $this->invoice->id)
|
||||
@ -141,8 +141,7 @@ class HandleRestore extends AbstractService
|
||||
$payment->restore();
|
||||
$payment->save();
|
||||
});
|
||||
}
|
||||
|
||||
|
||||
return $this;
|
||||
}
|
||||
|
||||
|
@ -53,16 +53,6 @@ class MarkInvoiceDeleted extends AbstractService
|
||||
->adjustPaidToDateAndBalance()
|
||||
->adjustLedger();
|
||||
|
||||
$transaction = [
|
||||
'invoice' => $this->invoice->transaction_event(),
|
||||
'payment' => $this->invoice->payments()->exists() ? $this->invoice->payments()->first()->transaction_event() : [],
|
||||
'client' => $this->invoice->client->transaction_event(),
|
||||
'credit' => [],
|
||||
'metadata' => ['total_payments' => $this->total_payments, 'balance_adjustment' => $this->balance_adjustment, 'adjustment_amount' => $this->adjustment_amount],
|
||||
];
|
||||
|
||||
// TransactionLog::dispatch(TransactionEvent::INVOICE_DELETED, $transaction, $this->invoice->company->db);
|
||||
|
||||
return $this->invoice;
|
||||
}
|
||||
|
||||
@ -87,26 +77,17 @@ class MarkInvoiceDeleted extends AbstractService
|
||||
return $this;
|
||||
}
|
||||
|
||||
// @deprecated
|
||||
private function adjustBalance()
|
||||
{
|
||||
// $client = $this->invoice->client->fresh();
|
||||
// $client->balance += $this->balance_adjustment * -1;
|
||||
// $client->save();
|
||||
|
||||
// $this->invoice->client->service()->updateBalance($this->balance_adjustment * -1)->save(); //reduces the client balance by the invoice amount.
|
||||
|
||||
return $this;
|
||||
}
|
||||
|
||||
/* Adjust the payment amounts */
|
||||
private function adjustPayments()
|
||||
{
|
||||
//if total payments = adjustment amount - that means we need to delete the payments as well.
|
||||
|
||||
if ($this->adjustment_amount == $this->total_payments) {
|
||||
nlog($this->adjustment_amount);
|
||||
nlog($this->total_payments);
|
||||
|
||||
if ($this->adjustment_amount == $this->total_payments)
|
||||
$this->invoice->payments()->update(['payments.deleted_at' => now(), 'payments.is_deleted' => true]);
|
||||
} else {
|
||||
|
||||
|
||||
//adjust payments down by the amount applied to the invoice payment.
|
||||
|
||||
@ -125,7 +106,7 @@ class MarkInvoiceDeleted extends AbstractService
|
||||
$payment->applied -= $payment_adjustment;
|
||||
$payment->save();
|
||||
});
|
||||
}
|
||||
|
||||
|
||||
return $this;
|
||||
}
|
||||
|
@ -28,6 +28,6 @@ class NinjaPdf
|
||||
RequestOptions::JSON => ['html' => $html],
|
||||
]);
|
||||
|
||||
return $response->getBody();
|
||||
return $response->getBody()->getContents();
|
||||
}
|
||||
}
|
||||
|
@ -30,7 +30,7 @@ trait ClientGroupSettingsSaver
|
||||
* Saves a setting object.
|
||||
*
|
||||
* Works for groups|clients|companies
|
||||
* @param array $settings The request input settings array
|
||||
* @param array|object $settings The request input settings array
|
||||
* @param object $entity The entity which the settings belongs to
|
||||
* @return void
|
||||
*/
|
||||
@ -64,19 +64,6 @@ trait ClientGroupSettingsSaver
|
||||
$entity_settings->{$key} = $value;
|
||||
}
|
||||
|
||||
$entity->settings = $entity_settings;
|
||||
|
||||
try{
|
||||
$entity->save();
|
||||
}
|
||||
catch(\Exception $e){
|
||||
|
||||
nlog("client settings failure");
|
||||
nlog($entity_settings);
|
||||
nlog($e->getMessage());
|
||||
|
||||
}
|
||||
|
||||
return $entity_settings;
|
||||
}
|
||||
|
||||
|
@ -14,8 +14,8 @@ return [
|
||||
'require_https' => env('REQUIRE_HTTPS', true),
|
||||
'app_url' => rtrim(env('APP_URL', ''), '/'),
|
||||
'app_domain' => env('APP_DOMAIN', 'invoicing.co'),
|
||||
'app_version' => '5.5.43',
|
||||
'app_tag' => '5.5.43',
|
||||
'app_version' => '5.5.44',
|
||||
'app_tag' => '5.5.44',
|
||||
'minimum_client_version' => '5.0.16',
|
||||
'terms_version' => '1.0.1',
|
||||
'api_secret' => env('API_SECRET', ''),
|
||||
|
@ -254,6 +254,8 @@ $LANG = array(
|
||||
'notification_invoice_paid' => 'A payment of :amount was made by client :client towards Invoice :invoice.',
|
||||
'notification_invoice_sent' => 'The following client :client was emailed Invoice :invoice for :amount.',
|
||||
'notification_invoice_viewed' => 'The following client :client viewed Invoice :invoice for :amount.',
|
||||
'stripe_paymenttext' => 'Invoice :invoicenumber for :amount for client :client',
|
||||
'stripe_paymenttext_without_invoice' => 'Payment with no invoice for amount :amount for client :client',
|
||||
'reset_password' => 'You can reset your account password by clicking the following button:',
|
||||
'secure_payment' => 'Secure Payment',
|
||||
'card_number' => 'Card Number',
|
||||
@ -4061,7 +4063,7 @@ $LANG = array(
|
||||
'save_payment_method_details' => 'Save payment method details',
|
||||
'new_card' => 'New card',
|
||||
'new_bank_account' => 'New bank account',
|
||||
'company_limit_reached' => 'Limit of 10 companies per account.',
|
||||
'company_limit_reached' => 'Limit of :limit companies per account.',
|
||||
'credits_applied_validation' => 'Total credits applied cannot be MORE than total of invoices',
|
||||
'credit_number_taken' => 'Credit number already taken',
|
||||
'credit_not_found' => 'Credit not found',
|
||||
|
@ -11,12 +11,20 @@
|
||||
|
||||
namespace Tests\Feature;
|
||||
|
||||
use App\DataMapper\ClientSettings;
|
||||
use App\Factory\ClientFactory;
|
||||
use App\Http\Requests\Client\StoreClientRequest;
|
||||
use App\Models\Client;
|
||||
use App\Models\Country;
|
||||
use App\Repositories\ClientContactRepository;
|
||||
use App\Repositories\ClientRepository;
|
||||
use App\Utils\Number;
|
||||
use App\Utils\Traits\ClientGroupSettingsSaver;
|
||||
use App\Utils\Traits\MakesHash;
|
||||
use Illuminate\Database\Eloquent\Model;
|
||||
use Illuminate\Foundation\Testing\DatabaseTransactions;
|
||||
use Illuminate\Support\Facades\Session;
|
||||
use Illuminate\Support\Facades\Validator;
|
||||
use Illuminate\Validation\ValidationException;
|
||||
use Tests\MockAccountData;
|
||||
use Tests\TestCase;
|
||||
@ -30,6 +38,7 @@ class ClientApiTest extends TestCase
|
||||
use MakesHash;
|
||||
use DatabaseTransactions;
|
||||
use MockAccountData;
|
||||
use ClientGroupSettingsSaver;
|
||||
|
||||
protected function setUp() :void
|
||||
{
|
||||
@ -44,6 +53,302 @@ class ClientApiTest extends TestCase
|
||||
Model::reguard();
|
||||
}
|
||||
|
||||
public function testCsvImportRepositoryPersistance()
|
||||
{
|
||||
Client::unguard();
|
||||
|
||||
$data = [
|
||||
'company_id' => $this->company->id,
|
||||
'name' => 'Christian xx',
|
||||
'phone' => '',
|
||||
'address1' => '',
|
||||
'address2' => '',
|
||||
'postal_code' => '',
|
||||
'city' => '',
|
||||
'state' => '',
|
||||
'shipping_address1' => '',
|
||||
'shipping_address2' => '',
|
||||
'shipping_city' => '',
|
||||
'shipping_state' => '',
|
||||
'shipping_postal_code' => '',
|
||||
'public_notes' => '',
|
||||
'private_notes' => '',
|
||||
'website' => '',
|
||||
'vat_number' => '',
|
||||
'id_number' => '',
|
||||
'custom_value1' => '',
|
||||
'custom_value2' => '',
|
||||
'custom_value3' => '',
|
||||
'custom_value4' => '',
|
||||
'balance' => '0',
|
||||
'paid_to_date' => '0',
|
||||
'credit_balance' => 0,
|
||||
'settings' => [
|
||||
'entity' => 'App\\Models\\Client',
|
||||
'currency_id' => '3',
|
||||
],
|
||||
'client_hash' => 'xx',
|
||||
'contacts' =>
|
||||
[
|
||||
[
|
||||
'first_name' => '',
|
||||
'last_name' => '',
|
||||
'email' => '',
|
||||
'phone' => '',
|
||||
'custom_value1' => '',
|
||||
'custom_value2' => '',
|
||||
'custom_value3' => '',
|
||||
'custom_value4' => '',
|
||||
]
|
||||
],
|
||||
'country_id' => NULL,
|
||||
'shipping_country_id' => NULL,
|
||||
'user_id' => $this->user->id,
|
||||
];
|
||||
|
||||
$repository_name = ClientRepository::class;
|
||||
$factory_name = ClientFactory::class;
|
||||
|
||||
$repository = app()->make($repository_name);
|
||||
$repository->import_mode = true;
|
||||
|
||||
$c = $repository->save(array_diff_key($data, ['user_id' => false]), ClientFactory::create($this->company->id, $this->user->id));
|
||||
|
||||
Client::reguard();
|
||||
|
||||
$c->refresh();
|
||||
|
||||
$this->assertEquals("3", $c->settings->currency_id);
|
||||
|
||||
}
|
||||
|
||||
public function testClientSettingsSave()
|
||||
{
|
||||
|
||||
$std = new \stdClass;
|
||||
$std->entity = 'App\\Models\\Client';
|
||||
$std->currency_id = 3;
|
||||
|
||||
$this->settings = $this->client->settings;
|
||||
|
||||
$this->saveSettings($std, $this->client);
|
||||
|
||||
$this->assertTrue(true);
|
||||
|
||||
}
|
||||
|
||||
|
||||
public function testClientSettingsSave2()
|
||||
{
|
||||
|
||||
$std = new \stdClass;
|
||||
$std->entity = 'App\\Models\\Client';
|
||||
$std->industry_id = '';
|
||||
$std->size_id = '';
|
||||
$std->currency_id = 3;
|
||||
|
||||
$this->settings = $this->client->settings;
|
||||
|
||||
$this->saveSettings($std, $this->client);
|
||||
|
||||
$this->assertTrue(true);
|
||||
|
||||
}
|
||||
|
||||
public function testClientStoreValidation()
|
||||
{
|
||||
|
||||
auth()->login($this->user, false);
|
||||
auth()->user()->setCompany($this->company);
|
||||
|
||||
$data = array (
|
||||
'company_id' => $this->company->id,
|
||||
'name' => 'Christian xx',
|
||||
'phone' => '',
|
||||
'address1' => '',
|
||||
'address2' => '',
|
||||
'postal_code' => '',
|
||||
'city' => '',
|
||||
'state' => '',
|
||||
'shipping_address1' => '',
|
||||
'shipping_address2' => '',
|
||||
'shipping_city' => '',
|
||||
'shipping_state' => '',
|
||||
'shipping_postal_code' => '',
|
||||
'public_notes' => '',
|
||||
'private_notes' => '',
|
||||
'website' => '',
|
||||
'vat_number' => '',
|
||||
'id_number' => '',
|
||||
'custom_value1' => '',
|
||||
'custom_value2' => '',
|
||||
'custom_value3' => '',
|
||||
'custom_value4' => '',
|
||||
'balance' => '0',
|
||||
'paid_to_date' => '0',
|
||||
'credit_balance' => 0,
|
||||
'settings' =>
|
||||
(object) array(
|
||||
'entity' => 'App\\Models\\Client',
|
||||
'currency_id' => '3',
|
||||
),
|
||||
'client_hash' => 'xx',
|
||||
'contacts' =>
|
||||
array (
|
||||
0 =>
|
||||
array (
|
||||
'first_name' => '',
|
||||
'last_name' => '',
|
||||
'email' => '',
|
||||
'phone' => '',
|
||||
'custom_value1' => '',
|
||||
'custom_value2' => '',
|
||||
'custom_value3' => '',
|
||||
'custom_value4' => '',
|
||||
),
|
||||
),
|
||||
'country_id' => NULL,
|
||||
'shipping_country_id' => NULL,
|
||||
'user_id' => $this->user->id,
|
||||
);
|
||||
|
||||
|
||||
$request_name = StoreClientRequest::class;
|
||||
$repository_name = ClientRepository::class;
|
||||
$factory_name = ClientFactory::class;
|
||||
|
||||
$repository = app()->make($repository_name);
|
||||
$repository->import_mode = true;
|
||||
|
||||
$_syn_request_class = new $request_name;
|
||||
$_syn_request_class->setContainer(app());
|
||||
$_syn_request_class->initialize($data);
|
||||
$_syn_request_class->prepareForValidation();
|
||||
|
||||
$validator = Validator::make($_syn_request_class->all(), $_syn_request_class->rules());
|
||||
|
||||
$_syn_request_class->setValidator($validator);
|
||||
|
||||
$this->assertFalse($validator->fails());
|
||||
|
||||
|
||||
}
|
||||
|
||||
|
||||
|
||||
public function testClientImportDataStructure()
|
||||
{
|
||||
|
||||
|
||||
$data = array (
|
||||
'company_id' => $this->company->id,
|
||||
'name' => 'Christian xx',
|
||||
'phone' => '',
|
||||
'address1' => '',
|
||||
'address2' => '',
|
||||
'postal_code' => '',
|
||||
'city' => '',
|
||||
'state' => '',
|
||||
'shipping_address1' => '',
|
||||
'shipping_address2' => '',
|
||||
'shipping_city' => '',
|
||||
'shipping_state' => '',
|
||||
'shipping_postal_code' => '',
|
||||
'public_notes' => '',
|
||||
'private_notes' => '',
|
||||
'website' => '',
|
||||
'vat_number' => '',
|
||||
'id_number' => '',
|
||||
'custom_value1' => '',
|
||||
'custom_value2' => '',
|
||||
'custom_value3' => '',
|
||||
'custom_value4' => '',
|
||||
'balance' => '0',
|
||||
'paid_to_date' => '0',
|
||||
'credit_balance' => 0,
|
||||
'settings' =>
|
||||
(object) array(
|
||||
'entity' => 'App\\Models\\Client',
|
||||
'currency_id' => '3',
|
||||
),
|
||||
'client_hash' => 'xx',
|
||||
'contacts' =>
|
||||
array (
|
||||
0 =>
|
||||
array (
|
||||
'first_name' => '',
|
||||
'last_name' => '',
|
||||
'email' => '',
|
||||
'phone' => '',
|
||||
'custom_value1' => '',
|
||||
'custom_value2' => '',
|
||||
'custom_value3' => '',
|
||||
'custom_value4' => '',
|
||||
),
|
||||
),
|
||||
'country_id' => NULL,
|
||||
'shipping_country_id' => NULL,
|
||||
'user_id' => $this->user->id,
|
||||
);
|
||||
|
||||
$crepo = new ClientRepository(new ClientContactRepository());
|
||||
|
||||
$c = $crepo->save(array_diff_key($data, ['user_id' => false]), ClientFactory::create($this->company->id, $this->user->id));
|
||||
$c->saveQuietly();
|
||||
|
||||
$this->assertEquals('Christian xx', $c->name);
|
||||
$this->assertEquals('3', $c->settings->currency_id);
|
||||
}
|
||||
|
||||
public function testClientCsvImport()
|
||||
{
|
||||
|
||||
$settings = ClientSettings::defaults();
|
||||
$settings->currency_id = "840";
|
||||
|
||||
$data = [
|
||||
'name' => $this->faker->firstName(),
|
||||
'id_number' => 'Coolio',
|
||||
'settings' => (array)$settings,
|
||||
'contacts' => [
|
||||
[
|
||||
'first_name' => '',
|
||||
'last_name' => '',
|
||||
'email' => '',
|
||||
'phone' => '',
|
||||
'custom_value1' => '',
|
||||
'custom_value2' => '',
|
||||
'custom_value3' => '',
|
||||
'custom_value4' => '',
|
||||
]
|
||||
]
|
||||
];
|
||||
|
||||
$response = false;
|
||||
|
||||
try {
|
||||
$response = $this->withHeaders([
|
||||
'X-API-SECRET' => config('ninja.api_secret'),
|
||||
'X-API-TOKEN' => $this->token,
|
||||
])->post('/api/v1/clients/', $data);
|
||||
} catch (ValidationException $e) {
|
||||
$message = json_decode($e->validator->getMessageBag(), 1);
|
||||
nlog($message);
|
||||
}
|
||||
|
||||
$response->assertStatus(200);
|
||||
|
||||
$crepo = new ClientRepository(new ClientContactRepository());
|
||||
|
||||
$c = $crepo->save($data, ClientFactory::create($this->company->id, $this->user->id));
|
||||
$c->saveQuietly();
|
||||
|
||||
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
public function testIllegalPropertiesInClientSettings()
|
||||
{
|
||||
$settings = [
|
||||
|
@ -162,6 +162,7 @@ class DeleteInvoiceTest extends TestCase
|
||||
$payment = $payment->fresh();
|
||||
|
||||
$this->assertTrue($payment->is_deleted);
|
||||
$this->assertEquals(0, $payment->amount);
|
||||
$this->assertEquals(4, $payment->status_id);
|
||||
|
||||
$client->fresh();
|
||||
|
Loading…
x
Reference in New Issue
Block a user