mirror of
https://github.com/invoiceninja/invoiceninja.git
synced 2025-05-24 02:14:21 -04:00
TDD for purchase order PDFs
This commit is contained in:
parent
04e55836ea
commit
c0ba8aa822
@ -52,7 +52,10 @@ class InvoiceItemSum
|
||||
|
||||
$this->invoice = $invoice;
|
||||
|
||||
$this->currency = $this->invoice->client->currency();
|
||||
if($this->invoice->vendor)
|
||||
$this->currency = $this->invoice->vendor->currency();
|
||||
else
|
||||
$this->currency = $this->invoice->client->currency();
|
||||
|
||||
$this->line_items = [];
|
||||
}
|
||||
|
@ -44,6 +44,8 @@ class InvoiceSum
|
||||
|
||||
private $gross_sub_total;
|
||||
|
||||
private $precision;
|
||||
|
||||
/**
|
||||
* Constructs the object with Invoice and Settings object.
|
||||
*
|
||||
@ -53,8 +55,10 @@ class InvoiceSum
|
||||
{
|
||||
$this->invoice = $invoice;
|
||||
|
||||
// if(!$this->invoice->relationLoaded('client'))
|
||||
// $this->invoice->load('client');
|
||||
if($this->invoice->vendor)
|
||||
$this->precision = $this->invoice->vendor->currency()->precision;
|
||||
else
|
||||
$this->precision = $this->invoice->client->currency()->precision;
|
||||
|
||||
$this->tax_map = new Collection;
|
||||
}
|
||||
@ -234,9 +238,9 @@ class InvoiceSum
|
||||
|
||||
public function getRecurringInvoice()
|
||||
{
|
||||
$this->invoice->amount = $this->formatValue($this->getTotal(), $this->invoice->client->currency()->precision);
|
||||
$this->invoice->amount = $this->formatValue($this->getTotal(), $this->precision);
|
||||
$this->invoice->total_taxes = $this->getTotalTaxes();
|
||||
$this->invoice->balance = $this->formatValue($this->getTotal(), $this->invoice->client->currency()->precision);
|
||||
$this->invoice->balance = $this->formatValue($this->getTotal(), $this->precision);
|
||||
|
||||
$this->invoice->saveQuietly();
|
||||
|
||||
@ -255,13 +259,13 @@ class InvoiceSum
|
||||
if ($this->invoice->amount != $this->invoice->balance) {
|
||||
$paid_to_date = $this->invoice->amount - $this->invoice->balance;
|
||||
|
||||
$this->invoice->balance = $this->formatValue($this->getTotal(), $this->invoice->client->currency()->precision) - $paid_to_date;
|
||||
$this->invoice->balance = $this->formatValue($this->getTotal(), $this->precision) - $paid_to_date;
|
||||
} else {
|
||||
$this->invoice->balance = $this->formatValue($this->getTotal(), $this->invoice->client->currency()->precision);
|
||||
$this->invoice->balance = $this->formatValue($this->getTotal(), $this->precision);
|
||||
}
|
||||
}
|
||||
/* Set new calculated total */
|
||||
$this->invoice->amount = $this->formatValue($this->getTotal(), $this->invoice->client->currency()->precision);
|
||||
$this->invoice->amount = $this->formatValue($this->getTotal(), $this->precision);
|
||||
|
||||
$this->invoice->total_taxes = $this->getTotalTaxes();
|
||||
|
||||
|
3
app/Jobs/Vendor/CreatePurchaseOrderPdf.php
vendored
3
app/Jobs/Vendor/CreatePurchaseOrderPdf.php
vendored
@ -73,7 +73,8 @@ class CreatePurchaseOrderPdf implements ShouldQueue
|
||||
public function __construct($invitation, $disk = 'public')
|
||||
{
|
||||
$this->invitation = $invitation;
|
||||
|
||||
$this->company = $invitation->company;
|
||||
|
||||
$this->entity = $invitation->purchase_order;
|
||||
$this->entity_string = 'purchase_order';
|
||||
|
||||
|
42
app/Models/Presenters/VendorContactPresenter.php
Normal file
42
app/Models/Presenters/VendorContactPresenter.php
Normal file
@ -0,0 +1,42 @@
|
||||
<?php
|
||||
/**
|
||||
* Invoice Ninja (https://invoiceninja.com).
|
||||
*
|
||||
* @link https://github.com/invoiceninja/invoiceninja source repository
|
||||
*
|
||||
* @copyright Copyright (c) 2022. Invoice Ninja LLC (https://invoiceninja.com)
|
||||
*
|
||||
* @license https://www.elastic.co/licensing/elastic-license
|
||||
*/
|
||||
|
||||
namespace App\Models\Presenters;
|
||||
|
||||
/**
|
||||
* Class VendorContactPresenter.
|
||||
*/
|
||||
class VendorContactPresenter extends EntityPresenter
|
||||
{
|
||||
/**
|
||||
* @return string
|
||||
*/
|
||||
public function name()
|
||||
{
|
||||
$contact_name = $this->entity->first_name.' '.$this->entity->last_name;
|
||||
|
||||
if (strlen($contact_name) > 1) {
|
||||
return $contact_name;
|
||||
}
|
||||
|
||||
return $this->entity->vendor->present()->name();
|
||||
}
|
||||
|
||||
public function first_name()
|
||||
{
|
||||
return $this->entity->first_name ?: '';
|
||||
}
|
||||
|
||||
public function last_name()
|
||||
{
|
||||
return $this->entity->last_name ?: '';
|
||||
}
|
||||
}
|
@ -12,7 +12,10 @@
|
||||
namespace App\Models;
|
||||
|
||||
|
||||
use App\Helpers\Invoice\InvoiceSum;
|
||||
use App\Helpers\Invoice\InvoiceSumInclusive;
|
||||
use App\Jobs\Entity\CreateEntityPdf;
|
||||
use App\Jobs\Vendor\CreatePurchaseOrderPdf;
|
||||
use App\Services\PurchaseOrder\PurchaseOrderService;
|
||||
use App\Utils\Ninja;
|
||||
use Illuminate\Database\Eloquent\SoftDeletes;
|
||||
@ -165,14 +168,14 @@ class PurchaseOrder extends BaseModel
|
||||
return Storage::disk(config('filesystems.default'))->{$type}($file_path);
|
||||
}
|
||||
elseif(Ninja::isHosted() && $portal){
|
||||
$file_path = CreateEntityPdf::dispatchNow($invitation,config('filesystems.default'));
|
||||
$file_path = CreatePurchaseOrderPdf::dispatchNow($invitation,config('filesystems.default'));
|
||||
return Storage::disk(config('filesystems.default'))->{$type}($file_path);
|
||||
}
|
||||
|
||||
if(Storage::disk('public')->exists($file_path))
|
||||
return Storage::disk('public')->{$type}($file_path);
|
||||
|
||||
$file_path = CreateEntityPdf::dispatchNow($invitation);
|
||||
$file_path = CreatePurchaseOrderPdf::dispatchNow($invitation);
|
||||
return Storage::disk('public')->{$type}($file_path);
|
||||
}
|
||||
|
||||
@ -193,7 +196,7 @@ class PurchaseOrder extends BaseModel
|
||||
|
||||
public function service()
|
||||
{
|
||||
return new PurchaseOrderService($this);
|
||||
return new PurchaseOrderService($this);
|
||||
}
|
||||
|
||||
public function invoices()
|
||||
@ -211,4 +214,17 @@ class PurchaseOrder extends BaseModel
|
||||
return $this->morphMany(Document::class, 'documentable');
|
||||
}
|
||||
|
||||
public function calc()
|
||||
{
|
||||
$purchase_order_calc = null;
|
||||
|
||||
if ($this->uses_inclusive_taxes) {
|
||||
$purchase_order_calc = new InvoiceSumInclusive($this);
|
||||
} else {
|
||||
$purchase_order_calc = new InvoiceSum($this);
|
||||
}
|
||||
|
||||
return $purchase_order_calc->build();
|
||||
}
|
||||
|
||||
}
|
||||
|
@ -15,9 +15,10 @@ use App\DataMapper\CompanySettings;
|
||||
use App\Models\Presenters\VendorPresenter;
|
||||
use App\Utils\Traits\AppSetup;
|
||||
use App\Utils\Traits\GeneratesCounter;
|
||||
use App\Utils\Traits\NumberFormatter;
|
||||
use Illuminate\Database\Eloquent\SoftDeletes;
|
||||
use Laracasts\Presenter\PresentableTrait;
|
||||
use Illuminate\Support\Facades\Cache;
|
||||
use Laracasts\Presenter\PresentableTrait;
|
||||
|
||||
class Vendor extends BaseModel
|
||||
{
|
||||
@ -26,7 +27,7 @@ class Vendor extends BaseModel
|
||||
use GeneratesCounter;
|
||||
use PresentableTrait;
|
||||
use AppSetup;
|
||||
|
||||
|
||||
protected $fillable = [
|
||||
'name',
|
||||
'assigned_user_id',
|
||||
@ -166,6 +167,14 @@ class Vendor extends BaseModel
|
||||
public function purchase_order_filepath($invitation)
|
||||
{
|
||||
$contact_key = $invitation->contact->contact_key;
|
||||
|
||||
return $this->company->company_key.'/'.$this->vendor_hash.'/'.$contact_key.'/purchase_orders/';
|
||||
}
|
||||
|
||||
public function country()
|
||||
{
|
||||
return $this->belongsTo(Country::class);
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
|
@ -11,6 +11,7 @@
|
||||
|
||||
namespace App\Models;
|
||||
|
||||
use App\Models\Presenters\VendorContactPresenter;
|
||||
use App\Notifications\ClientContactResetPassword;
|
||||
use App\Utils\Traits\MakesHash;
|
||||
use Illuminate\Contracts\Translation\HasLocalePreference;
|
||||
@ -35,6 +36,8 @@ class VendorContact extends Authenticatable implements HasLocalePreference
|
||||
|
||||
protected $touches = ['vendor'];
|
||||
|
||||
protected $presenter = VendorContactPresenter::class;
|
||||
|
||||
/* Allow microtime timestamps */
|
||||
protected $dateFormat = 'Y-m-d H:i:s.u';
|
||||
|
||||
|
@ -11,9 +11,10 @@
|
||||
|
||||
namespace App\Repositories;
|
||||
|
||||
|
||||
use App\Factory\PurchaseOrderInvitationFactory;
|
||||
use App\Models\PurchaseOrder;
|
||||
use App\Models\PurchaseOrderInvitation;
|
||||
use App\Models\VendorContact;
|
||||
use App\Utils\Traits\MakesHash;
|
||||
|
||||
class PurchaseOrderRepository extends BaseRepository
|
||||
@ -27,13 +28,83 @@ class PurchaseOrderRepository extends BaseRepository
|
||||
public function save(array $data, PurchaseOrder $purchase_order) : ?PurchaseOrder
|
||||
{
|
||||
$purchase_order->fill($data);
|
||||
|
||||
$purchase_order->save();
|
||||
|
||||
if (isset($data['invitations'])) {
|
||||
$invitations = collect($data['invitations']);
|
||||
|
||||
/* Get array of Keys which have been removed from the invitations array and soft delete each invitation */
|
||||
$purchase_order->invitations->pluck('key')->diff($invitations->pluck('key'))->each(function ($invitation) {
|
||||
|
||||
$invitation = PurchaseOrderInvitation::where('key', $invitation)->first();
|
||||
|
||||
if ($invitation)
|
||||
$invitation->delete();
|
||||
|
||||
});
|
||||
|
||||
foreach ($data['invitations'] as $invitation) {
|
||||
|
||||
//if no invitations are present - create one.
|
||||
if (! $this->getInvitation($invitation)) {
|
||||
|
||||
if (isset($invitation['id']))
|
||||
unset($invitation['id']);
|
||||
|
||||
//make sure we are creating an invite for a contact who belongs to the client only!
|
||||
$contact = VendorContact::find($invitation['vendor_contact_id']);
|
||||
|
||||
if ($contact && $purchase_order->vendor_id == $contact->vendor_id) {
|
||||
|
||||
$new_invitation = PurchaseOrderInvitation::withTrashed()
|
||||
->where('vendor_contact_id', $contact->id)
|
||||
->where('purchase_order_id', $purchase_order->id)
|
||||
->first();
|
||||
|
||||
if ($new_invitation && $new_invitation->trashed()) {
|
||||
|
||||
$new_invitation->restore();
|
||||
|
||||
} else {
|
||||
|
||||
$new_invitation = PurchaseOrderInvitationFactory::create($purchase_order->company_id, $purchase_order->user_id);
|
||||
$new_invitation->purchase_order_id = $purchase_order->id;
|
||||
$new_invitation->vendor_contact_id = $contact->id;
|
||||
$new_invitation->key = $this->createDbHash($purchase_order->company->db);
|
||||
$new_invitation->save();
|
||||
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/* If no invitations have been created, this is our fail safe to maintain state*/
|
||||
if ($purchase_order->invitations()->count() == 0)
|
||||
$purchase_order->service()->createInvitations();
|
||||
|
||||
nlog("4");
|
||||
|
||||
/* Recalculate invoice amounts */
|
||||
$purchase_order = $purchase_order->calc()->getPurchaseOrder();
|
||||
|
||||
return $purchase_order;
|
||||
}
|
||||
|
||||
public function getInvitationByKey($key) :?PurchaseOrderInvitation
|
||||
{
|
||||
return PurchaseOrderInvitation::where('key', $key)->first();
|
||||
}
|
||||
|
||||
public function getInvitation($invitation, $resource=null)
|
||||
{
|
||||
if (is_array($invitation) && ! array_key_exists('key', $invitation))
|
||||
return false;
|
||||
|
||||
$invitation = PurchaseOrderInvitation::where('key', $invitation['key'])->first();
|
||||
|
||||
return $invitation;
|
||||
}
|
||||
|
||||
}
|
||||
|
@ -35,6 +35,9 @@ class Design extends BaseDesign
|
||||
/** @var App\Models\Client */
|
||||
public $client;
|
||||
|
||||
/** @var App\Models\Vendor */
|
||||
public $vendor;
|
||||
|
||||
/** Global state of the design, @var array */
|
||||
public $context;
|
||||
|
||||
@ -198,6 +201,9 @@ class Design extends BaseDesign
|
||||
{
|
||||
$elements = [];
|
||||
|
||||
if(!$this->vendor)
|
||||
return $elements;
|
||||
|
||||
$variables = $this->context['pdf_variables']['vendor_details'];
|
||||
|
||||
foreach ($variables as $variable) {
|
||||
@ -211,6 +217,9 @@ class Design extends BaseDesign
|
||||
{
|
||||
$elements = [];
|
||||
|
||||
if(!$this->client)
|
||||
return $elements;
|
||||
|
||||
if ($this->type == self::DELIVERY_NOTE) {
|
||||
$elements = [
|
||||
['element' => 'p', 'content' => ctrans('texts.delivery_note'), 'properties' => ['data-ref' => 'delivery_note-label', 'style' => 'font-weight: bold; text-transform: uppercase']],
|
||||
|
@ -30,6 +30,10 @@ trait DesignHelpers
|
||||
{
|
||||
$this->syncPdfVariables();
|
||||
|
||||
if (isset($this->context['vendor'])) {
|
||||
$this->vendor = $this->context['vendor'];
|
||||
}
|
||||
|
||||
if (isset($this->context['client'])) {
|
||||
$this->client = $this->context['client'];
|
||||
}
|
||||
|
@ -39,10 +39,13 @@ class CreateInvitations extends AbstractService
|
||||
$new_contact->is_primary = true;
|
||||
$new_contact->save();
|
||||
}
|
||||
|
||||
public function run()
|
||||
{
|
||||
$contacts = $this->purchase_order->vendor->contacts()->where('send_email', true)->get();
|
||||
|
||||
nlog("a");
|
||||
|
||||
if($contacts->count() == 0){
|
||||
$this->createBlankContact();
|
||||
|
||||
@ -50,6 +53,9 @@ class CreateInvitations extends AbstractService
|
||||
$contacts = $this->purchase_order->vendor->contacts;
|
||||
}
|
||||
|
||||
nlog("b");
|
||||
nlog($contacts->count());
|
||||
|
||||
$contacts->each(function ($contact) {
|
||||
$invitation = PurchaseOrderInvitation::where('company_id', $this->purchase_order->company_id)
|
||||
->where('vendor_contact_id', $contact->id)
|
||||
@ -58,16 +64,24 @@ class CreateInvitations extends AbstractService
|
||||
->first();
|
||||
|
||||
if (! $invitation) {
|
||||
try{
|
||||
$ii = PurchaseOrderInvitationFactory::create($this->purchase_order->company_id, $this->purchase_order->user_id);
|
||||
$ii->key = $this->createDbHash($this->purchase_order->company->db);
|
||||
$ii->purchase_order_id = $this->purchase_order->id;
|
||||
$ii->vendor_contact_id = $contact->id;
|
||||
$ii->save();
|
||||
}
|
||||
catch(\Exception $e){
|
||||
nlog($e->getMessage());
|
||||
}
|
||||
} elseif (! $contact->send_email) {
|
||||
$invitation->delete();
|
||||
}
|
||||
});
|
||||
|
||||
nlog("c");
|
||||
|
||||
|
||||
if($this->purchase_order->invitations()->count() == 0) {
|
||||
|
||||
if($contacts->count() == 0){
|
||||
@ -76,7 +90,7 @@ class CreateInvitations extends AbstractService
|
||||
else{
|
||||
$contact = $contacts->first();
|
||||
|
||||
$invitation = PurchaseOrder::where('company_id', $this->purchase_order->company_id)
|
||||
$invitation = PurchaseOrderInvitation::where('company_id', $this->purchase_order->company_id)
|
||||
->where('vendor_contact_id', $contact->id)
|
||||
->where('purchase_order_id', $this->purchase_order->id)
|
||||
->withTrashed()
|
||||
@ -88,6 +102,9 @@ class CreateInvitations extends AbstractService
|
||||
}
|
||||
}
|
||||
|
||||
nlog("d");
|
||||
|
||||
|
||||
$ii = PurchaseOrderInvitationFactory::create($this->purchase_order->company_id, $this->purchase_order->user_id);
|
||||
$ii->key = $this->createDbHash($this->purchase_order->company->db);
|
||||
$ii->purchase_order_id = $this->purchase_order->id;
|
||||
@ -95,6 +112,7 @@ class CreateInvitations extends AbstractService
|
||||
$ii->save();
|
||||
}
|
||||
|
||||
nlog("e");
|
||||
|
||||
return $this->purchase_order;
|
||||
}
|
||||
|
58
app/Services/PurchaseOrder/GetPurchaseOrderPdf.php
Normal file
58
app/Services/PurchaseOrder/GetPurchaseOrderPdf.php
Normal file
@ -0,0 +1,58 @@
|
||||
<?php
|
||||
/**
|
||||
* Invoice Ninja (https://invoiceninja.com).
|
||||
*
|
||||
* @link https://github.com/invoiceninja/invoiceninja source repository
|
||||
*
|
||||
* @copyright Copyright (c) 2022. Invoice Ninja LLC (https://invoiceninja.com)
|
||||
*
|
||||
* @license https://www.elastic.co/licensing/elastic-license
|
||||
*/
|
||||
|
||||
namespace App\Services\PurchaseOrder;
|
||||
|
||||
use App\Jobs\Vendor\CreatePurchaseOrderPdf;
|
||||
use App\Models\PurchaseOrder;
|
||||
use App\Models\VendorContact;
|
||||
use App\Services\AbstractService;
|
||||
use App\Utils\TempFile;
|
||||
use Illuminate\Support\Facades\Storage;
|
||||
|
||||
class GetPurchaseOrderPdf extends AbstractService
|
||||
{
|
||||
public function __construct(PurchaseOrder $purchase_order, VendorContact $contact = null)
|
||||
{
|
||||
$this->purchase_order = $purchase_order;
|
||||
|
||||
$this->contact = $contact;
|
||||
}
|
||||
|
||||
public function run()
|
||||
{
|
||||
|
||||
if (! $this->contact) {
|
||||
$this->contact = $this->purchase_order->vendor->contacts()->where('send_email', true)->first();
|
||||
}
|
||||
|
||||
$invitation = $this->purchase_order->invitations()->where('vendor_contact_id', $this->contact->id)->first();
|
||||
|
||||
if(!$invitation)
|
||||
$invitation = $this->purchase_order->invitations()->first();
|
||||
|
||||
$path = $this->purchase_order->vendor->purchase_order_filepath($invitation);
|
||||
|
||||
$file_path = $path.$this->purchase_order->numberFormatter().'.pdf';
|
||||
|
||||
// $disk = 'public';
|
||||
$disk = config('filesystems.default');
|
||||
|
||||
$file = Storage::disk($disk)->exists($file_path);
|
||||
|
||||
if (! $file) {
|
||||
$file_path = CreatePurchaseOrderPdf::dispatchNow($invitation);
|
||||
}
|
||||
|
||||
return $file_path;
|
||||
|
||||
}
|
||||
}
|
@ -15,6 +15,7 @@ namespace App\Services\PurchaseOrder;
|
||||
use App\Models\PurchaseOrder;
|
||||
use App\Services\PurchaseOrder\ApplyNumber;
|
||||
use App\Services\PurchaseOrder\CreateInvitations;
|
||||
use App\Services\PurchaseOrder\GetPurchaseOrderPdf;
|
||||
use App\Utils\Traits\MakesHash;
|
||||
|
||||
class PurchaseOrderService
|
||||
@ -23,7 +24,7 @@ class PurchaseOrderService
|
||||
|
||||
public PurchaseOrder $purchase_order;
|
||||
|
||||
public function __construct($purchase_order)
|
||||
public function __construct(PurchaseOrder $purchase_order)
|
||||
{
|
||||
$this->purchase_order = $purchase_order;
|
||||
}
|
||||
@ -61,6 +62,11 @@ class PurchaseOrderService
|
||||
return $this;
|
||||
}
|
||||
|
||||
public function getPurchaseOrderPdf($contact = null)
|
||||
{
|
||||
return (new GetPurchaseOrderPdf($this->purchase_order, $contact))->run();
|
||||
}
|
||||
|
||||
public function setStatus($status)
|
||||
{
|
||||
$this->purchase_order->status_id = $status;
|
||||
|
@ -52,7 +52,7 @@ class Helpers
|
||||
*
|
||||
* @return null|string
|
||||
*/
|
||||
public function formatCustomFieldValue($custom_fields, $field, $value, Client $client = null): ?string
|
||||
public function formatCustomFieldValue($custom_fields, $field, $value, $entity = null): ?string
|
||||
{
|
||||
$custom_field = '';
|
||||
|
||||
@ -67,7 +67,7 @@ class Helpers
|
||||
|
||||
switch ($custom_field) {
|
||||
case 'date':
|
||||
return is_null($client) ? $value : $this->translateDate($value, $client->date_format(), $client->locale());
|
||||
return is_null($entity) ? $value : $this->translateDate($value, $entity->date_format(), $entity->locale());
|
||||
break;
|
||||
|
||||
case 'switch':
|
||||
|
@ -130,7 +130,8 @@ class VendorHtmlEngine
|
||||
$data['$dueDate'] = &$data['$due_date'];
|
||||
|
||||
$data['$payment_due'] = ['value' => $this->translateDate($this->entity->due_date, $this->company->date_format(), $this->company->locale()) ?: ' ', 'label' => ctrans('texts.payment_due')];
|
||||
$data['$poNumber'] = &$data['$invoice.po_number'];
|
||||
$data['$poNumber'] = ['value' => $this->entity->po_number, 'label' => ctrans('texts.po_number')];
|
||||
|
||||
$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' => '<a class="button" href="'.$this->invitation->getPaymentLink().'">'.ctrans('texts.pay_now').'</a>', 'label' => ctrans('texts.pay_now')];
|
||||
@ -156,7 +157,7 @@ class VendorHtmlEngine
|
||||
$data['$portal_url'] = ['value' => $this->invitation->getPortalLink(), 'label' =>''];
|
||||
|
||||
$data['$entity_number'] = &$data['$number'];
|
||||
$data['$discount'] = &$data['$invoice.discount'];
|
||||
$data['$discount'] = ['value' => $this->entity->discount, 'label' => ctrans('texts.discount')];
|
||||
$data['$subtotal'] = ['value' => Number::formatMoney($this->entity_calc->getSubTotal(), $this->vendor) ?: ' ', 'label' => ctrans('texts.subtotal')];
|
||||
$data['$gross_subtotal'] = ['value' => Number::formatMoney($this->entity_calc->getGrossSubTotal(), $this->vendor) ?: ' ', 'label' => ctrans('texts.subtotal')];
|
||||
|
||||
@ -165,8 +166,6 @@ class VendorHtmlEngine
|
||||
else
|
||||
$data['$net_subtotal'] = ['value' => Number::formatMoney($this->entity_calc->getSubTotal() - $this->entity_calc->getTotalDiscount(), $this->vendor) ?: ' ', 'label' => ctrans('texts.net_subtotal')];
|
||||
|
||||
$data['$invoice.subtotal'] = &$data['$subtotal'];
|
||||
|
||||
if ($this->entity->partial > 0) {
|
||||
$data['$balance_due'] = ['value' => Number::formatMoney($this->entity->partial, $this->vendor) ?: ' ', 'label' => ctrans('texts.partial_due')];
|
||||
$data['$balance_due_raw'] = ['value' => $this->entity->partial, 'label' => ctrans('texts.partial_due')];
|
||||
@ -205,19 +204,19 @@ class VendorHtmlEngine
|
||||
$data['$created_by_user'] = &$data['$user.name'];
|
||||
$data['$assigned_to_user'] = ['value' => $this->entity->assigned_user ? $this->entity->assigned_user->present()->name() : '', 'label' => ctrans('texts.name')];
|
||||
|
||||
$data['$entity.public_notes'] = &$data['$invoice.public_notes'];
|
||||
$data['$public_notes'] = &$data['$invoice.public_notes'];
|
||||
$data['$public_notes'] = ['value' => $this->entity->public_notes, 'label' => ctrans("texts.public_notes")];
|
||||
$data['$entity.public_notes'] = &$data['$public_notes'];
|
||||
$data['$notes'] = &$data['$public_notes'];
|
||||
|
||||
$data['$purchase_order.custom1'] = ['value' => $this->helpers->formatCustomFieldValue($this->company->custom_fields, 'purchase_order1', $this->entity->custom_value1, $this->vendor) ?: ' ', 'label' => $this->helpers->makeCustomField($this->company->custom_fields, 'purchase_order1')];
|
||||
$data['$purchase_order.custom2'] = ['value' => $this->helpers->formatCustomFieldValue($this->company->custom_fields, 'purchase_order2', $this->entity->custom_value2, $this->vendor) ?: ' ', 'label' => $this->helpers->makeCustomField($this->company->custom_fields, 'purchase_order2')];
|
||||
$data['$purchase_order.custom3'] = ['value' => $this->helpers->formatCustomFieldValue($this->company->custom_fields, 'purchase_order3', $this->entity->custom_value3, $this->vendor) ?: ' ', 'label' => $this->helpers->makeCustomField($this->company->custom_fields, 'purchase_order3')];
|
||||
$data['$purchase_order.custom4'] = ['value' => $this->helpers->formatCustomFieldValue($this->company->custom_fields, 'purchase_order4', $this->entity->custom_value4, $this->vendor) ?: ' ', 'label' => $this->helpers->makeCustomField($this->company->custom_fields, 'purchase_order4')];
|
||||
$data['$purchase_order.custom1'] = ['value' => $this->helpers->formatCustomFieldValue($this->company->custom_fields, 'purchase_order1', $this->entity->custom_value1, $this->company) ?: ' ', 'label' => $this->helpers->makeCustomField($this->company->custom_fields, 'purchase_order1')];
|
||||
$data['$purchase_order.custom2'] = ['value' => $this->helpers->formatCustomFieldValue($this->company->custom_fields, 'purchase_order2', $this->entity->custom_value2, $this->company) ?: ' ', 'label' => $this->helpers->makeCustomField($this->company->custom_fields, 'purchase_order2')];
|
||||
$data['$purchase_order.custom3'] = ['value' => $this->helpers->formatCustomFieldValue($this->company->custom_fields, 'purchase_order3', $this->entity->custom_value3, $this->company) ?: ' ', 'label' => $this->helpers->makeCustomField($this->company->custom_fields, 'purchase_order3')];
|
||||
$data['$purchase_order.custom4'] = ['value' => $this->helpers->formatCustomFieldValue($this->company->custom_fields, 'purchase_order4', $this->entity->custom_value4, $this->company) ?: ' ', 'label' => $this->helpers->makeCustomField($this->company->custom_fields, 'purchase_order4')];
|
||||
|
||||
$data['$vendor1'] = ['value' => $this->helpers->formatCustomFieldValue($this->company->custom_fields, 'vendor1', $this->vendor->custom_value1, $this->vendor) ?: ' ', 'label' => $this->helpers->makeCustomField($this->company->custom_fields, 'vendor1')];
|
||||
$data['$vendor2'] = ['value' => $this->helpers->formatCustomFieldValue($this->company->custom_fields, 'vendor2', $this->vendor->custom_value2, $this->vendor) ?: ' ', 'label' => $this->helpers->makeCustomField($this->company->custom_fields, 'vendor2')];
|
||||
$data['$vendor3'] = ['value' => $this->helpers->formatCustomFieldValue($this->company->custom_fields, 'vendor3', $this->vendor->custom_value3, $this->vendor) ?: ' ', 'label' => $this->helpers->makeCustomField($this->company->custom_fields, 'vendor3')];
|
||||
$data['$vendor4'] = ['value' => $this->helpers->formatCustomFieldValue($this->company->custom_fields, 'vendor4', $this->vendor->custom_value4, $this->vendor) ?: ' ', 'label' => $this->helpers->makeCustomField($this->company->custom_fields, 'vendor4')];
|
||||
$data['$vendor1'] = ['value' => $this->helpers->formatCustomFieldValue($this->company->custom_fields, 'vendor1', $this->vendor->custom_value1, $this->company) ?: ' ', 'label' => $this->helpers->makeCustomField($this->company->custom_fields, 'vendor1')];
|
||||
$data['$vendor2'] = ['value' => $this->helpers->formatCustomFieldValue($this->company->custom_fields, 'vendor2', $this->vendor->custom_value2, $this->company) ?: ' ', 'label' => $this->helpers->makeCustomField($this->company->custom_fields, 'vendor2')];
|
||||
$data['$vendor3'] = ['value' => $this->helpers->formatCustomFieldValue($this->company->custom_fields, 'vendor3', $this->vendor->custom_value3, $this->company) ?: ' ', 'label' => $this->helpers->makeCustomField($this->company->custom_fields, 'vendor3')];
|
||||
$data['$vendor4'] = ['value' => $this->helpers->formatCustomFieldValue($this->company->custom_fields, 'vendor4', $this->vendor->custom_value4, $this->company) ?: ' ', 'label' => $this->helpers->makeCustomField($this->company->custom_fields, 'vendor4')];
|
||||
$data['$vendor.custom1'] = &$data['$vendor1'];
|
||||
$data['$vendor.custom2'] = &$data['$vendor2'];
|
||||
$data['$vendor.custom3'] = &$data['$vendor3'];
|
||||
@ -430,6 +429,8 @@ class VendorHtmlEngine
|
||||
$values = $this->buildEntityDataArray();
|
||||
|
||||
foreach ($values as $key => $value) {
|
||||
nlog($key);
|
||||
nlog($value);
|
||||
$data['values'][$key] = $value['value'];
|
||||
$data['labels'][$key.'_label'] = $value['label'];
|
||||
}
|
||||
|
@ -1,5 +1,6 @@
|
||||
<?php
|
||||
|
||||
use App\Models\Company;
|
||||
use Illuminate\Database\Migrations\Migration;
|
||||
use Illuminate\Database\Schema\Blueprint;
|
||||
use Illuminate\Support\Facades\Schema;
|
||||
@ -15,10 +16,10 @@ class CreatePurchaseOrderInvitationsTable extends Migration
|
||||
{
|
||||
Schema::create('purchase_order_invitations', function (Blueprint $table) {
|
||||
$table->id();
|
||||
$table->unsignedInteger('company_id')->index();
|
||||
$table->unsignedInteger('company_id');
|
||||
$table->unsignedInteger('user_id');
|
||||
$table->unsignedInteger('vendor_contact_id')->unique();
|
||||
$table->unsignedBigInteger('purchase_order_id')->index()->unique();
|
||||
$table->unsignedInteger('vendor_contact_id');
|
||||
$table->unsignedBigInteger('purchase_order_id')->index();
|
||||
$table->string('key')->index();
|
||||
$table->string('transaction_reference')->nullable();
|
||||
$table->string('message_id')->nullable()->index();
|
||||
@ -37,6 +38,8 @@ class CreatePurchaseOrderInvitationsTable extends Migration
|
||||
|
||||
$table->timestamps(6);
|
||||
$table->softDeletes('deleted_at', 6);
|
||||
$table->unique(['vendor_contact_id', 'purchase_order_id'], 'vendor_purchase_unique');
|
||||
$table->index(['deleted_at', 'purchase_order_id', 'company_id'], 'vendor_purchase_company_index');
|
||||
|
||||
});
|
||||
|
||||
@ -58,7 +61,8 @@ class CreatePurchaseOrderInvitationsTable extends Migration
|
||||
|
||||
$company->settings = $settings;
|
||||
$company->save();
|
||||
})
|
||||
});
|
||||
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -40,6 +40,39 @@ class PurchaseOrderTest extends TestCase
|
||||
|
||||
}
|
||||
|
||||
public function testPostNewPurchaseOrderPdf()
|
||||
{
|
||||
$purchase_order = [
|
||||
'status_id' => 1,
|
||||
'discount' => 0,
|
||||
'is_amount_discount' => 1,
|
||||
'number' => '34343xx43',
|
||||
'public_notes' => 'notes',
|
||||
'is_deleted' => 0,
|
||||
'custom_value1' => 0,
|
||||
'custom_value2' => 0,
|
||||
'custom_value3' => 0,
|
||||
'custom_value4' => 0,
|
||||
'status' => 1,
|
||||
'vendor_id' => $this->encodePrimaryKey($this->vendor->id),
|
||||
];
|
||||
|
||||
$response = $this->withHeaders([
|
||||
'X-API-SECRET' => config('ninja.api_secret'),
|
||||
'X-API-TOKEN' => $this->token,
|
||||
])->post('/api/v1/purchase_orders/', $purchase_order)
|
||||
->assertStatus(200);
|
||||
|
||||
$arr = $response->json();
|
||||
|
||||
$purchase_order = PurchaseOrder::find($this->decodePrimaryKey($arr['data']['id']));
|
||||
|
||||
$this->assertNotNull($purchase_order);
|
||||
|
||||
$purchase_order->service()->markSent()->getPurchaseOrderPdf();
|
||||
|
||||
}
|
||||
|
||||
public function testPurchaseOrderRest()
|
||||
{
|
||||
$response = $this->withHeaders([
|
||||
|
@ -294,6 +294,7 @@ trait MockAccountData
|
||||
$this->vendor = Vendor::factory()->create([
|
||||
'user_id' => $user_id,
|
||||
'company_id' => $this->company->id,
|
||||
'currency_id' => 1
|
||||
]);
|
||||
|
||||
|
||||
|
Loading…
x
Reference in New Issue
Block a user