Merge pull request #9209 from turbo124/v5-develop

Adjustments for logic for sending payment emails
This commit is contained in:
David Bomba 2024-01-29 14:04:36 +11:00 committed by GitHub
commit f18ac57545
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194
23 changed files with 173 additions and 42 deletions

View File

@ -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);
}
}
}

View File

@ -131,6 +131,10 @@ class ClientExport extends BaseExport
$query = $this->addDateRange($query);
if($this->input['document_email_attachment'] ?? false) {
$this->queueDocuments($query);
}
return $query;
}

View File

@ -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;
}

View File

@ -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;

View File

@ -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;

View File

@ -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;
}
}

View File

@ -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);

View File

@ -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;
}

View File

@ -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;

View File

@ -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;

View File

@ -67,6 +67,10 @@ class PurchaseOrderItemExport extends BaseExport
$query = $this->addDateRange($query);
if($this->input['document_email_attachment'] ?? false) {
$this->queueDocuments($query);
}
return $query;
}

View File

@ -69,6 +69,10 @@ class QuoteExport extends BaseExport
$query = $this->addDateRange($query);
if($this->input['document_email_attachment'] ?? false) {
$this->queueDocuments($query);
}
return $query;
}

View File

@ -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;

View File

@ -72,6 +72,10 @@ class TaskExport extends BaseExport
$query = $this->addDateRange($query);
if($this->input['document_email_attachment'] ?? false) {
$this->queueDocuments($query);
}
return $query;
}

View File

@ -66,6 +66,10 @@ class VendorExport extends BaseExport
$query = $this->addDateRange($query);
if($this->input['document_email_attachment'] ?? false) {
$this->queueDocuments($query);
}
return $query;
}

View File

@ -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);
}
}

View File

@ -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.
*/

View File

@ -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');

View File

@ -48,8 +48,6 @@ class PreviewReport implements ShouldQueue
$report = $export->run();
}
// nlog($report);
Cache::put($this->hash, $report, 60 * 60);
}

View File

@ -254,7 +254,7 @@ class ClientContact extends Authenticatable implements HasLocalePreference
{
return $this->hasMany(CreditInvitation::class);
}
public function sendPasswordResetNotification($token)
{
$this->token = $token;

View File

@ -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);

View File

@ -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();
}
}
});
}

View File

@ -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'));
}
}