mirror of
https://github.com/invoiceninja/invoiceninja.git
synced 2025-06-01 02:04:46 -04:00
Download Invoice by Invitation (#3312)
* style cs * Style CS * Throw Record not found exception if invalid primary key hash is provided * Improve error handling * Create abstract implementation for designs * working on custom designs * Add Design Model * invoice services * Download Invoice by Invitation
This commit is contained in:
parent
dee99b1a62
commit
be3ade65f1
27
app/Designs/AbstractDesign.php
Normal file
27
app/Designs/AbstractDesign.php
Normal file
@ -0,0 +1,27 @@
|
|||||||
|
<?php
|
||||||
|
/**
|
||||||
|
* Invoice Ninja (https://invoiceninja.com)
|
||||||
|
*
|
||||||
|
* @link https://github.com/invoiceninja/invoiceninja source repository
|
||||||
|
*
|
||||||
|
* @copyright Copyright (c) 2020. Invoice Ninja LLC (https://invoiceninja.com)
|
||||||
|
*
|
||||||
|
* @license https://opensource.org/licenses/AAL
|
||||||
|
*/
|
||||||
|
|
||||||
|
namespace App\Designs;
|
||||||
|
|
||||||
|
abstract class AbstractDesign
|
||||||
|
{
|
||||||
|
|
||||||
|
abstract public function header();
|
||||||
|
|
||||||
|
abstract public function body();
|
||||||
|
|
||||||
|
abstract public function table();
|
||||||
|
|
||||||
|
abstract public function footer();
|
||||||
|
|
||||||
|
abstract public function table_styles();
|
||||||
|
|
||||||
|
}
|
77
app/Designs/Custom.php
Normal file
77
app/Designs/Custom.php
Normal file
@ -0,0 +1,77 @@
|
|||||||
|
<?php
|
||||||
|
/**
|
||||||
|
* Invoice Ninja (https://invoiceninja.com)
|
||||||
|
*
|
||||||
|
* @link https://github.com/invoiceninja/invoiceninja source repository
|
||||||
|
*
|
||||||
|
* @copyright Copyright (c) 2020. Invoice Ninja LLC (https://invoiceninja.com)
|
||||||
|
*
|
||||||
|
* @license https://opensource.org/licenses/AAL
|
||||||
|
*/
|
||||||
|
|
||||||
|
namespace App\Designs;
|
||||||
|
|
||||||
|
class Custom extends AbstractDesign
|
||||||
|
{
|
||||||
|
|
||||||
|
private $header;
|
||||||
|
|
||||||
|
private $body;
|
||||||
|
|
||||||
|
private $table;
|
||||||
|
|
||||||
|
private $footer;
|
||||||
|
|
||||||
|
private $table_styles;
|
||||||
|
|
||||||
|
public function __construct(array $data)
|
||||||
|
{
|
||||||
|
|
||||||
|
$this->header = $data['header'];
|
||||||
|
|
||||||
|
$this->body = $data['body'];
|
||||||
|
|
||||||
|
$this->table = $data['table'];
|
||||||
|
|
||||||
|
$this->footer = $data['footer'];
|
||||||
|
|
||||||
|
$this->table_styles = $data['table_styles'];
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
public function header()
|
||||||
|
{
|
||||||
|
|
||||||
|
return $this->header;
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
public function body()
|
||||||
|
{
|
||||||
|
|
||||||
|
return $this->body;
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
public function table_styles()
|
||||||
|
{
|
||||||
|
|
||||||
|
return $this->table_styles;
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
public function table()
|
||||||
|
{
|
||||||
|
|
||||||
|
return $this->table;
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
public function footer()
|
||||||
|
{
|
||||||
|
|
||||||
|
return $this->footer;
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
@ -14,8 +14,7 @@ namespace App\Designs;
|
|||||||
use App\Models\Company;
|
use App\Models\Company;
|
||||||
use App\Models\Invoice;
|
use App\Models\Invoice;
|
||||||
|
|
||||||
class Designer
|
class Designer {
|
||||||
{
|
|
||||||
|
|
||||||
protected $design;
|
protected $design;
|
||||||
|
|
||||||
@ -26,33 +25,32 @@ class Designer
|
|||||||
protected $html;
|
protected $html;
|
||||||
|
|
||||||
private static $custom_fields = [
|
private static $custom_fields = [
|
||||||
'invoice1',
|
'invoice1',
|
||||||
'invoice2',
|
'invoice2',
|
||||||
'invoice3',
|
'invoice3',
|
||||||
'invoice4',
|
'invoice4',
|
||||||
'surcharge1',
|
'surcharge1',
|
||||||
'surcharge2',
|
'surcharge2',
|
||||||
'surcharge3',
|
'surcharge3',
|
||||||
'surcharge4',
|
'surcharge4',
|
||||||
'client1',
|
'client1',
|
||||||
'client2',
|
'client2',
|
||||||
'client3',
|
'client3',
|
||||||
'client4',
|
'client4',
|
||||||
'contact1',
|
'contact1',
|
||||||
'contact2',
|
'contact2',
|
||||||
'contact3',
|
'contact3',
|
||||||
'contact4',
|
'contact4',
|
||||||
'company1',
|
'company1',
|
||||||
'company2',
|
'company2',
|
||||||
'company3',
|
'company3',
|
||||||
'company4',
|
'company4',
|
||||||
];
|
];
|
||||||
|
|
||||||
public function __construct($design, $input_variables)
|
public function __construct($design, $input_variables) {
|
||||||
{
|
|
||||||
$this->design = $design;
|
$this->design = $design;
|
||||||
|
|
||||||
$this->input_variables = (array)$input_variables;
|
$this->input_variables = (array) $input_variables;
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@ -60,23 +58,21 @@ class Designer
|
|||||||
* formatted HTML
|
* formatted HTML
|
||||||
* @return string The HTML design built
|
* @return string The HTML design built
|
||||||
*/
|
*/
|
||||||
public function build(Invoice $invoice) :Designer
|
public function build(Invoice $invoice):Designer {
|
||||||
{
|
|
||||||
|
|
||||||
$this->exportVariables($invoice)
|
$this->exportVariables($invoice)
|
||||||
->setDesign($this->getSection('header'))
|
->setDesign($this->getSection('header'))
|
||||||
->setDesign($this->getSection('body'))
|
->setDesign($this->getSection('body'))
|
||||||
->setDesign($this->getTable($invoice))
|
->setDesign($this->getTable($invoice))
|
||||||
->setDesign($this->getSection('footer'));
|
->setDesign($this->getSection('footer'));
|
||||||
|
|
||||||
return $this;
|
return $this;
|
||||||
}
|
}
|
||||||
|
|
||||||
public function getTable(Invoice $invoice) :string
|
public function getTable(Invoice $invoice):string {
|
||||||
{
|
|
||||||
|
|
||||||
$table_header = $invoice->table_header($this->input_variables['table_columns'], $this->design->table_styles());
|
$table_header = $invoice->table_header($this->input_variables['table_columns'], $this->design->table_styles());
|
||||||
$table_body = $invoice->table_body($this->input_variables['table_columns'], $this->design->table_styles());
|
$table_body = $invoice->table_body($this->input_variables['table_columns'], $this->design->table_styles());
|
||||||
|
|
||||||
$data = str_replace('$table_header', $table_header, $this->getSection('table'));
|
$data = str_replace('$table_header', $table_header, $this->getSection('table'));
|
||||||
$data = str_replace('$table_body', $table_body, $data);
|
$data = str_replace('$table_body', $table_body, $data);
|
||||||
@ -85,13 +81,11 @@ class Designer
|
|||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
public function getHtml() :string
|
public function getHtml():string {
|
||||||
{
|
|
||||||
return $this->html;
|
return $this->html;
|
||||||
}
|
}
|
||||||
|
|
||||||
private function setDesign($section)
|
private function setDesign($section) {
|
||||||
{
|
|
||||||
|
|
||||||
$this->html .= $section;
|
$this->html .= $section;
|
||||||
|
|
||||||
@ -99,48 +93,44 @@ class Designer
|
|||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Returns the template section on with the
|
* Returns the template section on with the
|
||||||
* stacked variables replaced with single variables.
|
* stacked variables replaced with single variables.
|
||||||
*
|
*
|
||||||
* @param string $section the method name to be executed ie header/body/table/footer
|
* @param string $section the method name to be executed ie header/body/table/footer
|
||||||
* @return string The HTML of the template section
|
* @return string The HTML of the template section
|
||||||
*/
|
*/
|
||||||
public function getSection($section) :string
|
public function getSection($section):string {
|
||||||
{
|
return str_replace(array_keys($this->exported_variables), array_values($this->exported_variables), $this->design->{ $section}());
|
||||||
return str_replace(array_keys($this->exported_variables), array_values($this->exported_variables), $this->design->{$section}());
|
|
||||||
}
|
}
|
||||||
|
|
||||||
private function exportVariables($invoice)
|
private function exportVariables($invoice) {
|
||||||
{
|
|
||||||
$company = $invoice->company;
|
$company = $invoice->company;
|
||||||
|
|
||||||
$this->exported_variables['$client_details'] = $this->processVariables($this->processInputVariables($company, $this->input_variables['client_details']), $this->clientDetails($company));
|
$this->exported_variables['$client_details'] = $this->processVariables($this->processInputVariables($company, $this->input_variables['client_details']), $this->clientDetails($company));
|
||||||
$this->exported_variables['$company_details'] = $this->processVariables($this->processInputVariables($company, $this->input_variables['company_details']), $this->companyDetails($company));
|
$this->exported_variables['$company_details'] = $this->processVariables($this->processInputVariables($company, $this->input_variables['company_details']), $this->companyDetails($company));
|
||||||
$this->exported_variables['$company_address'] = $this->processVariables($this->processInputVariables($company, $this->input_variables['company_address']), $this->companyAddress($company));
|
$this->exported_variables['$company_address'] = $this->processVariables($this->processInputVariables($company, $this->input_variables['company_address']), $this->companyAddress($company));
|
||||||
$this->exported_variables['$invoice_details_labels'] = $this->processLabels($this->processInputVariables($company, $this->input_variables['invoice_details']), $this->invoiceDetails($company));
|
$this->exported_variables['$invoice_details_labels'] = $this->processLabels($this->processInputVariables($company, $this->input_variables['invoice_details']), $this->invoiceDetails($company));
|
||||||
$this->exported_variables['$invoice_details'] = $this->processVariables($this->processInputVariables($company, $this->input_variables['invoice_details']), $this->invoiceDetails($company));
|
$this->exported_variables['$invoice_details'] = $this->processVariables($this->processInputVariables($company, $this->input_variables['invoice_details']), $this->invoiceDetails($company));
|
||||||
|
|
||||||
return $this;
|
return $this;
|
||||||
}
|
}
|
||||||
|
|
||||||
private function processVariables($input_variables, $variables) :string
|
private function processVariables($input_variables, $variables):string {
|
||||||
{
|
|
||||||
|
|
||||||
$output = '';
|
$output = '';
|
||||||
|
|
||||||
foreach($input_variables as $value)
|
foreach ($input_variables as $value)
|
||||||
$output .= $variables[$value];
|
$output .= $variables[$value];
|
||||||
|
|
||||||
return $output;
|
return $output;
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
private function processLabels($input_variables, $variables) :string
|
private function processLabels($input_variables, $variables):string {
|
||||||
{
|
|
||||||
$output = '';
|
$output = '';
|
||||||
|
|
||||||
foreach($input_variables as $value) {
|
foreach ($input_variables as $value) {
|
||||||
|
|
||||||
$tmp = str_replace("</span>", "_label</span>", $variables[$value]);
|
$tmp = str_replace("</span>", "_label</span>", $variables[$value]);
|
||||||
|
|
||||||
$output .= $tmp;
|
$output .= $tmp;
|
||||||
@ -156,19 +146,19 @@ class Designer
|
|||||||
// * $invoice_details
|
// * $invoice_details
|
||||||
// */
|
// */
|
||||||
// $header = $this->design->header();
|
// $header = $this->design->header();
|
||||||
|
|
||||||
// /*
|
// /*
|
||||||
// * $company_logo - full URL
|
// * $company_logo - full URL
|
||||||
// * $client_details
|
// * $client_details
|
||||||
// */
|
// */
|
||||||
// $body = $this->design->body();
|
// $body = $this->design->body();
|
||||||
|
|
||||||
// /*
|
// /*
|
||||||
// * $table_header
|
// * $table_header
|
||||||
// * $table_body
|
// * $table_body
|
||||||
// * $total_labels
|
// * $total_labels
|
||||||
// * $total_values
|
// * $total_values
|
||||||
// */
|
// */
|
||||||
// $table = $this->design->table();
|
// $table = $this->design->table();
|
||||||
|
|
||||||
// /*
|
// /*
|
||||||
@ -178,132 +168,124 @@ class Designer
|
|||||||
// $footer = $this->design->footer();
|
// $footer = $this->design->footer();
|
||||||
// }
|
// }
|
||||||
|
|
||||||
private function clientDetails(Company $company)
|
private function clientDetails(Company $company) {
|
||||||
{
|
|
||||||
|
|
||||||
$data = [
|
$data = [
|
||||||
'name' => '<p>$client.name</p>',
|
'name' => '<p>$client.name</p>',
|
||||||
'id_number' => '<p>$client.id_number</p>',
|
'id_number' => '<p>$client.id_number</p>',
|
||||||
'vat_number' => '<p>$client.vat_number</p>',
|
'vat_number' => '<p>$client.vat_number</p>',
|
||||||
'address1' => '<p>$client.address1</p>',
|
'address1' => '<p>$client.address1</p>',
|
||||||
'address2' => '<p>$client.address2</p>',
|
'address2' => '<p>$client.address2</p>',
|
||||||
'city_state_postal' => '<p>$client.city_state_postal</p>',
|
'city_state_postal' => '<p>$client.city_state_postal</p>',
|
||||||
'postal_city_state' => '<p>$client.postal_city_state</p>',
|
'postal_city_state' => '<p>$client.postal_city_state</p>',
|
||||||
'country' => '<p>$client.country</p>',
|
'country' => '<p>$client.country</p>',
|
||||||
'email' => '<p>$client.email</p>',
|
'email' => '<p>$client.email</p>',
|
||||||
'client1' => '<p>$client1</p>',
|
'client1' => '<p>$client1</p>',
|
||||||
'client2' => '<p>$client2</p>',
|
'client2' => '<p>$client2</p>',
|
||||||
'client3' => '<p>$client3</p>',
|
'client3' => '<p>$client3</p>',
|
||||||
'client4' => '<p>$client4</p>',
|
'client4' => '<p>$client4</p>',
|
||||||
'contact1' => '<p>$contact1</p>',
|
'contact1' => '<p>$contact1</p>',
|
||||||
'contact2' => '<p>$contact2</p>',
|
'contact2' => '<p>$contact2</p>',
|
||||||
'contact3' => '<p>$contact3</p>',
|
'contact3' => '<p>$contact3</p>',
|
||||||
'contact4' => '<p>$contact4</p>',
|
'contact4' => '<p>$contact4</p>',
|
||||||
];
|
];
|
||||||
|
|
||||||
return $this->processCustomFields($company, $data);
|
return $this->processCustomFields($company, $data);
|
||||||
}
|
}
|
||||||
|
|
||||||
private function companyDetails(Company $company)
|
private function companyDetails(Company $company) {
|
||||||
{
|
|
||||||
$data = [
|
$data = [
|
||||||
'company_name' => '<span>$company.company_name</span>',
|
'company_name' => '<span>$company.company_name</span>',
|
||||||
'id_number' => '<span>$company.id_number</span>',
|
'id_number' => '<span>$company.id_number</span>',
|
||||||
'vat_number' => '<span>$company.vat_number</span>',
|
'vat_number' => '<span>$company.vat_number</span>',
|
||||||
'website' => '<span>$company.website</span>',
|
'website' => '<span>$company.website</span>',
|
||||||
'email' => '<span>$company.email</span>',
|
'email' => '<span>$company.email</span>',
|
||||||
'phone' => '<span>$company.phone</span>',
|
'phone' => '<span>$company.phone</span>',
|
||||||
'company1' => '<span>$company1</span>',
|
'company1' => '<span>$company1</span>',
|
||||||
'company2' => '<span>$company2</span>',
|
'company2' => '<span>$company2</span>',
|
||||||
'company3' => '<span>$company3</span>',
|
'company3' => '<span>$company3</span>',
|
||||||
'company4' => '<span>$company4</span>',
|
'company4' => '<span>$company4</span>',
|
||||||
];
|
];
|
||||||
|
|
||||||
return $this->processCustomFields($company, $data);
|
return $this->processCustomFields($company, $data);
|
||||||
}
|
}
|
||||||
|
|
||||||
private function companyAddress(Company $company)
|
private function companyAddress(Company $company) {
|
||||||
{
|
|
||||||
|
|
||||||
$data = [
|
$data = [
|
||||||
'address1' => '<span>$company.address1</span>',
|
'address1' => '<span>$company.address1</span>',
|
||||||
'address2' => '<span>$company.address1</span>',
|
'address2' => '<span>$company.address1</span>',
|
||||||
'city_state_postal' => '<span>$company.city_state_postal</span>',
|
'city_state_postal' => '<span>$company.city_state_postal</span>',
|
||||||
'postal_city_state' => '<span>$company.postal_city_state</span>',
|
'postal_city_state' => '<span>$company.postal_city_state</span>',
|
||||||
'country' => '<span>$company.country</span>',
|
'country' => '<span>$company.country</span>',
|
||||||
'company1' => '<span>$company1</span>',
|
'company1' => '<span>$company1</span>',
|
||||||
'company2' => '<span>$company2</span>',
|
'company2' => '<span>$company2</span>',
|
||||||
'company3' => '<span>$company3</span>',
|
'company3' => '<span>$company3</span>',
|
||||||
'company4' => '<span>$company4</span>',
|
'company4' => '<span>$company4</span>',
|
||||||
];
|
];
|
||||||
|
|
||||||
return $this->processCustomFields($company, $data);
|
return $this->processCustomFields($company, $data);
|
||||||
}
|
}
|
||||||
|
|
||||||
private function invoiceDetails(Company $company)
|
private function invoiceDetails(Company $company) {
|
||||||
{
|
|
||||||
|
|
||||||
$data = [
|
$data = [
|
||||||
'invoice_number' => '<span>$invoice_number</span>',
|
'invoice_number' => '<span>$invoice_number</span>',
|
||||||
'po_number' => '<span>$po_number</span>',
|
'po_number' => '<span>$po_number</span>',
|
||||||
'date' => '<span>$date</span>',
|
'date' => '<span>$date</span>',
|
||||||
'due_date' => '<span>$due_date</span>',
|
'due_date' => '<span>$due_date</span>',
|
||||||
'balance_due' => '<span>$balance_due</span>',
|
'balance_due' => '<span>$balance_due</span>',
|
||||||
'invoice_total' => '<span>$invoice_total</span>',
|
'invoice_total' => '<span>$invoice_total</span>',
|
||||||
'partial_due' => '<span>$partial_due</span>',
|
'partial_due' => '<span>$partial_due</span>',
|
||||||
'invoice1' => '<span>$invoice1</span>',
|
'invoice1' => '<span>$invoice1</span>',
|
||||||
'invoice2' => '<span>$invoice2</span>',
|
'invoice2' => '<span>$invoice2</span>',
|
||||||
'invoice3' => '<span>$invoice3</span>',
|
'invoice3' => '<span>$invoice3</span>',
|
||||||
'invoice4' => '<span>$invoice4</span>',
|
'invoice4' => '<span>$invoice4</span>',
|
||||||
'surcharge1' =>'<span>$surcharge1</span>',
|
'surcharge1' => '<span>$surcharge1</span>',
|
||||||
'surcharge2' =>'<span>$surcharge2</span>',
|
'surcharge2' => '<span>$surcharge2</span>',
|
||||||
'surcharge3' =>'<span>$surcharge3</span>',
|
'surcharge3' => '<span>$surcharge3</span>',
|
||||||
'surcharge4' =>'<span>$surcharge4</span>',
|
'surcharge4' => '<span>$surcharge4</span>',
|
||||||
];
|
];
|
||||||
|
|
||||||
|
|
||||||
return $this->processCustomFields($company, $data);
|
return $this->processCustomFields($company, $data);
|
||||||
}
|
}
|
||||||
|
|
||||||
private function processCustomFields(Company $company, $data)
|
private function processCustomFields(Company $company, $data) {
|
||||||
{
|
|
||||||
|
|
||||||
$custom_fields = $company->custom_fields;
|
$custom_fields = $company->custom_fields;
|
||||||
|
|
||||||
foreach(self::$custom_fields as $cf)
|
if (!$custom_fields) {
|
||||||
{
|
return [];
|
||||||
|
}
|
||||||
|
|
||||||
if(!property_exists($custom_fields, $cf) || (strlen($custom_fields->{$cf}) == 0))
|
foreach (self::$custom_fields as $cf) {
|
||||||
|
|
||||||
|
if (!property_exists($custom_fields, $cf) || (strlen($custom_fields->{ $cf}) == 0)) {
|
||||||
unset($data[$cf]);
|
unset($data[$cf]);
|
||||||
|
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
return $data;
|
return $data;
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
private function processInputVariables($company, $variables)
|
private function processInputVariables($company, $variables) {
|
||||||
{
|
|
||||||
|
|
||||||
$custom_fields = $company->custom_fields;
|
$custom_fields = $company->custom_fields;
|
||||||
|
|
||||||
$matches = array_intersect(self::$custom_fields, $variables);
|
$matches = array_intersect(self::$custom_fields, $variables);
|
||||||
|
|
||||||
foreach($matches as $match)
|
foreach ($matches as $match) {
|
||||||
{
|
|
||||||
|
|
||||||
if(!property_exists($custom_fields, $match) || (strlen($custom_fields->{$match}) == 0))
|
if (!property_exists($custom_fields, $match) || (strlen($custom_fields->{ $match}) == 0)) {
|
||||||
{
|
foreach ($variables as $key => $value) {
|
||||||
foreach($variables as $key => $value)
|
if ($value == $match) {
|
||||||
{
|
|
||||||
if($value == $match)
|
|
||||||
{
|
|
||||||
unset($variables[$key]);
|
unset($variables[$key]);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
return $variables;
|
return $variables;
|
||||||
|
@ -11,15 +11,13 @@
|
|||||||
|
|
||||||
namespace App\Designs;
|
namespace App\Designs;
|
||||||
|
|
||||||
class Modern
|
class Modern extends AbstractDesign
|
||||||
{
|
{
|
||||||
|
|
||||||
public function __construct()
|
public function __construct() {
|
||||||
{
|
}
|
||||||
}
|
|
||||||
|
|
||||||
public function header()
|
public function header() {
|
||||||
{
|
|
||||||
|
|
||||||
return '
|
return '
|
||||||
<!DOCTYPE html>
|
<!DOCTYPE html>
|
||||||
@ -35,7 +33,7 @@ class Modern
|
|||||||
</style>
|
</style>
|
||||||
</head>
|
</head>
|
||||||
<body>
|
<body>
|
||||||
|
|
||||||
<div class="bg-orange-600 flex justify-between py-12 px-12">
|
<div class="bg-orange-600 flex justify-between py-12 px-12">
|
||||||
<div class="w-1/2">
|
<div class="w-1/2">
|
||||||
<h1 class="text-white font-bold text-5xl">$company.name</h1>
|
<h1 class="text-white font-bold text-5xl">$company.name</h1>
|
||||||
@ -53,8 +51,7 @@ class Modern
|
|||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
public function body()
|
public function body() {
|
||||||
{
|
|
||||||
|
|
||||||
return '
|
return '
|
||||||
<div class="flex justify-between px-12 pt-12">
|
<div class="flex justify-between px-12 pt-12">
|
||||||
@ -74,17 +71,15 @@ class Modern
|
|||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
public function table_styles()
|
public function table_styles() {
|
||||||
{
|
|
||||||
return [
|
return [
|
||||||
'table_header_thead_class' => "text-left text-white bg-gray-900",
|
'table_header_thead_class' => "text-left text-white bg-gray-900",
|
||||||
'table_header_td_class' => "px-4 py-2",
|
'table_header_td_class' => "px-4 py-2",
|
||||||
'table_body_td_class' => "border-t border-b border-gray-900 px-4 py-4",
|
'table_body_td_class' => "border-t border-b border-gray-900 px-4 py-4",
|
||||||
];
|
];
|
||||||
}
|
}
|
||||||
|
|
||||||
public function table()
|
public function table() {
|
||||||
{
|
|
||||||
|
|
||||||
return '
|
return '
|
||||||
<div class="px-12 pt-5 pb-20">
|
<div class="px-12 pt-5 pb-20">
|
||||||
@ -115,14 +110,14 @@ class Modern
|
|||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
<div class="flex px-4 mt-4 w-full items-end mt-5">
|
<div class="flex px-4 mt-4 w-full items-end mt-5" style="page-break-inside: avoid;">
|
||||||
<div class="w-1/2">
|
<div class="w-1/2">
|
||||||
<p class="font-semibold">$terms_label</p>
|
<p class="font-semibold">$terms_label</p>
|
||||||
$terms
|
$terms
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
<div class="mt-8 px-4 py-2 bg-gray-900 text-white">
|
<div class="mt-8 px-4 py-2 bg-gray-900 text-white" style="page-break-inside: avoid;">
|
||||||
<div class="w-1/2"></div>
|
<div class="w-1/2"></div>
|
||||||
<div class="w-auto flex justify-end">
|
<div class="w-auto flex justify-end">
|
||||||
<div class="w-56">
|
<div class="w-56">
|
||||||
@ -136,8 +131,7 @@ class Modern
|
|||||||
';
|
';
|
||||||
}
|
}
|
||||||
|
|
||||||
public function footer()
|
public function footer() {
|
||||||
{
|
|
||||||
|
|
||||||
return '
|
return '
|
||||||
<div class="bg-orange-600 flex justify-between py-8 px-12" style="page-break-inside: avoid;">
|
<div class="bg-orange-600 flex justify-between py-8 px-12" style="page-break-inside: avoid;">
|
||||||
|
@ -28,10 +28,13 @@ use App\Jobs\Invoice\CreateInvoicePdf;
|
|||||||
use App\Jobs\Invoice\EmailInvoice;
|
use App\Jobs\Invoice\EmailInvoice;
|
||||||
use App\Jobs\Invoice\StoreInvoice;
|
use App\Jobs\Invoice\StoreInvoice;
|
||||||
use App\Models\Invoice;
|
use App\Models\Invoice;
|
||||||
|
use App\Models\InvoiceInvitation;
|
||||||
use App\Repositories\InvoiceRepository;
|
use App\Repositories\InvoiceRepository;
|
||||||
use App\Transformers\InvoiceTransformer;
|
use App\Transformers\InvoiceTransformer;
|
||||||
use App\Utils\Traits\MakesHash;
|
use App\Utils\Traits\MakesHash;
|
||||||
use Illuminate\Http\Request;
|
use Illuminate\Http\Request;
|
||||||
|
use Illuminate\Support\Facades\File;
|
||||||
|
use Illuminate\Support\Facades\Storage;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Class InvoiceController
|
* Class InvoiceController
|
||||||
@ -57,9 +60,11 @@ class InvoiceController extends BaseController {
|
|||||||
* @param \App\Repositories\InvoiceRepository $invoice_repo The invoice repo
|
* @param \App\Repositories\InvoiceRepository $invoice_repo The invoice repo
|
||||||
*/
|
*/
|
||||||
public function __construct(InvoiceRepository $invoice_repo) {
|
public function __construct(InvoiceRepository $invoice_repo) {
|
||||||
|
|
||||||
parent::__construct();
|
parent::__construct();
|
||||||
|
|
||||||
$this->invoice_repo = $invoice_repo;
|
$this->invoice_repo = $invoice_repo;
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@ -75,8 +80,8 @@ class InvoiceController extends BaseController {
|
|||||||
* tags={"invoices"},
|
* tags={"invoices"},
|
||||||
* summary="Gets a list of invoices",
|
* summary="Gets a list of invoices",
|
||||||
* description="Lists invoices, search and filters allow fine grained lists to be generated.
|
* description="Lists invoices, search and filters allow fine grained lists to be generated.
|
||||||
|
*
|
||||||
Query parameters can be added to performed more fine grained filtering of the invoices, these are handled by the InvoiceFilters class which defines the methods available",
|
* Query parameters can be added to performed more fine grained filtering of the invoices, these are handled by the InvoiceFilters class which defines the methods available",
|
||||||
* @OA\Parameter(ref="#/components/parameters/X-Api-Secret"),
|
* @OA\Parameter(ref="#/components/parameters/X-Api-Secret"),
|
||||||
* @OA\Parameter(ref="#/components/parameters/X-Api-Token"),
|
* @OA\Parameter(ref="#/components/parameters/X-Api-Token"),
|
||||||
* @OA\Parameter(ref="#/components/parameters/X-Requested-With"),
|
* @OA\Parameter(ref="#/components/parameters/X-Requested-With"),
|
||||||
@ -519,17 +524,17 @@ class InvoiceController extends BaseController {
|
|||||||
* tags={"invoices"},
|
* tags={"invoices"},
|
||||||
* summary="Performs a custom action on an invoice",
|
* summary="Performs a custom action on an invoice",
|
||||||
* description="Performs a custom action on an invoice.
|
* description="Performs a custom action on an invoice.
|
||||||
|
*
|
||||||
The current range of actions are as follows
|
* The current range of actions are as follows
|
||||||
- clone_to_invoice
|
* - clone_to_invoice
|
||||||
- clone_to_quote
|
* - clone_to_quote
|
||||||
- history
|
* - history
|
||||||
- delivery_note
|
* - delivery_note
|
||||||
- mark_paid
|
* - mark_paid
|
||||||
- download
|
* - download
|
||||||
- archive
|
* - archive
|
||||||
- delete
|
* - delete
|
||||||
- email",
|
* - email",
|
||||||
* @OA\Parameter(ref="#/components/parameters/X-Api-Secret"),
|
* @OA\Parameter(ref="#/components/parameters/X-Api-Secret"),
|
||||||
* @OA\Parameter(ref="#/components/parameters/X-Api-Token"),
|
* @OA\Parameter(ref="#/components/parameters/X-Api-Token"),
|
||||||
* @OA\Parameter(ref="#/components/parameters/X-Requested-With"),
|
* @OA\Parameter(ref="#/components/parameters/X-Requested-With"),
|
||||||
@ -649,11 +654,11 @@ class InvoiceController extends BaseController {
|
|||||||
|
|
||||||
public function downloadPdf($invitation_key) {
|
public function downloadPdf($invitation_key) {
|
||||||
|
|
||||||
$invitation = InvoiceInvitation::whereKey($invitation_key)->company()->first();
|
$invitation = $this->invoice_repo->getInvitationByKey($invitation_key);
|
||||||
$contact = $invitation->contact;
|
$contact = $invitation->contact;
|
||||||
$invoice = $invitation->invoice;
|
$invoice = $invitation->invoice;
|
||||||
|
|
||||||
$file_path = CreateInvoicePdf::dispatchNow($invoice, $invoice->company, $contact);
|
$file_path = $invoice->service()->getInvoicePdf(); //CreateInvoicePdf::dispatchNow($invoice, $invoice->company, $contact);
|
||||||
|
|
||||||
return response()->download($file_path);
|
return response()->download($file_path);
|
||||||
|
|
||||||
|
@ -39,27 +39,35 @@ class CreateInvoicePdf implements ShouldQueue {
|
|||||||
public $company;
|
public $company;
|
||||||
|
|
||||||
public $contact;
|
public $contact;
|
||||||
|
|
||||||
|
private $disk;
|
||||||
/**
|
/**
|
||||||
* Create a new job instance.
|
* Create a new job instance.
|
||||||
*
|
*
|
||||||
* @return void
|
* @return void
|
||||||
*/
|
*/
|
||||||
public function __construct(Invoice $invoice, Company $company, ClientContact $contact) {
|
public function __construct(Invoice $invoice, Company $company, ClientContact $contact, $disk = 'public')
|
||||||
|
{
|
||||||
|
|
||||||
$this->invoice = $invoice;
|
$this->invoice = $invoice;
|
||||||
|
|
||||||
$this->company = $company;
|
$this->company = $company;
|
||||||
|
|
||||||
$this->contact = $contact;
|
$this->contact = $contact;
|
||||||
|
|
||||||
|
$this->disk = $disk ?? config('filesystems.default');
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
public function handle() {
|
public function handle() {
|
||||||
|
|
||||||
MultiDB::setDB($this->company->db);
|
MultiDB::setDB($this->company->db);
|
||||||
|
|
||||||
App::setLocale($this->contact->preferredLocale());
|
App::setLocale($this->contact->preferredLocale());
|
||||||
|
|
||||||
$this->invoice->load('client');
|
$this->invoice->load('client');
|
||||||
$path = 'public/'.$this->invoice->client->client_hash.'/invoices/';
|
$path = $this->invoice->client->client_hash . '/invoices/';
|
||||||
$file_path = $path.$this->invoice->number.'.pdf';
|
$file_path = $path . $this->invoice->number . '.pdf';
|
||||||
|
|
||||||
$modern = new Modern();
|
$modern = new Modern();
|
||||||
$designer = new Designer($modern, $this->invoice->client->getSetting('invoice_variables'));
|
$designer = new Designer($modern, $this->invoice->client->getSetting('invoice_variables'));
|
||||||
@ -74,9 +82,14 @@ class CreateInvoicePdf implements ShouldQueue {
|
|||||||
//create pdf
|
//create pdf
|
||||||
$pdf = $this->makePdf(null, null, $html);
|
$pdf = $this->makePdf(null, null, $html);
|
||||||
|
|
||||||
$path = Storage::put($file_path, $pdf);
|
$instance = Storage::disk($this->disk)->put($file_path, $pdf);
|
||||||
|
|
||||||
|
\Log::error($instance);
|
||||||
|
|
||||||
return $path;
|
//$instance = Storage::disk($this->disk)->putFileAs($path, $pdf, $this->invoice->number . '.pdf');
|
||||||
|
//$instance = Storage::putFileAs($path, $pdf, $this->invoice->number . '.pdf');
|
||||||
|
|
||||||
|
return $instance;
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@ -12,40 +12,37 @@
|
|||||||
namespace App\Jobs\Invoice;
|
namespace App\Jobs\Invoice;
|
||||||
|
|
||||||
use App\Models\Invoice;
|
use App\Models\Invoice;
|
||||||
use App\Repositories\InvoiceRepository;
|
|
||||||
use Illuminate\Bus\Queueable;
|
use Illuminate\Bus\Queueable;
|
||||||
use Illuminate\Contracts\Queue\ShouldQueue;
|
use Illuminate\Contracts\Queue\ShouldQueue;
|
||||||
use Illuminate\Foundation\Bus\Dispatchable;
|
use Illuminate\Foundation\Bus\Dispatchable;
|
||||||
use Illuminate\Queue\InteractsWithQueue;
|
use Illuminate\Queue\InteractsWithQueue;
|
||||||
use Illuminate\Queue\SerializesModels;
|
use Illuminate\Queue\SerializesModels;
|
||||||
|
|
||||||
class InvoiceNotification implements ShouldQueue
|
class InvoiceNotification implements ShouldQueue {
|
||||||
{
|
use Dispatchable, InteractsWithQueue, Queueable, SerializesModels;
|
||||||
use Dispatchable, InteractsWithQueue, Queueable, SerializesModels;
|
|
||||||
|
|
||||||
public $invoice;
|
public $invoice;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Create a new job instance.
|
* Create a new job instance.
|
||||||
*
|
*
|
||||||
* @return void
|
* @return void
|
||||||
*/
|
*/
|
||||||
public function __construct(Invoice $invoice)
|
public function __construct(Invoice $invoice) {
|
||||||
{
|
$this->invoice = $invoice;
|
||||||
$this->invoice = $invoice;
|
}
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Execute the job.
|
* Execute the job.
|
||||||
*
|
*
|
||||||
*
|
*
|
||||||
* @return void
|
* @return void
|
||||||
*/
|
*/
|
||||||
public function handle()
|
public function handle() {
|
||||||
{
|
|
||||||
|
|
||||||
//notification for the invoice.
|
//notification for the invoice.
|
||||||
//
|
//
|
||||||
//could mean a email, sms, slack, push
|
//could mean a email, sms, slack, push
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -47,7 +47,7 @@ class UploadFile implements ShouldQueue
|
|||||||
|
|
||||||
public $entity;
|
public $entity;
|
||||||
|
|
||||||
public function __construct($file, $type, $user, $company, $entity, $disk = 'local')
|
public function __construct($file, $type, $user, $company, $entity, $disk = 'public')
|
||||||
{
|
{
|
||||||
$this->file = $file;
|
$this->file = $file;
|
||||||
$this->type = $type;
|
$this->type = $type;
|
||||||
|
25
app/Models/Design.php
Normal file
25
app/Models/Design.php
Normal file
@ -0,0 +1,25 @@
|
|||||||
|
<?php
|
||||||
|
/**
|
||||||
|
* Invoice Ninja (https://invoiceninja.com)
|
||||||
|
*
|
||||||
|
* @link https://github.com/invoiceninja/invoiceninja source repository
|
||||||
|
*
|
||||||
|
* @copyright Copyright (c) 2020. Invoice Ninja LLC (https://invoiceninja.com)
|
||||||
|
*
|
||||||
|
* @license https://opensource.org/licenses/AAL
|
||||||
|
*/
|
||||||
|
|
||||||
|
namespace App\Models;
|
||||||
|
|
||||||
|
use Illuminate\Database\Eloquent\Model;
|
||||||
|
use Illuminate\Database\Eloquent\SoftDeletes;
|
||||||
|
|
||||||
|
class Design extends BaseModel
|
||||||
|
{
|
||||||
|
|
||||||
|
public function company()
|
||||||
|
{
|
||||||
|
return $this->belongsTo(Company::class);
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
@ -342,9 +342,14 @@ class Invoice extends BaseModel
|
|||||||
/** TODO// DOCUMENT THIS FUNCTIONALITY */
|
/** TODO// DOCUMENT THIS FUNCTIONALITY */
|
||||||
public function pdf_url()
|
public function pdf_url()
|
||||||
{
|
{
|
||||||
$public_path = 'storage/' . $this->client->client_hash . '/invoices/'. $this->number . '.pdf';
|
// $public_path = 'storage/' . $this->client->client_hash . '/invoices/'. $this->number . '.pdf';
|
||||||
|
|
||||||
|
// $storage_path = 'public/' . $this->client->client_hash . '/invoices/'. $this->number . '.pdf';
|
||||||
|
|
||||||
|
$public_path = $this->client->client_hash . '/invoices/'. $this->number . '.pdf';
|
||||||
|
|
||||||
|
$storage_path = $this->client->client_hash . '/invoices/'. $this->number . '.pdf';
|
||||||
|
|
||||||
$storage_path = 'public/' . $this->client->client_hash . '/invoices/'. $this->number . '.pdf';
|
|
||||||
|
|
||||||
if (!Storage::exists($storage_path)) {
|
if (!Storage::exists($storage_path)) {
|
||||||
event(new InvoiceWasUpdated($this, $this->company));
|
event(new InvoiceWasUpdated($this, $this->company));
|
||||||
|
@ -131,4 +131,9 @@ class InvoiceRepository extends BaseRepository {
|
|||||||
public function markSent(Invoice $invoice):?Invoice {
|
public function markSent(Invoice $invoice):?Invoice {
|
||||||
return $invoice->service()->markSent()->save();
|
return $invoice->service()->markSent()->save();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public function getInvitationByKey($key)
|
||||||
|
{
|
||||||
|
return InvoiceInvitation::whereRaw("BINARY `key`= ?", [$key])->first();
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
52
app/Services/Invoice/GetInvoicePdf.php
Normal file
52
app/Services/Invoice/GetInvoicePdf.php
Normal file
@ -0,0 +1,52 @@
|
|||||||
|
<?php
|
||||||
|
/**
|
||||||
|
* Invoice Ninja (https://invoiceninja.com)
|
||||||
|
*
|
||||||
|
* @link https://github.com/invoiceninja/invoiceninja source repository
|
||||||
|
*
|
||||||
|
* @copyright Copyright (c) 2020. Invoice Ninja LLC (https://invoiceninja.com)
|
||||||
|
*
|
||||||
|
* @license https://opensource.org/licenses/AAL
|
||||||
|
*/
|
||||||
|
|
||||||
|
namespace App\Services\Invoice;
|
||||||
|
|
||||||
|
use App\Jobs\Invoice\CreateInvoicePdf;
|
||||||
|
use Illuminate\Support\Facades\Storage;
|
||||||
|
|
||||||
|
class GetInvoicePdf
|
||||||
|
{
|
||||||
|
|
||||||
|
public function __construct()
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|
||||||
|
public function __invoke($invoice, $contact = null)
|
||||||
|
{
|
||||||
|
|
||||||
|
$path = $invoice->client->client_hash . '/invoices/';
|
||||||
|
|
||||||
|
$file_path = $path . $invoice->number . '.pdf';
|
||||||
|
|
||||||
|
$disk = config('filesystems.default');
|
||||||
|
|
||||||
|
$file = Storage::disk($disk)->exists($file_path);
|
||||||
|
|
||||||
|
if(!$contact)
|
||||||
|
$contact = $invoice->client->primary_contact()->first();
|
||||||
|
|
||||||
|
if(!$file)
|
||||||
|
{
|
||||||
|
|
||||||
|
$file_path = CreateInvoicePdf::dispatchNow($invoice, $invoice->company, $contact);
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
//return $file_path;
|
||||||
|
|
||||||
|
return Storage::disk($disk)->path($file_path);
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
|
@ -17,6 +17,7 @@ use App\Services\Client\ClientService;
|
|||||||
use App\Services\Invoice\ApplyNumber;
|
use App\Services\Invoice\ApplyNumber;
|
||||||
use App\Services\Invoice\ApplyPayment;
|
use App\Services\Invoice\ApplyPayment;
|
||||||
use App\Services\Invoice\CreateInvitations;
|
use App\Services\Invoice\CreateInvitations;
|
||||||
|
use App\Services\Invoice\GetInvoicePdf;
|
||||||
use App\Services\Invoice\MarkInvoicePaid;
|
use App\Services\Invoice\MarkInvoicePaid;
|
||||||
use App\Services\Invoice\MarkSent;
|
use App\Services\Invoice\MarkSent;
|
||||||
use App\Services\Invoice\UpdateBalance;
|
use App\Services\Invoice\UpdateBalance;
|
||||||
@ -112,6 +113,22 @@ class InvoiceService
|
|||||||
return $this;
|
return $this;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public function getInvoicePdf()
|
||||||
|
{
|
||||||
|
$get_invoice_pdf = new GetInvoicePdf();
|
||||||
|
|
||||||
|
return $get_invoice_pdf($this->invoice);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
public function markViewed()
|
public function markViewed()
|
||||||
{
|
{
|
||||||
$this->invoice->last_viewed = Carbon::now()->format('Y-m-d H:i');
|
$this->invoice->last_viewed = Carbon::now()->format('Y-m-d H:i');
|
||||||
@ -159,7 +176,6 @@ class InvoiceService
|
|||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Saves the invoice
|
* Saves the invoice
|
||||||
* @return Invoice object
|
* @return Invoice object
|
||||||
|
@ -11,6 +11,7 @@
|
|||||||
|
|
||||||
namespace App\Utils\Traits;
|
namespace App\Utils\Traits;
|
||||||
|
|
||||||
|
use App\Exceptions\ModelNotFoundException;
|
||||||
use App\Libraries\MultiDB;
|
use App\Libraries\MultiDB;
|
||||||
use Hashids\Hashids;
|
use Hashids\Hashids;
|
||||||
|
|
||||||
@ -69,6 +70,9 @@ trait MakesHash
|
|||||||
|
|
||||||
// \Log::error($decoded_array);
|
// \Log::error($decoded_array);
|
||||||
|
|
||||||
|
if(!is_array($decoded_array))
|
||||||
|
throw new ModelNotFoundException("Resource not found", 1);
|
||||||
|
|
||||||
return $decoded_array[0];
|
return $decoded_array[0];
|
||||||
} catch (\Exception $e) {
|
} catch (\Exception $e) {
|
||||||
return response()->json(['error'=>'Invalid primary key'], 400);
|
return response()->json(['error'=>'Invalid primary key'], 400);
|
||||||
|
@ -13,7 +13,7 @@ return [
|
|||||||
|
|
|
|
||||||
*/
|
*/
|
||||||
|
|
||||||
'default' => env('FILESYSTEM_DRIVER', 'local'),
|
'default' => env('FILESYSTEM_DRIVER', 'public'),
|
||||||
|
|
||||||
/*
|
/*
|
||||||
|--------------------------------------------------------------------------
|
|--------------------------------------------------------------------------
|
||||||
|
@ -1353,6 +1353,20 @@ class CreateUsersTable extends Migration
|
|||||||
$table->foreign('client_id')->references('id')->on('clients')->onDelete('cascade')->onUpdate('cascade');
|
$table->foreign('client_id')->references('id')->on('clients')->onDelete('cascade')->onUpdate('cascade');
|
||||||
});
|
});
|
||||||
|
|
||||||
|
|
||||||
|
Schema::create('designs', function ($table) {
|
||||||
|
$table->increments('id');
|
||||||
|
$table->unsignedInteger('user_id')->nullable();
|
||||||
|
$table->unsignedInteger('company_id')->nullable()->index();
|
||||||
|
$table->string('name');
|
||||||
|
$table->boolean('is_custom')->default(true);
|
||||||
|
$table->boolean('is_active')->default(true);
|
||||||
|
$table->mediumText('design')->nullable();
|
||||||
|
$table->timestamps(6);
|
||||||
|
|
||||||
|
$table->foreign('company_id')->references('id')->on('companies')->onDelete('cascade')->onUpdate('cascade');
|
||||||
|
|
||||||
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@ -31,6 +31,7 @@ class DatabaseSeeder extends Seeder
|
|||||||
$this->call('PaymentTypesSeeder');
|
$this->call('PaymentTypesSeeder');
|
||||||
$this->call('GatewayTypesSeeder');
|
$this->call('GatewayTypesSeeder');
|
||||||
$this->call('DateFormatsSeeder');
|
$this->call('DateFormatsSeeder');
|
||||||
|
$this->call('DesignSeeder');
|
||||||
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
40
database/seeds/DesignSeeder.php
Normal file
40
database/seeds/DesignSeeder.php
Normal file
@ -0,0 +1,40 @@
|
|||||||
|
<?php
|
||||||
|
|
||||||
|
use App\Models\Bank;
|
||||||
|
use App\Models\Design;
|
||||||
|
use Illuminate\Database\Seeder;
|
||||||
|
|
||||||
|
class DesignSeeder extends Seeder
|
||||||
|
{
|
||||||
|
public function run()
|
||||||
|
{
|
||||||
|
Eloquent::unguard();
|
||||||
|
|
||||||
|
$this->createDesigns();
|
||||||
|
}
|
||||||
|
|
||||||
|
private function createDesigns()
|
||||||
|
{
|
||||||
|
$designs = [
|
||||||
|
['id' => 1, 'name' => 'Plain', 'user_id' => null, 'company_id' => null, 'is_custom' => false, 'design' => '', 'is_active' => true],
|
||||||
|
['id' => 2, 'name' => 'Clean', 'user_id' => null, 'company_id' => null, 'is_custom' => false, 'design' => '', 'is_active' => true],
|
||||||
|
['id' => 3, 'name' => 'Bold', 'user_id' => null, 'company_id' => null, 'is_custom' => false, 'design' => '', 'is_active' => true],
|
||||||
|
['id' => 4, 'name' => 'Modern', 'user_id' => null, 'company_id' => null, 'is_custom' => false, 'design' => '', 'is_active' => true],
|
||||||
|
['id' => 5, 'name' => 'Business', 'user_id' => null, 'company_id' => null, 'is_custom' => false, 'design' => '', 'is_active' => true],
|
||||||
|
['id' => 6, 'name' => 'Creative', 'user_id' => null, 'company_id' => null, 'is_custom' => false, 'design' => '', 'is_active' => true],
|
||||||
|
['id' => 7, 'name' => 'Elegant', 'user_id' => null, 'company_id' => null, 'is_custom' => false, 'design' => '', 'is_active' => true],
|
||||||
|
['id' => 8, 'name' => 'Hipster', 'user_id' => null, 'company_id' => null, 'is_custom' => false, 'design' => '', 'is_active' => true],
|
||||||
|
['id' => 9, 'name' => 'Playful', 'user_id' => null, 'company_id' => null, 'is_custom' => false, 'design' => '', 'is_active' => true],
|
||||||
|
['id' => 10, 'name' => 'Photo', 'user_id' => null, 'company_id' => null, 'is_custom' => false, 'design' => '', 'is_active' => true],
|
||||||
|
];
|
||||||
|
|
||||||
|
foreach($designs as $design) {
|
||||||
|
|
||||||
|
$d = Design::find($design['id']);
|
||||||
|
|
||||||
|
if(!$d)
|
||||||
|
Design::create($design);
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
}
|
39
tests/Integration/InvoiceUploadTest.php
Normal file
39
tests/Integration/InvoiceUploadTest.php
Normal file
@ -0,0 +1,39 @@
|
|||||||
|
<?php
|
||||||
|
|
||||||
|
namespace Tests\Integration;
|
||||||
|
|
||||||
|
use App\Jobs\Invoice\CreateInvoicePdf;
|
||||||
|
use Illuminate\Foundation\Testing\Concerns\InteractsWithDatabase;
|
||||||
|
use Illuminate\Foundation\Testing\DatabaseTransactions;
|
||||||
|
use Illuminate\Support\Facades\Cache;
|
||||||
|
use Illuminate\Support\Facades\Storage;
|
||||||
|
use Tests\MockAccountData;
|
||||||
|
use Tests\TestCase;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @test
|
||||||
|
* @covers App\Services\Invoice\GetInvoicePdf
|
||||||
|
*/
|
||||||
|
class InvoiceUploadTest extends TestCase
|
||||||
|
{
|
||||||
|
use MockAccountData;
|
||||||
|
use DatabaseTransactions;
|
||||||
|
|
||||||
|
public function setUp() :void
|
||||||
|
{
|
||||||
|
parent::setUp();
|
||||||
|
|
||||||
|
$this->makeTestData();
|
||||||
|
}
|
||||||
|
|
||||||
|
public function testInvoiceUploadWorks()
|
||||||
|
{
|
||||||
|
|
||||||
|
CreateInvoicePdf::dispatchNow($this->invoice, $this->invoice->company, $this->invoice->client->primary_contact()->first());
|
||||||
|
|
||||||
|
$this->assertNotNull($this->invoice->service()->getInvoicePdf());
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
}
|
@ -19,6 +19,7 @@ use Illuminate\Foundation\Testing\DatabaseTransactions;
|
|||||||
use Illuminate\Http\UploadedFile;
|
use Illuminate\Http\UploadedFile;
|
||||||
use Illuminate\Routing\Middleware\ThrottleRequests;
|
use Illuminate\Routing\Middleware\ThrottleRequests;
|
||||||
use Illuminate\Support\Facades\Log;
|
use Illuminate\Support\Facades\Log;
|
||||||
|
use Illuminate\Support\Facades\Storage;
|
||||||
use Tests\MockAccountData;
|
use Tests\MockAccountData;
|
||||||
use Tests\TestCase;
|
use Tests\TestCase;
|
||||||
|
|
||||||
@ -50,7 +51,7 @@ class UploadFileTest extends TestCase
|
|||||||
$document = UploadFile::dispatchNow(
|
$document = UploadFile::dispatchNow(
|
||||||
$image, UploadFile::IMAGE, $this->invoice->user, $this->invoice->company, $this->invoice
|
$image, UploadFile::IMAGE, $this->invoice->user, $this->invoice->company, $this->invoice
|
||||||
);
|
);
|
||||||
|
|
||||||
$this->assertNotNull($document);
|
$this->assertNotNull($document);
|
||||||
|
|
||||||
}
|
}
|
||||||
|
Loading…
x
Reference in New Issue
Block a user