diff --git a/app/DataMapper/EmailTemplateDefaults.php b/app/DataMapper/EmailTemplateDefaults.php
index 03e212557147..5cdc7b915c23 100644
--- a/app/DataMapper/EmailTemplateDefaults.php
+++ b/app/DataMapper/EmailTemplateDefaults.php
@@ -62,7 +62,7 @@ class EmailTemplateDefaults
case 'email_template_custom3':
return self::emailInvoiceTemplate();
case 'email_template_purchase_order':
- return self::emailPurchaseOrderSubject();
+ return self::emailPurchaseOrderTemplate();
break;
/* Subject */
@@ -157,7 +157,7 @@ class EmailTemplateDefaults
public static function emailPurchaseOrderSubject()
{
- return ctrans('texts.purchase_order_subject', ['number' => '$number']);
+ return ctrans('texts.purchase_order_subject', ['number' => '$number', 'account' => '$account']);
}
public static function emailPurchaseOrderTemplate()
diff --git a/app/Events/PurchaseOrder/PurchaseOrderWasEmailed.php b/app/Events/PurchaseOrder/PurchaseOrderWasEmailed.php
index 7836a8442636..7674039d7027 100644
--- a/app/Events/PurchaseOrder/PurchaseOrderWasEmailed.php
+++ b/app/Events/PurchaseOrder/PurchaseOrderWasEmailed.php
@@ -13,6 +13,7 @@ namespace App\Events\PurchaseOrder;
use App\Models\Company;
use App\Models\PurchaseOrder;
+use App\Models\PurchaseOrderInvitation;
use Illuminate\Queue\SerializesModels;
/**
@@ -25,7 +26,7 @@ class PurchaseOrderWasEmailed
/**
* @var PurchaseOrder
*/
- public $purchase_order;
+ public $invitation;
public $company;
@@ -38,9 +39,9 @@ class PurchaseOrderWasEmailed
* @param Company $company
* @param array $event_vars
*/
- public function __construct(PurchaseOrder $purchase_order, Company $company, array $event_vars)
+ public function __construct(PurchaseOrderInvitation $invitation, Company $company, array $event_vars)
{
- $this->purchase_order = $purchase_order;
+ $this->invitation = $invitation;
$this->company = $company;
$this->event_vars = $event_vars;
}
diff --git a/app/Http/Controllers/PurchaseOrderController.php b/app/Http/Controllers/PurchaseOrderController.php
index 61877a56d6d7..ad25c6fabe46 100644
--- a/app/Http/Controllers/PurchaseOrderController.php
+++ b/app/Http/Controllers/PurchaseOrderController.php
@@ -23,6 +23,7 @@ use App\Http\Requests\PurchaseOrder\EditPurchaseOrderRequest;
use App\Http\Requests\PurchaseOrder\ShowPurchaseOrderRequest;
use App\Http\Requests\PurchaseOrder\StorePurchaseOrderRequest;
use App\Http\Requests\PurchaseOrder\UpdatePurchaseOrderRequest;
+use App\Jobs\Invoice\PurchaseOrderEmail;
use App\Jobs\Invoice\ZipInvoices;
use App\Models\Client;
use App\Models\PurchaseOrder;
@@ -183,6 +184,7 @@ class PurchaseOrderController extends BaseController
$purchase_order = $purchase_order->service()
->fillDefaults()
+ ->triggeredActions($request)
->save();
event(new PurchaseOrderWasCreated($purchase_order, $purchase_order->company, Ninja::eventVars(auth()->user() ? auth()->user()->id : null)));
@@ -627,7 +629,7 @@ class PurchaseOrderController extends BaseController
case 'email':
//check query parameter for email_type and set the template else use calculateTemplate
-
+ PurchaseOrderEmail::dispatch($purchase_order, $purchase_order->company);
default:
return response()->json(['message' => ctrans('texts.action_unavailable', ['action' => $action])], 400);
diff --git a/app/Jobs/PurchaseOrder/PurchaseOrderEmail.php b/app/Jobs/PurchaseOrder/PurchaseOrderEmail.php
new file mode 100644
index 000000000000..d27ffdd21ae7
--- /dev/null
+++ b/app/Jobs/PurchaseOrder/PurchaseOrderEmail.php
@@ -0,0 +1,102 @@
+purchase_order = $purchase_order;
+ $this->company = $company;
+ $this->template_data = $template_data;
+ }
+
+ /**
+ * Execute the job.
+ *
+ *
+ * @return void
+ */
+ public function handle()
+ {
+ MultiDB::setDb($this->company->db);
+
+ $this->purchase_order->last_sent_date = now();
+
+ $this->purchase_order->invitations->load('contact.vendor.country', 'purchase_order.vendor.country', 'purchase_order.company')->each(function ($invitation) {
+
+ /* Don't fire emails if the company is disabled */
+ if ($this->company->is_disabled)
+ return true;
+
+ /* Set DB */
+ MultiDB::setDB($this->company->db);
+
+ App::forgetInstance('translator');
+ $t = app('translator');
+ App::setLocale($invitation->contact->preferredLocale());
+ $t->replace(Ninja::transformTranslations($this->company->settings));
+
+ /* Mark entity sent */
+ $invitation->purchase_order->service()->markSent()->save();
+
+ $email_builder = (new PurchaseOrderEmailEngine($invitation, 'purchase_order', $this->template_data))->build();
+
+ $nmo = new NinjaMailerObject;
+ $nmo->mailable = new VendorTemplateEmail($email_builder, $invitation->contact, $invitation);
+ $nmo->company = $this->company;
+ $nmo->settings = $this->company->settings;
+ $nmo->to_user = $invitation->contact;
+ $nmo->entity_string = 'purchase_order';
+ $nmo->invitation = $invitation;
+ $nmo->reminder_template = 'purchase_order';
+ $nmo->entity = $invitation->purchase_order;
+
+ NinjaMailerJob::dispatchNow($nmo);
+
+
+ });
+
+ if ($this->purchase_order->invitations->count() >= 1) {
+ event(new PurchaseOrderWasEmailed($this->purchase_order->invitations->first(), $this->purchase_order->invitations->first()->company, Ninja::eventVars(auth()->user() ? auth()->user()->id : null)));
+ }
+
+ }
+
+}
diff --git a/app/Mail/Engine/PurchaseOrderEmailEngine.php b/app/Mail/Engine/PurchaseOrderEmailEngine.php
new file mode 100644
index 000000000000..d3b2fcbad5bd
--- /dev/null
+++ b/app/Mail/Engine/PurchaseOrderEmailEngine.php
@@ -0,0 +1,207 @@
+invitation = $invitation;
+ $this->reminder_template = $reminder_template; //'purchase_order'
+ $this->vendor = $invitation->contact->vendor;
+ $this->purchase_order = $invitation->purchase_order;
+ $this->contact = $invitation->contact;
+ $this->template_data = $template_data;
+ }
+
+ public function build()
+ {
+
+ App::forgetInstance('translator');
+ $t = app('translator');
+ $t->replace(Ninja::transformTranslations($this->vendor->company->settings));
+
+ if (is_array($this->template_data) && array_key_exists('body', $this->template_data) && strlen($this->template_data['body']) > 0) {
+ $body_template = $this->template_data['body'];
+ } elseif (strlen($this->vendor->getSetting('email_template_'.$this->reminder_template)) > 0) {
+ $body_template = $this->vendor->getSetting('email_template_'.$this->reminder_template);
+ } else {
+ $body_template = EmailTemplateDefaults::getDefaultTemplate('email_template_'.$this->reminder_template, $this->vendor->company->locale());
+ }
+
+ /* Use default translations if a custom message has not been set*/
+ if (iconv_strlen($body_template) == 0) {
+ $body_template = trans(
+ 'texts.invoice_message',
+ [
+ 'invoice' => $this->purchase_order->number,
+ 'company' => $this->purchase_order->company->present()->name(),
+ 'amount' => Number::formatMoney($this->purchase_order->balance, $this->vendor),
+ ],
+ null,
+ $this->vendor->company->locale()
+ );
+
+ $body_template .= '
$view_button
';
+
+ }
+ $text_body = trans(
+ 'texts.purchase_order_message',
+ [
+ 'purchase_order' => $this->purchase_order->number,
+ 'company' => $this->purchase_order->company->present()->name(),
+ 'amount' => Number::formatMoney($this->purchase_order->balance, $this->vendor),
+ ],
+ null,
+ $this->vendor->company->locale()
+ ) . "\n\n" . $this->invitation->getLink();
+
+ if (is_array($this->template_data) && array_key_exists('subject', $this->template_data) && strlen($this->template_data['subject']) > 0) {
+ $subject_template = $this->template_data['subject'];
+ } elseif (strlen($this->vendor->getSetting('email_subject_'.$this->reminder_template)) > 0) {
+ $subject_template = $this->vendor->getSetting('email_subject_'.$this->reminder_template);
+ } else {
+ $subject_template = EmailTemplateDefaults::getDefaultTemplate('email_subject_'.$this->reminder_template, $this->vendor->company->locale());
+
+ }
+
+ if (iconv_strlen($subject_template) == 0) {
+ $subject_template = trans(
+ 'texts.purchase_order_subject',
+ [
+ 'number' => $this->purchase_order->number,
+ 'account' => $this->purchase_order->company->present()->name(),
+ ],
+ null,
+ $this->vendor->company->locale()
+ );
+ }
+
+ $this->setTemplate($this->vendor->getSetting('email_style'))
+ ->setContact($this->contact)
+ ->setVariables((new VendorHtmlEngine($this->invitation))->makeValues())//move make values into the htmlengine
+ ->setSubject($subject_template)
+ ->setBody($body_template)
+ ->setFooter("".ctrans('texts.view_purchase_order').'')
+ ->setViewLink($this->invitation->getLink())
+ ->setViewText(ctrans('texts.view_purchase_order'))
+ ->setInvitation($this->invitation)
+ ->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)]);
+
+ }
+
+ //attach third party documents
+ if($this->vendor->getSetting('document_email_attachment') !== false && $this->purchase_order->company->account->hasFeature(Account::FEATURE_DOCUMENTS)){
+
+ // Storage::url
+ foreach($this->purchase_order->documents as $document){
+ $this->setAttachments([['path' => $document->filePath(), 'name' => $document->name, 'mime' => $document->type]]);
+ }
+
+ foreach($this->purchase_order->company->documents as $document){
+ $this->setAttachments([['path' => $document->filePath(), 'name' => $document->name, 'mime' => $document->type]]);
+ }
+
+ // $line_items = $this->purchase_order->line_items;
+
+
+ // foreach($line_items as $item)
+ // {
+
+ // $expense_ids = [];
+
+ // if(property_exists($item, 'expense_id'))
+ // {
+ // $expense_ids[] = $item->expense_id;
+ // }
+
+ // if(count($expense_ids) > 0){
+
+ // $expenses = Expense::whereIn('id', $this->transformKeys($expense_ids))
+ // ->where('invoice_documents', 1)
+ // ->cursor()
+ // ->each(function ($expense){
+
+ // foreach($expense->documents as $document)
+ // {
+ // $this->setAttachments([['path' => $document->filePath(), 'name' => $document->name, 'mime' => $document->type]]);
+ // }
+
+ // });
+ // }
+
+ // $task_ids = [];
+
+ // if(property_exists($item, 'task_id'))
+ // {
+ // $task_ids[] = $item->task_id;
+ // }
+
+ // if(count($task_ids) > 0 && $this->purchase_order->company->purchase_order_task_documents){
+
+ // $tasks = Task::whereIn('id', $this->transformKeys($task_ids))
+ // ->cursor()
+ // ->each(function ($task){
+
+ // foreach($task->documents as $document)
+ // {
+ // $this->setAttachments([['path' => $document->filePath(), 'name' => $document->name, 'mime' => $document->type]]);
+ // }
+
+ // });
+ // }
+
+ // }
+
+
+ }
+
+ return $this;
+ }
+}
\ No newline at end of file
diff --git a/app/Mail/VendorTemplateEmail.php b/app/Mail/VendorTemplateEmail.php
new file mode 100644
index 000000000000..2612f90c6209
--- /dev/null
+++ b/app/Mail/VendorTemplateEmail.php
@@ -0,0 +1,132 @@
+build_email = $build_email;
+
+ $this->contact = $contact;
+
+ $this->vendor = $contact->vendor;
+
+ $this->company = $contact->company;
+
+ $this->invitation = $invitation;
+ }
+
+ public function build()
+ {
+
+ $template_name = 'email.template.'.$this->build_email->getTemplate();
+
+ if ($this->build_email->getTemplate() == 'light' || $this->build_email->getTemplate() == 'dark') {
+ $template_name = 'email.template.client';
+ }
+
+ if($this->build_email->getTemplate() == 'custom') {
+ $this->build_email->setBody(str_replace('$body', $this->build_email->getBody(), $this->client->getSetting('email_style_custom')));
+ }
+
+ $settings = $this->company->settings;
+
+ if ($this->build_email->getTemplate() !== 'custom') {
+ $this->build_email->setBody(
+ DesignHelpers::parseMarkdownToHtml($this->build_email->getBody())
+ );
+ }
+
+ if($this->invitation)
+ {
+ $html_variables = (new VendorHtmlEngine($this->invitation))->makeValues();
+ $signature = str_replace(array_keys($html_variables), array_values($html_variables), $settings->email_signature);
+ }
+ else
+ $signature = $settings->email_signature;
+
+ if(property_exists($settings, 'email_from_name') && strlen($settings->email_from_name) > 1)
+ $email_from_name = $settings->email_from_name;
+ else
+ $email_from_name = $this->company->present()->name();
+
+ $this->from(config('mail.from.address'), $email_from_name);
+
+ if (strlen($settings->bcc_email) > 1)
+ $this->bcc(explode(",",str_replace(" ", "", $settings->bcc_email)));//remove whitespace if any has been inserted.
+
+ $this->subject($this->build_email->getSubject())
+ ->text('email.template.text', [
+ 'text_body' => $this->build_email->getTextBody(),
+ 'whitelabel' => $this->vendor->user->account->isPaid() ? true : false,
+ 'settings' => $settings,
+ ])
+ ->view($template_name, [
+ 'greeting' => ctrans('texts.email_salutation', ['name' => $this->contact->present()->name()]),
+ 'body' => $this->build_email->getBody(),
+ 'footer' => $this->build_email->getFooter(),
+ 'view_link' => $this->build_email->getViewLink(),
+ 'view_text' => $this->build_email->getViewText(),
+ 'title' => '',
+ 'signature' => $signature,
+ 'settings' => $settings,
+ 'company' => $this->company,
+ 'whitelabel' => $this->vendor->user->account->isPaid() ? true : false,
+ 'logo' => $this->company->present()->logo($settings),
+ ])
+ ->withSwiftMessage(function ($message) {
+ $message->getHeaders()->addTextHeader('Tag', $this->company->company_key);
+ $message->invitation = $this->invitation;
+ });
+
+ /*In the hosted platform we need to slow things down a little for Storage to catch up.*/
+ if(Ninja::isHosted())
+ sleep(1);
+
+ 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' => $file['mime']]);
+
+ }
+
+ return $this;
+ }
+}
diff --git a/app/Models/Account.php b/app/Models/Account.php
index 8af56a3a590d..4f9f9a333e0d 100644
--- a/app/Models/Account.php
+++ b/app/Models/Account.php
@@ -57,6 +57,7 @@ class Account extends BaseModel
'utm_content',
'user_agent',
'platform',
+ // 'set_react_as_default_ap',
];
/**
diff --git a/app/Models/VendorContact.php b/app/Models/VendorContact.php
index 2f5f9447cc04..d4a4bd92f91a 100644
--- a/app/Models/VendorContact.php
+++ b/app/Models/VendorContact.php
@@ -110,7 +110,7 @@ class VendorContact extends Authenticatable implements HasLocalePreference
public function sendPasswordResetNotification($token)
{
- $this->notify(new ClientContactResetPassword($token));
+ // $this->notify(new ClientContactResetPassword($token));
}
public function preferredLocale()
@@ -118,12 +118,9 @@ class VendorContact extends Authenticatable implements HasLocalePreference
$languages = Cache::get('languages');
return $languages->filter(function ($item) {
- return $item->id == $this->client->getSetting('language_id');
+ return $item->id == $this->company->getSetting('language_id');
})->first()->locale;
- //$lang = Language::find($this->client->getSetting('language_id'));
-
- //return $lang->locale;
}
/**
diff --git a/app/Services/PdfMaker/Design.php b/app/Services/PdfMaker/Design.php
index dcbc8f39bff4..01be541aa1c0 100644
--- a/app/Services/PdfMaker/Design.php
+++ b/app/Services/PdfMaker/Design.php
@@ -56,6 +56,10 @@ class Design extends BaseDesign
/** @var Payment[] */
public $payments;
+ public $settings_object;
+
+ public $company;
+
/** @var array */
public $aging = [];
@@ -80,6 +84,7 @@ class Design extends BaseDesign
Str::endsWith('.html', $design) ? $this->design = $design : $this->design = "{$design}.html";
$this->options = $options;
+
}
public function html(): ?string
@@ -574,19 +579,19 @@ class Design extends BaseDesign
foreach ($this->context['pdf_variables']["{$type}_columns"] as $column) {
if (array_key_exists($column, $aliases)) {
- $elements[] = ['element' => 'th', 'content' => $aliases[$column] . '_label', 'properties' => ['data-ref' => "{$type}_table-" . substr($aliases[$column], 1) . '-th', 'hidden' => $this->client->getSetting('hide_empty_columns_on_pdf')]];
- } elseif ($column == '$product.discount' && !$this->client->company->enable_product_discount) {
+ $elements[] = ['element' => 'th', 'content' => $aliases[$column] . '_label', 'properties' => ['data-ref' => "{$type}_table-" . substr($aliases[$column], 1) . '-th', 'hidden' => $this->settings_object->getSetting('hide_empty_columns_on_pdf')]];
+ } elseif ($column == '$product.discount' && !$this->company->enable_product_discount) {
$elements[] = ['element' => 'th', 'content' => $column . '_label', 'properties' => ['data-ref' => "{$type}_table-" . substr($column, 1) . '-th', 'style' => 'display: none;']];
- } elseif ($column == '$product.quantity' && !$this->client->company->enable_product_quantity) {
+ } elseif ($column == '$product.quantity' && !$this->company->enable_product_quantity) {
$elements[] = ['element' => 'th', 'content' => $column . '_label', 'properties' => ['data-ref' => "{$type}_table-" . substr($column, 1) . '-th', 'style' => 'display: none;']];
} elseif ($column == '$product.tax_rate1') {
- $elements[] = ['element' => 'th', 'content' => $column . '_label', 'properties' => ['data-ref' => "{$type}_table-product.tax1-th", 'hidden' => $this->client->getSetting('hide_empty_columns_on_pdf')]];
+ $elements[] = ['element' => 'th', 'content' => $column . '_label', 'properties' => ['data-ref' => "{$type}_table-product.tax1-th", 'hidden' => $this->settings_object->getSetting('hide_empty_columns_on_pdf')]];
} elseif ($column == '$product.tax_rate2') {
- $elements[] = ['element' => 'th', 'content' => $column . '_label', 'properties' => ['data-ref' => "{$type}_table-product.tax2-th", 'hidden' => $this->client->getSetting('hide_empty_columns_on_pdf')]];
+ $elements[] = ['element' => 'th', 'content' => $column . '_label', 'properties' => ['data-ref' => "{$type}_table-product.tax2-th", 'hidden' => $this->settings_object->getSetting('hide_empty_columns_on_pdf')]];
} elseif ($column == '$product.tax_rate3') {
- $elements[] = ['element' => 'th', 'content' => $column . '_label', 'properties' => ['data-ref' => "{$type}_table-product.tax3-th", 'hidden' => $this->client->getSetting('hide_empty_columns_on_pdf')]];
+ $elements[] = ['element' => 'th', 'content' => $column . '_label', 'properties' => ['data-ref' => "{$type}_table-product.tax3-th", 'hidden' => $this->settings_object->getSetting('hide_empty_columns_on_pdf')]];
} else {
- $elements[] = ['element' => 'th', 'content' => $column . '_label', 'properties' => ['data-ref' => "{$type}_table-" . substr($column, 1) . '-th', 'hidden' => $this->client->getSetting('hide_empty_columns_on_pdf')]];
+ $elements[] = ['element' => 'th', 'content' => $column . '_label', 'properties' => ['data-ref' => "{$type}_table-" . substr($column, 1) . '-th', 'hidden' => $this->settings_object->getSetting('hide_empty_columns_on_pdf')]];
}
}
@@ -677,9 +682,9 @@ class Design extends BaseDesign
if ($cell == '$task.rate') {
$element['elements'][] = ['element' => 'td', 'content' => $row['$task.cost'], 'properties' => ['data-ref' => 'task_table-task.cost-td']];
- } elseif ($cell == '$product.discount' && !$this->client->company->enable_product_discount) {
+ } elseif ($cell == '$product.discount' && !$this->company->enable_product_discount) {
$element['elements'][] = ['element' => 'td', 'content' => $row['$product.discount'], 'properties' => ['data-ref' => 'product_table-product.discount-td', 'style' => 'display: none;']];
- } elseif ($cell == '$product.quantity' && !$this->client->company->enable_product_quantity) {
+ } elseif ($cell == '$product.quantity' && !$this->company->enable_product_quantity) {
$element['elements'][] = ['element' => 'td', 'content' => $row['$product.quantity'], 'properties' => ['data-ref' => 'product_table-product.quantity-td', 'style' => 'display: none;']];
} elseif ($cell == '$task.hours') {
$element['elements'][] = ['element' => 'td', 'content' => $row['$task.quantity'], 'properties' => ['data-ref' => 'task_table-task.hours-td']];
@@ -807,7 +812,7 @@ class Design extends BaseDesign
]];
} elseif (Str::startsWith($variable, '$custom')) {
$field = explode('_', $variable);
- $visible = is_object($this->client->company->custom_fields) && property_exists($this->client->company->custom_fields, $field[1]) && !empty($this->client->company->custom_fields->{$field[1]});
+ $visible = is_object($this->company->custom_fields) && property_exists($this->company->custom_fields, $field[1]) && !empty($this->company->custom_fields->{$field[1]});
$elements[1]['elements'][] = ['element' => 'div', 'elements' => [
['element' => 'span', 'content' => $variable . '_label', 'properties' => ['hidden' => !$visible, 'data-ref' => 'totals_table-' . substr($variable, 1) . '-label']],
diff --git a/app/Services/PdfMaker/Designs/Utilities/DesignHelpers.php b/app/Services/PdfMaker/Designs/Utilities/DesignHelpers.php
index 944c518db166..ff449e8f1ae6 100644
--- a/app/Services/PdfMaker/Designs/Utilities/DesignHelpers.php
+++ b/app/Services/PdfMaker/Designs/Utilities/DesignHelpers.php
@@ -60,6 +60,10 @@ trait DesignHelpers
$this->document();
+ $this->settings_object = $this->vendor ? $this->vendor->company : $this->client;
+
+ $this->company = $this->vendor ? $this->vendor->company : $this->client->company;
+
return $this;
}
diff --git a/app/Services/PurchaseOrder/CreateInvitations.php b/app/Services/PurchaseOrder/CreateInvitations.php
index fa01a8457b27..cd8634fc5de1 100644
--- a/app/Services/PurchaseOrder/CreateInvitations.php
+++ b/app/Services/PurchaseOrder/CreateInvitations.php
@@ -42,7 +42,7 @@ class CreateInvitations extends AbstractService
public function run()
{
- $contacts = $this->purchase_order->vendor->contacts()->where('send_email', true)->get();
+ $contacts = $this->purchase_order->vendor->contacts()->get();
if($contacts->count() == 0){
$this->createBlankContact();
diff --git a/app/Services/PurchaseOrder/PurchaseOrderService.php b/app/Services/PurchaseOrder/PurchaseOrderService.php
index 69e6066b992a..89d2b64a8b31 100644
--- a/app/Services/PurchaseOrder/PurchaseOrderService.php
+++ b/app/Services/PurchaseOrder/PurchaseOrderService.php
@@ -11,11 +11,12 @@
namespace App\Services\PurchaseOrder;
-
+use App\Jobs\Vendor\CreatePurchaseOrderPdf;
use App\Models\PurchaseOrder;
use App\Services\PurchaseOrder\ApplyNumber;
use App\Services\PurchaseOrder\CreateInvitations;
use App\Services\PurchaseOrder\GetPurchaseOrderPdf;
+use App\Services\PurchaseOrder\TriggeredActions;
use App\Utils\Traits\MakesHash;
class PurchaseOrderService
@@ -62,6 +63,13 @@ class PurchaseOrderService
return $this;
}
+ public function triggeredActions($request)
+ {
+ $this->purchase_order = (new TriggeredActions($this->purchase_order->load('invitations'), $request))->run();
+
+ return $this;
+ }
+
public function getPurchaseOrderPdf($contact = null)
{
return (new GetPurchaseOrderPdf($this->purchase_order, $contact))->run();
@@ -81,6 +89,34 @@ class PurchaseOrderService
return $this;
}
+
+ public function touchPdf($force = false)
+ {
+ try {
+
+ if($force){
+
+ $this->purchase_order->invitations->each(function ($invitation) {
+ CreatePurchaseOrderPdf::dispatchNow($invitation);
+ });
+
+ return $this;
+ }
+
+ $this->purchase_order->invitations->each(function ($invitation) {
+ CreatePurchaseOrderPdf::dispatch($invitation);
+ });
+
+ }
+ catch(\Exception $e){
+
+ nlog("failed creating purchase orders in Touch PDF");
+
+ }
+
+ return $this;
+ }
+
/**
* Saves the purchase order.
* @return \App\Models\PurchaseOrder object
diff --git a/app/Services/PurchaseOrder/TriggeredActions.php b/app/Services/PurchaseOrder/TriggeredActions.php
new file mode 100644
index 000000000000..76735129cf13
--- /dev/null
+++ b/app/Services/PurchaseOrder/TriggeredActions.php
@@ -0,0 +1,65 @@
+request = $request;
+
+ $this->purchase_order = $purchase_order;
+ }
+
+ public function run()
+ {
+
+ if ($this->request->has('send_email') && $this->request->input('send_email') == 'true') {
+ $this->purchase_order->service()->markSent()->touchPdf()->save();
+ $this->sendEmail();
+ }
+
+ if ($this->request->has('mark_sent') && $this->request->input('mark_sent') == 'true') {
+ $this->purchase_order = $this->purchase_order->service()->markSent()->touchPdf()->save();
+ }
+
+ // if ($this->request->has('cancel') && $this->request->input('cancel') == 'true') {
+ // $this->purchase_order = $this->purchase_order->service()->handleCancellation()->save();
+ // }
+
+ return $this->purchase_order;
+ }
+
+ private function sendEmail()
+ {
+
+ PurchaseOrderEmail::dispatch($this->purchase_order, $this->purchase_order->company);
+
+ }
+}
diff --git a/app/Transformers/AccountTransformer.php b/app/Transformers/AccountTransformer.php
index 661ad79b2ce9..502f0b9dedc5 100644
--- a/app/Transformers/AccountTransformer.php
+++ b/app/Transformers/AccountTransformer.php
@@ -86,6 +86,7 @@ class AccountTransformer extends EntityTransformer
'hosted_client_count' => (int) $account->hosted_client_count,
'hosted_company_count' => (int) $account->hosted_company_count,
'is_hosted' => (bool) Ninja::isHosted(),
+ // 'set_react_as_default_ap' => (bool) $account->set_react_as_default_ap
];
}
diff --git a/app/Utils/Traits/MakesInvoiceValues.php b/app/Utils/Traits/MakesInvoiceValues.php
index e59c59a61478..1b5c6985155a 100644
--- a/app/Utils/Traits/MakesInvoiceValues.php
+++ b/app/Utils/Traits/MakesInvoiceValues.php
@@ -265,6 +265,8 @@ trait MakesInvoiceValues
*/
public function transformLineItems($items, $table_type = '$product') :array
{
+ $entity = $this->client ? $this->client : $this->company;
+
$data = [];
if (! is_array($items)) {
@@ -294,23 +296,23 @@ trait MakesInvoiceValues
$data[$key][$table_type.'.item'] = is_null(optional($item)->item) ? $item->product_key : $item->item;
$data[$key][$table_type.'.service'] = is_null(optional($item)->service) ? $item->product_key : $item->service;
- $data[$key][$table_type.'.notes'] = Helpers::processReservedKeywords($item->notes, $this->client);
- $data[$key][$table_type.'.description'] = Helpers::processReservedKeywords($item->notes, $this->client);
+ $data[$key][$table_type.'.notes'] = Helpers::processReservedKeywords($item->notes, $entity);
+ $data[$key][$table_type.'.description'] = Helpers::processReservedKeywords($item->notes, $entity);
- $data[$key][$table_type . ".{$_table_type}1"] = $helpers->formatCustomFieldValue($this->client->company->custom_fields, "{$_table_type}1", $item->custom_value1, $this->client);
- $data[$key][$table_type . ".{$_table_type}2"] = $helpers->formatCustomFieldValue($this->client->company->custom_fields, "{$_table_type}2", $item->custom_value2, $this->client);
- $data[$key][$table_type . ".{$_table_type}3"] = $helpers->formatCustomFieldValue($this->client->company->custom_fields, "{$_table_type}3", $item->custom_value3, $this->client);
- $data[$key][$table_type . ".{$_table_type}4"] = $helpers->formatCustomFieldValue($this->client->company->custom_fields, "{$_table_type}4", $item->custom_value4, $this->client);
+ $data[$key][$table_type . ".{$_table_type}1"] = $helpers->formatCustomFieldValue($this->company->custom_fields, "{$_table_type}1", $item->custom_value1, $entity);
+ $data[$key][$table_type . ".{$_table_type}2"] = $helpers->formatCustomFieldValue($this->company->custom_fields, "{$_table_type}2", $item->custom_value2, $entity);
+ $data[$key][$table_type . ".{$_table_type}3"] = $helpers->formatCustomFieldValue($this->company->custom_fields, "{$_table_type}3", $item->custom_value3, $entity);
+ $data[$key][$table_type . ".{$_table_type}4"] = $helpers->formatCustomFieldValue($this->company->custom_fields, "{$_table_type}4", $item->custom_value4, $entity);
if($item->quantity > 0 || $item->cost > 0){
- $data[$key][$table_type.'.quantity'] = Number::formatValueNoTrailingZeroes($item->quantity, $this->client->currency());
+ $data[$key][$table_type.'.quantity'] = Number::formatValueNoTrailingZeroes($item->quantity, $entity->currency());
- $data[$key][$table_type.'.unit_cost'] = Number::formatMoneyNoRounding($item->cost, $this->client);
+ $data[$key][$table_type.'.unit_cost'] = Number::formatMoneyNoRounding($item->cost, $entity);
- $data[$key][$table_type.'.cost'] = Number::formatMoney($item->cost, $this->client);
+ $data[$key][$table_type.'.cost'] = Number::formatMoney($item->cost, $entity);
- $data[$key][$table_type.'.line_total'] = Number::formatMoney($item->line_total, $this->client);
+ $data[$key][$table_type.'.line_total'] = Number::formatMoney($item->line_total, $entity);
}
else {
@@ -326,13 +328,13 @@ trait MakesInvoiceValues
}
if(property_exists($item, 'gross_line_total'))
- $data[$key][$table_type.'.gross_line_total'] = ($item->gross_line_total == 0) ? '' :Number::formatMoney($item->gross_line_total, $this->client);
+ $data[$key][$table_type.'.gross_line_total'] = ($item->gross_line_total == 0) ? '' :Number::formatMoney($item->gross_line_total, $entity);
else
$data[$key][$table_type.'.gross_line_total'] = '';
if (isset($item->discount) && $item->discount > 0) {
if ($item->is_amount_discount) {
- $data[$key][$table_type.'.discount'] = Number::formatMoney($item->discount, $this->client);
+ $data[$key][$table_type.'.discount'] = Number::formatMoney($item->discount, $entity);
} else {
$data[$key][$table_type.'.discount'] = floatval($item->discount).'%';
}
@@ -376,13 +378,14 @@ trait MakesInvoiceValues
private function makeLineTaxes() :string
{
$tax_map = $this->calc()->getTaxMap();
+ $entity = $this->client ? $this->client : $this->company;
$data = '';
foreach ($tax_map as $tax) {
$data .= '';
$data .= ''.$tax['name'].' | ';
- $data .= ''.Number::formatMoney($tax['total'], $this->client).' |
';
+ $data .= ''.Number::formatMoney($tax['total'], $entity).' | ';
}
return $data;
@@ -395,6 +398,7 @@ trait MakesInvoiceValues
private function makeTotalTaxes() :string
{
$data = '';
+ $entity = $this->client ? $this->client : $this->company;
if (! $this->calc()->getTotalTaxMap()) {
return $data;
@@ -403,7 +407,7 @@ trait MakesInvoiceValues
foreach ($this->calc()->getTotalTaxMap() as $tax) {
$data .= '';
$data .= ''.$tax['name'].' | ';
- $data .= ''.Number::formatMoney($tax['total'], $this->client).' |
';
+ $data .= ''.Number::formatMoney($tax['total'], $entity).' | ';
}
return $data;
@@ -427,13 +431,14 @@ trait MakesInvoiceValues
private function totalTaxValues() :string
{
$data = '';
+ $entity = $this->client ? $this->client : $this->company;
if (! $this->calc()->getTotalTaxMap()) {
return $data;
}
foreach ($this->calc()->getTotalTaxMap() as $tax) {
- $data .= ''.Number::formatMoney($tax['total'], $this->client).'';
+ $data .= ''.Number::formatMoney($tax['total'], $entity).'';
}
return $data;
@@ -455,11 +460,12 @@ trait MakesInvoiceValues
private function lineTaxValues() :string
{
$tax_map = $this->calc()->getTaxMap();
+ $entity = $this->client ? $this->client : $this->company;
$data = '';
foreach ($tax_map as $tax) {
- $data .= ''.Number::formatMoney($tax['total'], $this->client).'';
+ $data .= ''.Number::formatMoney($tax['total'], $entity).'';
}
return $data;
@@ -481,7 +487,8 @@ trait MakesInvoiceValues
*/
public function generateCustomCSS() :string
{
- $settings = $this->client->getMergedSettings();
+
+ $settings = $this->client ? $this->client->getMergedSettings() : $this->company->settings;
$header_and_footer = '
.header, .header-space {
diff --git a/app/Utils/VendorHtmlEngine.php b/app/Utils/VendorHtmlEngine.php
index 7e20a951684e..36cc99a9fb08 100644
--- a/app/Utils/VendorHtmlEngine.php
+++ b/app/Utils/VendorHtmlEngine.php
@@ -134,20 +134,15 @@ class VendorHtmlEngine
$data['$entity.datetime'] = ['value' => $this->formatDatetime($this->entity->created_at, $this->company->date_format(), $this->company->locale()), 'label' => ctrans('texts.date')];
- $data['$payment_button'] = ['value' => ''.ctrans('texts.pay_now').'', 'label' => ctrans('texts.pay_now')];
- $data['$payment_link'] = ['value' => $this->invitation->getPaymentLink(), 'label' => ctrans('texts.pay_now')];
-
-
$data['$entity'] = ['value' => '', 'label' => ctrans('texts.purchase_order')];
$data['$number'] = ['value' => $this->entity->number ?: ' ', 'label' => ctrans('texts.purchase_order_number')];
$data['$number_short'] = ['value' => $this->entity->number ?: ' ', 'label' => ctrans('texts.purchase_order_number_short')];
$data['$entity.terms'] = ['value' => Helpers::processReservedKeywords(\nl2br($this->entity->terms), $this->company) ?: '', 'label' => ctrans('texts.invoice_terms')];
$data['$terms'] = &$data['$entity.terms'];
- $data['$view_link'] = ['value' => ''.ctrans('texts.view_invoice').'', 'label' => ctrans('texts.view_invoice')];
+ $data['$view_link'] = ['value' => ''.ctrans('texts.view_purchase_order').'', 'label' => ctrans('texts.view_purchase_order')];
$data['$viewLink'] = &$data['$view_link'];
$data['$viewButton'] = &$data['$view_link'];
$data['$view_button'] = &$data['$view_link'];
- $data['$paymentButton'] = &$data['$payment_button'];
$data['$view_url'] = ['value' => $this->invitation->getLink(), 'label' => ctrans('texts.view_invoice')];
$data['$date'] = ['value' => $this->translateDate($this->entity->date, $this->company->date_format(), $this->company->locale()) ?: ' ', 'label' => ctrans('texts.date')];
@@ -390,11 +385,6 @@ class VendorHtmlEngine
$data['$autoBill'] = ['value' => ctrans('texts.auto_bill_notification_placeholder'), 'label' => ''];
$data['$auto_bill'] = &$data['$autoBill'];
- /*Payment Aliases*/
- $data['$paymentLink'] = &$data['$payment_link'];
- $data['$payment_url'] = &$data['$payment_link'];
- $data['$portalButton'] = &$data['$paymentLink'];
-
$data['$dir'] = ['value' => optional($this->company->language())->locale === 'ar' ? 'rtl' : 'ltr', 'label' => ''];
$data['$dir_text_align'] = ['value' => optional($this->company->language())->locale === 'ar' ? 'right' : 'left', 'label' => ''];
diff --git a/database/migrations/2022_06_10_030503_set_account_flag_for_react.php b/database/migrations/2022_06_10_030503_set_account_flag_for_react.php
new file mode 100644
index 000000000000..a81f53fa4c3e
--- /dev/null
+++ b/database/migrations/2022_06_10_030503_set_account_flag_for_react.php
@@ -0,0 +1,40 @@
+boolean('set_react_as_default_ap')->default(0);
+ // });
+ }
+
+ /**
+ * Reverse the migrations.
+ *
+ * @return void
+ */
+ public function down()
+ {
+ //
+ }
+}
diff --git a/resources/lang/en/texts.php b/resources/lang/en/texts.php
index 59a028251576..413a966fbe12 100644
--- a/resources/lang/en/texts.php
+++ b/resources/lang/en/texts.php
@@ -4619,8 +4619,10 @@ $LANG = array(
'activity_134' => ':user restored purchase order :purchase_order',
'activity_135' => ':user emailed purchase order :purchase_order',
'activity_136' => ':contact viewed purchase order :purchase_order',
- 'purchase_order_subject' => '',
- 'purchase_order_message' => '',
+ 'purchase_order_subject' => 'New Purchase Order :number from :account',
+ 'purchase_order_message' => 'To view your purchase order for :amount, click the link below.',
+ 'view_purchase_order' => 'View Purchase Order',
+
);
return $LANG;