mirror of
https://github.com/invoiceninja/invoiceninja.git
synced 2025-07-07 17:44:29 -04:00
Merge pull request #9209 from turbo124/v5-develop
Adjustments for logic for sending payment emails
This commit is contained in:
commit
f18ac57545
@ -11,27 +11,29 @@
|
||||
|
||||
namespace App\Export\CSV;
|
||||
|
||||
use App\Models\Task;
|
||||
use App\Models\User;
|
||||
use App\Models\Quote;
|
||||
use App\Models\Client;
|
||||
use App\Models\ClientContact;
|
||||
use App\Models\Company;
|
||||
use App\Models\Credit;
|
||||
use App\Models\Document;
|
||||
use App\Models\Vendor;
|
||||
use App\Utils\Helpers;
|
||||
use App\Models\Company;
|
||||
use App\Models\Expense;
|
||||
use App\Models\Invoice;
|
||||
use App\Models\Payment;
|
||||
use App\Models\Product;
|
||||
use App\Models\PurchaseOrder;
|
||||
use App\Models\Quote;
|
||||
use App\Models\RecurringInvoice;
|
||||
use App\Models\Task;
|
||||
use App\Models\Vendor;
|
||||
use App\Transformers\PaymentTransformer;
|
||||
use App\Transformers\TaskTransformer;
|
||||
use App\Utils\Helpers;
|
||||
use App\Utils\Traits\MakesHash;
|
||||
use Illuminate\Database\Eloquent\Builder;
|
||||
use Illuminate\Support\Carbon;
|
||||
use App\Models\Document;
|
||||
use League\Fractal\Manager;
|
||||
use App\Models\ClientContact;
|
||||
use App\Models\PurchaseOrder;
|
||||
use Illuminate\Support\Carbon;
|
||||
use App\Utils\Traits\MakesHash;
|
||||
use App\Models\RecurringInvoice;
|
||||
use App\Jobs\Document\ZipDocuments;
|
||||
use App\Transformers\TaskTransformer;
|
||||
use App\Transformers\PaymentTransformer;
|
||||
use Illuminate\Database\Eloquent\Builder;
|
||||
use League\Fractal\Serializer\ArraySerializer;
|
||||
|
||||
class BaseExport
|
||||
@ -1258,4 +1260,32 @@ class BaseExport
|
||||
return $clean_row;
|
||||
}
|
||||
|
||||
public function queueDocuments(Builder $query)
|
||||
{
|
||||
|
||||
if($query->getModel() instanceof Document)
|
||||
$documents = $query->pluck('id')->toArray();
|
||||
else{
|
||||
$documents = $query->cursor()
|
||||
->map(function ($entity){
|
||||
return $entity->documents()->pluck('id')->toArray();
|
||||
})->flatten()
|
||||
->toArray();
|
||||
}
|
||||
|
||||
nlog($documents);
|
||||
if(count($documents) > 0) {
|
||||
|
||||
$user = $this->company->owner();
|
||||
|
||||
if(auth()->user() && auth()->user()->account_id == $this->company->account_id)
|
||||
$user = auth()->user();
|
||||
|
||||
if($this->input['user_id'])
|
||||
$user = User::where('id', $this->input['user_id'])->where('account_id', $this->company->account_id)->first();
|
||||
|
||||
ZipDocuments::dispatch($documents, $this->company, $user);
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
@ -131,6 +131,10 @@ class ClientExport extends BaseExport
|
||||
|
||||
$query = $this->addDateRange($query);
|
||||
|
||||
if($this->input['document_email_attachment'] ?? false) {
|
||||
$this->queueDocuments($query);
|
||||
}
|
||||
|
||||
return $query;
|
||||
|
||||
}
|
||||
|
@ -106,6 +106,10 @@ class CreditExport extends BaseExport
|
||||
->where('is_deleted', 0);
|
||||
|
||||
$query = $this->addDateRange($query);
|
||||
|
||||
if($this->input['document_email_attachment'] ?? false) {
|
||||
$this->queueDocuments($query);
|
||||
}
|
||||
|
||||
return $query;
|
||||
}
|
||||
|
@ -77,6 +77,10 @@ class DocumentExport extends BaseExport
|
||||
$query = Document::query()->where('company_id', $this->company->id);
|
||||
|
||||
$query = $this->addDateRange($query);
|
||||
|
||||
if($this->input['document_email_attachment'] ?? false) {
|
||||
$this->queueDocuments($query);
|
||||
}
|
||||
|
||||
return $query;
|
||||
|
||||
|
@ -103,6 +103,10 @@ class ExpenseExport extends BaseExport
|
||||
if(isset($this->input['categories'])) {
|
||||
$query = $this->addCategoryFilter($query, $this->input['categories']);
|
||||
}
|
||||
|
||||
if($this->input['document_email_attachment'] ?? false) {
|
||||
$this->queueDocuments($query);
|
||||
}
|
||||
|
||||
return $query;
|
||||
|
||||
|
@ -62,10 +62,14 @@ class InvoiceExport extends BaseExport
|
||||
|
||||
$query = $this->addDateRange($query);
|
||||
|
||||
if(isset($this->input['status'])) {
|
||||
if($this->input['status'] ?? false) {
|
||||
$query = $this->addInvoiceStatusFilter($query, $this->input['status']);
|
||||
}
|
||||
|
||||
if($this->input['document_email_attachment'] ?? false) {
|
||||
$this->queueDocuments($query);
|
||||
}
|
||||
|
||||
return $query;
|
||||
|
||||
}
|
||||
@ -120,15 +124,11 @@ class InvoiceExport extends BaseExport
|
||||
if (is_array($parts) && $parts[0] == 'invoice' && array_key_exists($parts[1], $transformed_invoice)) {
|
||||
$entity[$key] = $transformed_invoice[$parts[1]];
|
||||
} else {
|
||||
// nlog($key);
|
||||
$entity[$key] = $this->decorator->transform($key, $invoice);
|
||||
// $entity[$key] = '';
|
||||
// $entity[$key] = $this->resolveKey($key, $invoice, $this->invoice_transformer);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
// return $entity;
|
||||
return $this->decorateAdvancedFields($invoice, $entity);
|
||||
}
|
||||
|
||||
@ -167,7 +167,6 @@ class InvoiceExport extends BaseExport
|
||||
$entity['invoice.user_id'] = $invoice->user ? $invoice->user->present()->name() : '';
|
||||
}
|
||||
|
||||
nlog($entity);
|
||||
return $entity;
|
||||
}
|
||||
}
|
||||
|
@ -76,6 +76,10 @@ class InvoiceItemExport extends BaseExport
|
||||
$query = $this->addDateRange($query);
|
||||
|
||||
$query = $this->applyFilters($query);
|
||||
|
||||
if($this->input['document_email_attachment'] ?? false) {
|
||||
$this->queueDocuments($query);
|
||||
}
|
||||
|
||||
return $query;
|
||||
|
||||
@ -91,7 +95,6 @@ class InvoiceItemExport extends BaseExport
|
||||
return ['identifier' => $key, 'display_value' => $headerdisplay[$value]];
|
||||
})->toArray();
|
||||
|
||||
|
||||
$query->cursor()
|
||||
->each(function ($resource) {
|
||||
$this->iterateItems($resource);
|
||||
|
@ -60,6 +60,10 @@ class PaymentExport extends BaseExport
|
||||
->where('is_deleted', 0);
|
||||
|
||||
$query = $this->addDateRange($query);
|
||||
|
||||
if($this->input['document_email_attachment'] ?? false) {
|
||||
$this->queueDocuments($query);
|
||||
}
|
||||
|
||||
return $query;
|
||||
}
|
||||
|
@ -77,6 +77,10 @@ class ProductExport extends BaseExport
|
||||
->where('is_deleted', 0);
|
||||
|
||||
$query = $this->addDateRange($query);
|
||||
|
||||
if($this->input['document_email_attachment'] ?? false) {
|
||||
$this->queueDocuments($query);
|
||||
}
|
||||
|
||||
return $query;
|
||||
|
||||
|
@ -107,6 +107,10 @@ class PurchaseOrderExport extends BaseExport
|
||||
->where('is_deleted', 0);
|
||||
|
||||
$query = $this->addDateRange($query);
|
||||
|
||||
if($this->input['document_email_attachment'] ?? false) {
|
||||
$this->queueDocuments($query);
|
||||
}
|
||||
|
||||
return $query;
|
||||
|
||||
|
@ -67,6 +67,10 @@ class PurchaseOrderItemExport extends BaseExport
|
||||
|
||||
$query = $this->addDateRange($query);
|
||||
|
||||
if($this->input['document_email_attachment'] ?? false) {
|
||||
$this->queueDocuments($query);
|
||||
}
|
||||
|
||||
return $query;
|
||||
|
||||
}
|
||||
|
@ -69,6 +69,10 @@ class QuoteExport extends BaseExport
|
||||
|
||||
$query = $this->addDateRange($query);
|
||||
|
||||
if($this->input['document_email_attachment'] ?? false) {
|
||||
$this->queueDocuments($query);
|
||||
}
|
||||
|
||||
return $query;
|
||||
|
||||
}
|
||||
|
@ -69,6 +69,10 @@ class QuoteItemExport extends BaseExport
|
||||
->where('is_deleted', 0);
|
||||
|
||||
$query = $this->addDateRange($query);
|
||||
|
||||
if($this->input['document_email_attachment'] ?? false) {
|
||||
$this->queueDocuments($query);
|
||||
}
|
||||
|
||||
return $query;
|
||||
|
||||
|
@ -72,6 +72,10 @@ class TaskExport extends BaseExport
|
||||
|
||||
$query = $this->addDateRange($query);
|
||||
|
||||
if($this->input['document_email_attachment'] ?? false) {
|
||||
$this->queueDocuments($query);
|
||||
}
|
||||
|
||||
return $query;
|
||||
|
||||
}
|
||||
|
@ -66,6 +66,10 @@ class VendorExport extends BaseExport
|
||||
|
||||
$query = $this->addDateRange($query);
|
||||
|
||||
if($this->input['document_email_attachment'] ?? false) {
|
||||
$this->queueDocuments($query);
|
||||
}
|
||||
|
||||
return $query;
|
||||
|
||||
}
|
||||
|
@ -37,6 +37,7 @@ class GenericReportRequest extends Request
|
||||
'start_date' => 'bail|required_if:date_range,custom|nullable|date',
|
||||
'report_keys' => 'present|array',
|
||||
'send_email' => 'required|bool',
|
||||
'document_email_attachment' => 'sometimes|bool'
|
||||
// 'status' => 'sometimes|string|nullable|in:all,draft,sent,viewed,paid,unpaid,overdue',
|
||||
];
|
||||
}
|
||||
@ -62,6 +63,8 @@ class GenericReportRequest extends Request
|
||||
$input['end_date'] = null;
|
||||
}
|
||||
|
||||
$input['user_id'] = auth()->user()->id;
|
||||
|
||||
$this->replace($input);
|
||||
}
|
||||
}
|
||||
|
@ -49,9 +49,9 @@ class ZipDocuments implements ShouldQueue
|
||||
public $tries = 1;
|
||||
|
||||
/**
|
||||
* @param $invoices
|
||||
* @param array $document_ids
|
||||
* @param Company $company
|
||||
* @param $email
|
||||
* @param User $user
|
||||
* @deprecated confirm to be deleted
|
||||
* Create a new job instance.
|
||||
*/
|
||||
|
@ -68,7 +68,7 @@ class EmailPayment implements ShouldQueue
|
||||
$this->payment->load('invoices');
|
||||
|
||||
if (!$this->contact) {
|
||||
$this->contact = $this->payment->client->contacts()->first();
|
||||
$this->contact = $this->payment->client->contacts()->orderBy('is_primary', 'desc')->first();
|
||||
}
|
||||
|
||||
$this->contact->load('client');
|
||||
|
@ -48,8 +48,6 @@ class PreviewReport implements ShouldQueue
|
||||
$report = $export->run();
|
||||
}
|
||||
|
||||
// nlog($report);
|
||||
|
||||
Cache::put($this->hash, $report, 60 * 60);
|
||||
}
|
||||
|
||||
|
@ -254,7 +254,7 @@ class ClientContact extends Authenticatable implements HasLocalePreference
|
||||
{
|
||||
return $this->hasMany(CreditInvitation::class);
|
||||
}
|
||||
|
||||
|
||||
public function sendPasswordResetNotification($token)
|
||||
{
|
||||
$this->token = $token;
|
||||
|
@ -14,22 +14,38 @@ namespace App\Services\Payment;
|
||||
use App\Jobs\Payment\EmailPayment;
|
||||
use App\Models\ClientContact;
|
||||
use App\Models\Payment;
|
||||
use Illuminate\Database\QueryException;
|
||||
|
||||
class SendEmail
|
||||
{
|
||||
public function __construct(public Payment $payment, public ?ClientContact $contact)
|
||||
{
|
||||
}
|
||||
public function __construct(public Payment $payment, public ?ClientContact $contact) {}
|
||||
|
||||
/**
|
||||
* Builds the correct template to send.
|
||||
*/
|
||||
public function run()
|
||||
{
|
||||
$this->payment->load('company', 'client.contacts', 'invoices');
|
||||
$this->payment->load('company', 'invoices');
|
||||
|
||||
if (!$this->contact) {
|
||||
$this->contact = $this->payment->client->contacts()->first();
|
||||
|
||||
if($invoice = $this->payment->invoices->first() ?? false) {
|
||||
|
||||
$invitation =
|
||||
$invoice
|
||||
->invitations()
|
||||
->whereHas("contact", function ($q) {
|
||||
$q->where('send_email', true)->orderBy("is_primary", 'ASC');
|
||||
})
|
||||
->first();
|
||||
|
||||
if($invitation) {
|
||||
$this->contact = $invitation->contact;
|
||||
} else {
|
||||
$this->contact = $this->payment->client->contacts()->orderBy('send_email', 'desc')->orderBy('is_primary', 'desc')->first();
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
EmailPayment::dispatch($this->payment, $this->payment->company, $this->contact);
|
||||
|
@ -23,9 +23,10 @@ return new class extends Migration
|
||||
Invoice::withTrashed()
|
||||
->where('is_deleted', false)
|
||||
->cursor()
|
||||
->each(function (Invoice $invoice) {
|
||||
|
||||
->each(function (Invoice $invoice) {
|
||||
|
||||
$hit = false;
|
||||
|
||||
$line_items = $invoice->line_items;
|
||||
|
||||
if(is_array($line_items))
|
||||
@ -35,14 +36,18 @@ return new class extends Migration
|
||||
|
||||
if($product = Product::where('company_id', $invoice->company_id)->where('product_key', $item->product_key)->where('cost', '>', 0)->first())
|
||||
{
|
||||
if((property_exists($item, 'product_cost') && $item->product_cost == 0) || !property_exists($item, 'product_cost'))
|
||||
if((property_exists($item, 'product_cost') && $item->product_cost == 0) || !property_exists($item, 'product_cost')){
|
||||
$hit = true;
|
||||
$line_items[$key]->product_cost = (float)$product->cost;
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
$invoice->line_items = $line_items;
|
||||
$invoice->saveQuietly();
|
||||
|
||||
if($hit){
|
||||
$invoice->line_items = $line_items;
|
||||
$invoice->saveQuietly();
|
||||
}
|
||||
}
|
||||
});
|
||||
}
|
||||
|
@ -11,10 +11,22 @@
|
||||
|
||||
namespace Tests\Unit;
|
||||
|
||||
use App\Helpers\Invoice\InvoiceSum;
|
||||
use Illuminate\Foundation\Testing\DatabaseTransactions;
|
||||
use Tests\MockAccountData;
|
||||
use Tests\TestCase;
|
||||
use App\Models\Invoice;
|
||||
use Tests\MockAccountData;
|
||||
use App\Helpers\Invoice\InvoiceSum;
|
||||
use App\Models\Client;
|
||||
use App\Models\Credit;
|
||||
use App\Models\Document;
|
||||
use App\Models\Expense;
|
||||
use App\Models\Payment;
|
||||
use App\Models\Product;
|
||||
use App\Models\Project;
|
||||
use App\Models\PurchaseOrder;
|
||||
use App\Models\Quote;
|
||||
use App\Models\Task;
|
||||
use App\Models\Vendor;
|
||||
use Illuminate\Foundation\Testing\DatabaseTransactions;
|
||||
|
||||
/**
|
||||
* @test
|
||||
@ -55,4 +67,21 @@ class EntityTest extends TestCase
|
||||
|
||||
$this->assertEquals('InvoiceInvitation', class_basename($invitation));
|
||||
}
|
||||
}
|
||||
|
||||
public function testDocumentRelationExists()
|
||||
{
|
||||
|
||||
$this->assertTrue(method_exists(Invoice::class, 'documents'));
|
||||
$this->assertTrue(method_exists(Quote::class, 'documents'));
|
||||
$this->assertTrue(method_exists(Credit::class, 'documents'));
|
||||
$this->assertTrue(method_exists(PurchaseOrder::class, 'documents'));
|
||||
$this->assertTrue(method_exists(Client::class, 'documents'));
|
||||
$this->assertTrue(method_exists(Vendor::class, 'documents'));
|
||||
$this->assertTrue(method_exists(Product::class, 'documents'));
|
||||
$this->assertTrue(method_exists(Payment::class, 'documents'));
|
||||
$this->assertTrue(method_exists(Expense::class, 'documents'));
|
||||
$this->assertTrue(method_exists(Project::class, 'documents'));
|
||||
$this->assertTrue(method_exists(Task::class, 'documents'));
|
||||
|
||||
}
|
||||
}
|
Loading…
x
Reference in New Issue
Block a user