mirror of
				https://github.com/invoiceninja/invoiceninja.git
				synced 2025-11-04 04:07:32 -05:00 
			
		
		
		
	
						commit
						f2bfca648f
					
				@ -276,6 +276,9 @@ class CompanySettings extends BaseSettings
 | 
				
			|||||||
    public $email_from_name = '';
 | 
					    public $email_from_name = '';
 | 
				
			||||||
    public $auto_archive_invoice_cancelled = false;
 | 
					    public $auto_archive_invoice_cancelled = false;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    public $purchase_order_number_counter = 1; //TODO
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    public static $casts = [
 | 
					    public static $casts = [
 | 
				
			||||||
        'page_numbering_alignment'           => 'string',
 | 
					        'page_numbering_alignment'           => 'string',
 | 
				
			||||||
        'page_numbering'                     => 'bool',
 | 
					        'page_numbering'                     => 'bool',
 | 
				
			||||||
@ -474,6 +477,7 @@ class CompanySettings extends BaseSettings
 | 
				
			|||||||
        'portal_custom_footer'               => 'string',
 | 
					        'portal_custom_footer'               => 'string',
 | 
				
			||||||
        'portal_custom_js'                   => 'string',
 | 
					        'portal_custom_js'                   => 'string',
 | 
				
			||||||
        'client_portal_enable_uploads'       => 'bool',
 | 
					        'client_portal_enable_uploads'       => 'bool',
 | 
				
			||||||
 | 
					        'purchase_order_number_counter'      => 'integer',
 | 
				
			||||||
    ];
 | 
					    ];
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    public static $free_plan_casts = [
 | 
					    public static $free_plan_casts = [
 | 
				
			||||||
 | 
				
			|||||||
							
								
								
									
										38
									
								
								app/Events/PurchaseOrder/PurchaseOrderWasMarkedSent.php
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										38
									
								
								app/Events/PurchaseOrder/PurchaseOrderWasMarkedSent.php
									
									
									
									
									
										Normal file
									
								
							@ -0,0 +1,38 @@
 | 
				
			|||||||
 | 
					<?php
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					namespace App\Events\PurchaseOrder;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					use App\Models\Company;
 | 
				
			||||||
 | 
					use App\Models\PurchaseOrder;
 | 
				
			||||||
 | 
					use Illuminate\Queue\SerializesModels;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					/**
 | 
				
			||||||
 | 
					 * Class PurchaseOrderWasMarkedSent.
 | 
				
			||||||
 | 
					 */
 | 
				
			||||||
 | 
					class PurchaseOrderWasMarkedSent
 | 
				
			||||||
 | 
					{
 | 
				
			||||||
 | 
					    use SerializesModels;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    /**
 | 
				
			||||||
 | 
					     * @var \App\Models\PurchaseOrder
 | 
				
			||||||
 | 
					     */
 | 
				
			||||||
 | 
					    public $purchase_order;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    public $company;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    public $event_vars;
 | 
				
			||||||
 | 
					    /**
 | 
				
			||||||
 | 
					     * Create a new event instance.
 | 
				
			||||||
 | 
					     *
 | 
				
			||||||
 | 
					     * @param PurchaseOrder $purchase_order
 | 
				
			||||||
 | 
					     * @param Company $company
 | 
				
			||||||
 | 
					     * @param array $event_vars
 | 
				
			||||||
 | 
					     */
 | 
				
			||||||
 | 
					    public function __construct(PurchaseOrder $purchase_order, Company $company, array $event_vars)
 | 
				
			||||||
 | 
					    {
 | 
				
			||||||
 | 
					        $this->purchase_order = $purchase_order;
 | 
				
			||||||
 | 
					        $this->company = $company;
 | 
				
			||||||
 | 
					        $this->event_vars = $event_vars;
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
							
								
								
									
										31
									
								
								app/Factory/PurchaseOrderInvitationFactory.php
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										31
									
								
								app/Factory/PurchaseOrderInvitationFactory.php
									
									
									
									
									
										Normal file
									
								
							@ -0,0 +1,31 @@
 | 
				
			|||||||
 | 
					<?php
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					namespace App\Factory;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					use App\Models\PurchaseOrderInvitation;
 | 
				
			||||||
 | 
					use Illuminate\Database\Eloquent\Model;
 | 
				
			||||||
 | 
					use Illuminate\Support\Str;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					class PurchaseOrderInvitationFactory
 | 
				
			||||||
 | 
					{
 | 
				
			||||||
 | 
					    public static function create(int $company_id, int $user_id) :PurchaseOrderInvitation
 | 
				
			||||||
 | 
					    {
 | 
				
			||||||
 | 
					        $ci = new PurchaseOrderInvitation();
 | 
				
			||||||
 | 
					        $ci->company_id = $company_id;
 | 
				
			||||||
 | 
					        $ci->user_id = $user_id;
 | 
				
			||||||
 | 
					        $ci->vendor_contact_id = null;
 | 
				
			||||||
 | 
					        $ci->purchase_order_id = null;
 | 
				
			||||||
 | 
					        $ci->key = Str::random(config('ninja.key_length'));
 | 
				
			||||||
 | 
					        $ci->transaction_reference = null;
 | 
				
			||||||
 | 
					        $ci->message_id = null;
 | 
				
			||||||
 | 
					        $ci->email_error = '';
 | 
				
			||||||
 | 
					        $ci->signature_base64 = '';
 | 
				
			||||||
 | 
					        $ci->signature_date = null;
 | 
				
			||||||
 | 
					        $ci->sent_date = null;
 | 
				
			||||||
 | 
					        $ci->viewed_date = null;
 | 
				
			||||||
 | 
					        $ci->opened_date = null;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        return $ci;
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
@ -22,6 +22,7 @@ use App\Models\ClientContact;
 | 
				
			|||||||
use App\Models\CreditInvitation;
 | 
					use App\Models\CreditInvitation;
 | 
				
			||||||
use App\Models\InvoiceInvitation;
 | 
					use App\Models\InvoiceInvitation;
 | 
				
			||||||
use App\Models\Payment;
 | 
					use App\Models\Payment;
 | 
				
			||||||
 | 
					use App\Models\PurchaseOrderInvitation;
 | 
				
			||||||
use App\Models\QuoteInvitation;
 | 
					use App\Models\QuoteInvitation;
 | 
				
			||||||
use App\Services\ClientPortal\InstantPayment;
 | 
					use App\Services\ClientPortal\InstantPayment;
 | 
				
			||||||
use App\Utils\CurlUtils;
 | 
					use App\Utils\CurlUtils;
 | 
				
			||||||
@ -279,6 +280,10 @@ class InvitationController extends Controller
 | 
				
			|||||||
            $invite = CreditInvitation::withTrashed()->where('key', $invitation_key)->first();
 | 
					            $invite = CreditInvitation::withTrashed()->where('key', $invitation_key)->first();
 | 
				
			||||||
            $invite->contact->send_email = false;
 | 
					            $invite->contact->send_email = false;
 | 
				
			||||||
            $invite->contact->save();
 | 
					            $invite->contact->save();
 | 
				
			||||||
 | 
					        }elseif($entity == 'purchase_order'){
 | 
				
			||||||
 | 
					            $invite = PurchaseOrderInvitation::withTrashed()->where('key', $invitation_key)->first();
 | 
				
			||||||
 | 
					            $invite->contact->send_email = false;
 | 
				
			||||||
 | 
					            $invite->contact->save();
 | 
				
			||||||
        }
 | 
					        }
 | 
				
			||||||
        else
 | 
					        else
 | 
				
			||||||
            return abort(404);
 | 
					            return abort(404);
 | 
				
			||||||
 | 
				
			|||||||
@ -12,8 +12,12 @@
 | 
				
			|||||||
namespace App\Models;
 | 
					namespace App\Models;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					use App\Jobs\Entity\CreateEntityPdf;
 | 
				
			||||||
use App\Services\PurchaseOrder\PurchaseOrderService;
 | 
					use App\Services\PurchaseOrder\PurchaseOrderService;
 | 
				
			||||||
 | 
					use App\Utils\Ninja;
 | 
				
			||||||
use Illuminate\Database\Eloquent\SoftDeletes;
 | 
					use Illuminate\Database\Eloquent\SoftDeletes;
 | 
				
			||||||
 | 
					use Illuminate\Support\Carbon;
 | 
				
			||||||
 | 
					use Illuminate\Support\Facades\Storage;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
class PurchaseOrder extends BaseModel
 | 
					class PurchaseOrder extends BaseModel
 | 
				
			||||||
{
 | 
					{
 | 
				
			||||||
@ -129,11 +133,52 @@ class PurchaseOrder extends BaseModel
 | 
				
			|||||||
    {
 | 
					    {
 | 
				
			||||||
        return $this->belongsTo(Client::class)->withTrashed();
 | 
					        return $this->belongsTo(Client::class)->withTrashed();
 | 
				
			||||||
    }
 | 
					    }
 | 
				
			||||||
 | 
					    public function markInvitationsSent()
 | 
				
			||||||
 | 
					    {
 | 
				
			||||||
 | 
					        $this->invitations->each(function ($invitation) {
 | 
				
			||||||
 | 
					            if (! isset($invitation->sent_date)) {
 | 
				
			||||||
 | 
					                $invitation->sent_date = Carbon::now();
 | 
				
			||||||
 | 
					                $invitation->save();
 | 
				
			||||||
 | 
					            }
 | 
				
			||||||
 | 
					        });
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    public function pdf_file_path($invitation = null, string $type = 'path', bool $portal = false)
 | 
				
			||||||
 | 
					    {
 | 
				
			||||||
 | 
					        if (! $invitation) {
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					            if($this->invitations()->exists())
 | 
				
			||||||
 | 
					                $invitation = $this->invitations()->first();
 | 
				
			||||||
 | 
					            else{
 | 
				
			||||||
 | 
					                $this->service()->createInvitations();
 | 
				
			||||||
 | 
					                $invitation = $this->invitations()->first();
 | 
				
			||||||
 | 
					            }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        if(!$invitation)
 | 
				
			||||||
 | 
					            throw new \Exception('Hard fail, could not create an invitation - is there a valid contact?');
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        $file_path = $this->client->credit_filepath($invitation).$this->numberFormatter().'.pdf';
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        if(Ninja::isHosted() && $portal && Storage::disk(config('filesystems.default'))->exists($file_path)){
 | 
				
			||||||
 | 
					            return Storage::disk(config('filesystems.default'))->{$type}($file_path);
 | 
				
			||||||
 | 
					        }
 | 
				
			||||||
 | 
					        elseif(Ninja::isHosted() && $portal){
 | 
				
			||||||
 | 
					            $file_path = CreateEntityPdf::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);
 | 
				
			||||||
 | 
					        return Storage::disk('public')->{$type}($file_path);
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    public function invitations()
 | 
					    public function invitations()
 | 
				
			||||||
    {
 | 
					    {
 | 
				
			||||||
        return $this->hasMany(CreditInvitation::class);
 | 
					        return $this->hasMany(PurchaseOrderInvitation::class);
 | 
				
			||||||
    }
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    public function project()
 | 
					    public function project()
 | 
				
			||||||
 | 
				
			|||||||
							
								
								
									
										81
									
								
								app/Models/PurchaseOrderInvitation.php
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										81
									
								
								app/Models/PurchaseOrderInvitation.php
									
									
									
									
									
										Normal file
									
								
							@ -0,0 +1,81 @@
 | 
				
			|||||||
 | 
					<?php
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					namespace App\Models;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					use App\Utils\Traits\Inviteable;
 | 
				
			||||||
 | 
					use App\Utils\Traits\MakesDates;
 | 
				
			||||||
 | 
					use Carbon\Carbon;
 | 
				
			||||||
 | 
					use Illuminate\Database\Eloquent\SoftDeletes;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					class PurchaseOrderInvitation extends BaseModel
 | 
				
			||||||
 | 
					{
 | 
				
			||||||
 | 
					    use MakesDates;
 | 
				
			||||||
 | 
					    use SoftDeletes;
 | 
				
			||||||
 | 
					    use Inviteable;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    protected $fillable = [
 | 
				
			||||||
 | 
					        'id',
 | 
				
			||||||
 | 
					        'vendor_contact_id',
 | 
				
			||||||
 | 
					    ];
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    protected $with = [
 | 
				
			||||||
 | 
					        'company',
 | 
				
			||||||
 | 
					        'contact',
 | 
				
			||||||
 | 
					    ];
 | 
				
			||||||
 | 
					    protected $touches = ['purchase_order'];
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    public function getEntityType()
 | 
				
			||||||
 | 
					    {
 | 
				
			||||||
 | 
					        return self::class;
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    public function entityType()
 | 
				
			||||||
 | 
					    {
 | 
				
			||||||
 | 
					        return PurchaseOrder::class;
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    /**
 | 
				
			||||||
 | 
					     * @return mixed
 | 
				
			||||||
 | 
					     */
 | 
				
			||||||
 | 
					    public function purchase_order()
 | 
				
			||||||
 | 
					    {
 | 
				
			||||||
 | 
					        return $this->belongsTo(PurchaseOrder::class)->withTrashed();
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    /**
 | 
				
			||||||
 | 
					     * @return mixed
 | 
				
			||||||
 | 
					     */
 | 
				
			||||||
 | 
					    public function contact()
 | 
				
			||||||
 | 
					    {
 | 
				
			||||||
 | 
					        return $this->belongsTo(VendorContact::class, 'vendor_contact_id', 'id')->withTrashed();
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    /**
 | 
				
			||||||
 | 
					     * @return mixed
 | 
				
			||||||
 | 
					     */
 | 
				
			||||||
 | 
					    public function user()
 | 
				
			||||||
 | 
					    {
 | 
				
			||||||
 | 
					        return $this->belongsTo(User::class)->withTrashed();
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    public function company()
 | 
				
			||||||
 | 
					    {
 | 
				
			||||||
 | 
					        return $this->belongsTo(Company::class);
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    public function getName()
 | 
				
			||||||
 | 
					    {
 | 
				
			||||||
 | 
					        return $this->key;
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    public function markViewed()
 | 
				
			||||||
 | 
					    {
 | 
				
			||||||
 | 
					        $this->viewed_date = Carbon::now();
 | 
				
			||||||
 | 
					        $this->save();
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
@ -136,4 +136,8 @@ class VendorContact extends Authenticatable implements HasLocalePreference
 | 
				
			|||||||
            ->withTrashed()
 | 
					            ->withTrashed()
 | 
				
			||||||
            ->where('id', $this->decodePrimaryKey($value))->firstOrFail();
 | 
					            ->where('id', $this->decodePrimaryKey($value))->firstOrFail();
 | 
				
			||||||
    }
 | 
					    }
 | 
				
			||||||
 | 
					    public function purchase_order_invitations(): \Illuminate\Database\Eloquent\Relations\HasMany
 | 
				
			||||||
 | 
					    {
 | 
				
			||||||
 | 
					        return $this->hasMany(PurchaseOrderInvitation::class);
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
				
			|||||||
@ -60,6 +60,7 @@ use App\Events\Payment\PaymentWasRefunded;
 | 
				
			|||||||
use App\Events\Payment\PaymentWasRestored;
 | 
					use App\Events\Payment\PaymentWasRestored;
 | 
				
			||||||
use App\Events\Payment\PaymentWasUpdated;
 | 
					use App\Events\Payment\PaymentWasUpdated;
 | 
				
			||||||
use App\Events\Payment\PaymentWasVoided;
 | 
					use App\Events\Payment\PaymentWasVoided;
 | 
				
			||||||
 | 
					use App\Events\PurchaseOrder\PurchaseOrderWasMarkedSent;
 | 
				
			||||||
use App\Events\Quote\QuoteWasApproved;
 | 
					use App\Events\Quote\QuoteWasApproved;
 | 
				
			||||||
use App\Events\Quote\QuoteWasArchived;
 | 
					use App\Events\Quote\QuoteWasArchived;
 | 
				
			||||||
use App\Events\Quote\QuoteWasCreated;
 | 
					use App\Events\Quote\QuoteWasCreated;
 | 
				
			||||||
@ -558,6 +559,8 @@ class EventServiceProvider extends ServiceProvider
 | 
				
			|||||||
        VendorWasUpdated::class => [
 | 
					        VendorWasUpdated::class => [
 | 
				
			||||||
            VendorUpdatedActivity::class,
 | 
					            VendorUpdatedActivity::class,
 | 
				
			||||||
        ],
 | 
					        ],
 | 
				
			||||||
 | 
					        PurchaseOrderWasMarkedSent::class => [
 | 
				
			||||||
 | 
					        ],
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    ];
 | 
					    ];
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
				
			|||||||
@ -13,6 +13,7 @@ namespace App\Repositories;
 | 
				
			|||||||
 | 
					
 | 
				
			||||||
 | 
					
 | 
				
			||||||
use App\Models\PurchaseOrder;
 | 
					use App\Models\PurchaseOrder;
 | 
				
			||||||
 | 
					use App\Models\PurchaseOrderInvitation;
 | 
				
			||||||
use App\Utils\Traits\MakesHash;
 | 
					use App\Utils\Traits\MakesHash;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
class PurchaseOrderRepository extends BaseRepository
 | 
					class PurchaseOrderRepository extends BaseRepository
 | 
				
			||||||
@ -30,5 +31,9 @@ class PurchaseOrderRepository extends BaseRepository
 | 
				
			|||||||
 | 
					
 | 
				
			||||||
        return $purchase_order;
 | 
					        return $purchase_order;
 | 
				
			||||||
    }
 | 
					    }
 | 
				
			||||||
 | 
					    public function getInvitationByKey($key) :?PurchaseOrderInvitation
 | 
				
			||||||
 | 
					    {
 | 
				
			||||||
 | 
					        return PurchaseOrderInvitation::where('key', $key)->first();
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
				
			|||||||
							
								
								
									
										59
									
								
								app/Services/PurchaseOrder/ApplyNumber.php
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										59
									
								
								app/Services/PurchaseOrder/ApplyNumber.php
									
									
									
									
									
										Normal file
									
								
							@ -0,0 +1,59 @@
 | 
				
			|||||||
 | 
					<?php
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					namespace App\Services\PurchaseOrder;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					use App\Models\Client;
 | 
				
			||||||
 | 
					use App\Models\Credit;
 | 
				
			||||||
 | 
					use App\Models\PurchaseOrder;
 | 
				
			||||||
 | 
					use App\Services\AbstractService;
 | 
				
			||||||
 | 
					use App\Utils\Traits\GeneratesCounter;
 | 
				
			||||||
 | 
					use Illuminate\Database\QueryException;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					class ApplyNumber extends AbstractService
 | 
				
			||||||
 | 
					{
 | 
				
			||||||
 | 
					    use GeneratesCounter;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    private Client $client;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    private PurchaseOrder $purchase_order;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    private bool $completed = true;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    public function __construct(Client $client, PurchaseOrder $purchase_order)
 | 
				
			||||||
 | 
					    {
 | 
				
			||||||
 | 
					        $this->client = $client;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        $this->purchase_order = $purchase_order;
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    public function run()
 | 
				
			||||||
 | 
					    {
 | 
				
			||||||
 | 
					        if ($this->purchase_order->number != '') {
 | 
				
			||||||
 | 
					            return $this->purchase_order;
 | 
				
			||||||
 | 
					        }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        $this->trySaving();
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        return $this->purchase_order;
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					    private function trySaving()
 | 
				
			||||||
 | 
					    {
 | 
				
			||||||
 | 
					        $x=1;
 | 
				
			||||||
 | 
					        do{
 | 
				
			||||||
 | 
					            try{
 | 
				
			||||||
 | 
					                $this->purchase_order->number = $this->getNextPurchaseOrderNumber($this->client, $this->purchase_order);
 | 
				
			||||||
 | 
					                $this->purchase_order->saveQuietly();
 | 
				
			||||||
 | 
					                $this->completed = false;
 | 
				
			||||||
 | 
					            }
 | 
				
			||||||
 | 
					            catch(QueryException $e){
 | 
				
			||||||
 | 
					                $x++;
 | 
				
			||||||
 | 
					                if($x>10)
 | 
				
			||||||
 | 
					                    $this->completed = false;
 | 
				
			||||||
 | 
					            }
 | 
				
			||||||
 | 
					        }
 | 
				
			||||||
 | 
					        while($this->completed);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
							
								
								
									
										91
									
								
								app/Services/PurchaseOrder/CreateInvitations.php
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										91
									
								
								app/Services/PurchaseOrder/CreateInvitations.php
									
									
									
									
									
										Normal file
									
								
							@ -0,0 +1,91 @@
 | 
				
			|||||||
 | 
					<?php
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					namespace App\Services\PurchaseOrder;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					use App\Factory\PurchaseOrderInvitationFactory;
 | 
				
			||||||
 | 
					use App\Models\PurchaseOrder;
 | 
				
			||||||
 | 
					use App\Models\PurchaseOrderInvitation;
 | 
				
			||||||
 | 
					use App\Services\AbstractService;
 | 
				
			||||||
 | 
					use App\Utils\Traits\MakesHash;
 | 
				
			||||||
 | 
					use Illuminate\Support\Str;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					class CreateInvitations extends AbstractService
 | 
				
			||||||
 | 
					{
 | 
				
			||||||
 | 
					    use MakesHash;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    public PurchaseOrder $purchase_order;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    public function __construct(PurchaseOrder $purchase_order)
 | 
				
			||||||
 | 
					    {
 | 
				
			||||||
 | 
					        $this->purchase_order = $purchase_order;
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					    private function createBlankContact()
 | 
				
			||||||
 | 
					    {
 | 
				
			||||||
 | 
					        $new_contact = PurchaseOrderInvitationFactory::create($this->purchase_order->company_id, $this->purchase_order->user_id);
 | 
				
			||||||
 | 
					        $new_contact->client_id = $this->purchase_order->client_id;
 | 
				
			||||||
 | 
					        $new_contact->contact_key = Str::random(40);
 | 
				
			||||||
 | 
					        $new_contact->is_primary = true;
 | 
				
			||||||
 | 
					        $new_contact->save();
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					    public function run()
 | 
				
			||||||
 | 
					    {
 | 
				
			||||||
 | 
					        $contacts = $this->purchase_order->vendor->contacts;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        if($contacts->count() == 0){
 | 
				
			||||||
 | 
					            $this->createBlankContact();
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					            $this->purchase_order->refresh();
 | 
				
			||||||
 | 
					            $contacts = $this->purchase_order->vendor->contacts;
 | 
				
			||||||
 | 
					        }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        $contacts->each(function ($contact) {
 | 
				
			||||||
 | 
					            $invitation = PurchaseOrderInvitation::whereCompanyId($this->purchase_order->company_id)
 | 
				
			||||||
 | 
					                ->whereClientContactId($contact->id)
 | 
				
			||||||
 | 
					                ->whereCreditId($this->purchase_order->id)
 | 
				
			||||||
 | 
					                ->withTrashed()
 | 
				
			||||||
 | 
					                ->first();
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					            if (! $invitation) {
 | 
				
			||||||
 | 
					                $ii = PurchaseOrderInvitation::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();
 | 
				
			||||||
 | 
					            } elseif (! $contact->send_email) {
 | 
				
			||||||
 | 
					                $invitation->delete();
 | 
				
			||||||
 | 
					            }
 | 
				
			||||||
 | 
					        });
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        if($this->purchase_order->invitations()->count() == 0) {
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					            if($contacts->count() == 0){
 | 
				
			||||||
 | 
					                $contact = $this->createBlankContact();
 | 
				
			||||||
 | 
					            }
 | 
				
			||||||
 | 
					            else{
 | 
				
			||||||
 | 
					                $contact = $contacts->first();
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					                $invitation = PurchaseOrder::where('company_id', $this->purchase_order->company_id)
 | 
				
			||||||
 | 
					                    ->where('vendor_contact_id', $contact->id)
 | 
				
			||||||
 | 
					                    ->where('purchase_order_id', $this->purchase_order->id)
 | 
				
			||||||
 | 
					                    ->withTrashed()
 | 
				
			||||||
 | 
					                    ->first();
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					                if($invitation){
 | 
				
			||||||
 | 
					                    $invitation->restore();
 | 
				
			||||||
 | 
					                    return $this->purchase_order;
 | 
				
			||||||
 | 
					                }
 | 
				
			||||||
 | 
					            }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					            $ii = PurchaseOrderInvitation::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();
 | 
				
			||||||
 | 
					        }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        return $this->purchase_order;
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
							
								
								
									
										45
									
								
								app/Services/PurchaseOrder/MarkSent.php
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										45
									
								
								app/Services/PurchaseOrder/MarkSent.php
									
									
									
									
									
										Normal file
									
								
							@ -0,0 +1,45 @@
 | 
				
			|||||||
 | 
					<?php
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					namespace App\Services\PurchaseOrder;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					use App\Events\PurchaseOrder\PurchaseOrderWasMarkedSent;
 | 
				
			||||||
 | 
					use App\Models\PurchaseOrder;
 | 
				
			||||||
 | 
					use App\Utils\Ninja;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					class MarkSent
 | 
				
			||||||
 | 
					{
 | 
				
			||||||
 | 
					    private $client;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    private $purchase_order;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    public function __construct($client, $purchase_order)
 | 
				
			||||||
 | 
					    {
 | 
				
			||||||
 | 
					        $this->client = $client;
 | 
				
			||||||
 | 
					        $this->purchase_order = $purchase_order;
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    public function run()
 | 
				
			||||||
 | 
					    {
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        /* Return immediately if status is not draft */
 | 
				
			||||||
 | 
					        if ($this->purchase_order->status_id != PurchaseOrder::STATUS_DRAFT) {
 | 
				
			||||||
 | 
					            return $this->purchase_order;
 | 
				
			||||||
 | 
					        }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        $this->purchase_order->markInvitationsSent();
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        $this->purchase_order
 | 
				
			||||||
 | 
					            ->service()
 | 
				
			||||||
 | 
					            ->setStatus(PurchaseOrder::STATUS_SENT)
 | 
				
			||||||
 | 
					            ->applyNumber()
 | 
				
			||||||
 | 
					            //  ->adjustBalance($this->purchase_order->amount)
 | 
				
			||||||
 | 
					            //  ->touchPdf()
 | 
				
			||||||
 | 
					            ->save();
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        event(new PurchaseOrderWasMarkedSent($this->purchase_order, $this->purchase_order->company, Ninja::eventVars(auth()->user() ? auth()->user()->id : null)));
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        return $this->purchase_order;
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
@ -52,6 +52,30 @@ class PurchaseOrderService
 | 
				
			|||||||
            $this->purchase_order->public_notes = $this->purchase_order->client->public_notes;
 | 
					            $this->purchase_order->public_notes = $this->purchase_order->client->public_notes;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        return $this;
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    public function setStatus($status)
 | 
				
			||||||
 | 
					    {
 | 
				
			||||||
 | 
					        $this->purchase_order->status_id = $status;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        return $this;
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    public function markSent()
 | 
				
			||||||
 | 
					    {
 | 
				
			||||||
 | 
					        $this->purchase_order = (new MarkSent($this->purchase_order->client, $this->purchase_order))->run();
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        return $this;
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					    /**
 | 
				
			||||||
 | 
					     * Applies the purchase order  number.
 | 
				
			||||||
 | 
					     * @return $this PurchaseOrderService object
 | 
				
			||||||
 | 
					     */
 | 
				
			||||||
 | 
					    public function applyNumber()
 | 
				
			||||||
 | 
					    {
 | 
				
			||||||
 | 
					        $this->purchase_order = (new ApplyNumber($this->purchase_order->client, $this->purchase_order))->run();
 | 
				
			||||||
 | 
					
 | 
				
			||||||
        return $this;
 | 
					        return $this;
 | 
				
			||||||
    }
 | 
					    }
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
				
			|||||||
							
								
								
									
										32
									
								
								app/Transformers/PurchaseOrderInvitationTransformer.php
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										32
									
								
								app/Transformers/PurchaseOrderInvitationTransformer.php
									
									
									
									
									
										Normal file
									
								
							@ -0,0 +1,32 @@
 | 
				
			|||||||
 | 
					<?php
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					namespace App\Transformers;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					use App\Models\PurchaseOrderInvitation;
 | 
				
			||||||
 | 
					use App\Utils\Traits\MakesHash;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					class PurchaseOrderInvitationTransformer extends EntityTransformer
 | 
				
			||||||
 | 
					{
 | 
				
			||||||
 | 
					    use MakesHash;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    public function transform(PurchaseOrderInvitation $invitation)
 | 
				
			||||||
 | 
					    {
 | 
				
			||||||
 | 
					        return [
 | 
				
			||||||
 | 
					            'id' => $this->encodePrimaryKey($invitation->id),
 | 
				
			||||||
 | 
					            'vendor_contact_id' => $this->encodePrimaryKey($invitation->vendor_contact_id),
 | 
				
			||||||
 | 
					            'key' => $invitation->key,
 | 
				
			||||||
 | 
					            'link' => $invitation->getLink() ?: '',
 | 
				
			||||||
 | 
					            'sent_date' => $invitation->sent_date ?: '',
 | 
				
			||||||
 | 
					            'viewed_date' => $invitation->viewed_date ?: '',
 | 
				
			||||||
 | 
					            'opened_date' => $invitation->opened_date ?: '',
 | 
				
			||||||
 | 
					            'updated_at' => (int)$invitation->updated_at,
 | 
				
			||||||
 | 
					            'archived_at' => (int)$invitation->deleted_at,
 | 
				
			||||||
 | 
					            'created_at' => (int)$invitation->created_at,
 | 
				
			||||||
 | 
					            'email_status' => $invitation->email_status ?: '',
 | 
				
			||||||
 | 
					            'email_error' => (string)$invitation->email_error,
 | 
				
			||||||
 | 
					        ];
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
@ -13,12 +13,24 @@ namespace App\Transformers;
 | 
				
			|||||||
 | 
					
 | 
				
			||||||
 | 
					
 | 
				
			||||||
use App\Models\PurchaseOrder;
 | 
					use App\Models\PurchaseOrder;
 | 
				
			||||||
 | 
					use App\Models\PurchaseOrderInvitation;
 | 
				
			||||||
use App\Utils\Traits\MakesHash;
 | 
					use App\Utils\Traits\MakesHash;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
class PurchaseOrderTransformer extends EntityTransformer
 | 
					class PurchaseOrderTransformer extends EntityTransformer
 | 
				
			||||||
{
 | 
					{
 | 
				
			||||||
    use MakesHash;
 | 
					    use MakesHash;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    protected $defaultIncludes = [
 | 
				
			||||||
 | 
					        'invitations',
 | 
				
			||||||
 | 
					    ];
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    public function includeInvitations(PurchaseOrder $purchase_order)
 | 
				
			||||||
 | 
					    {
 | 
				
			||||||
 | 
					        $transformer = new PurchaseOrderInvitationTransformer($this->serializer);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        return $this->includeCollection($purchase_order->invitations, $transformer, PurchaseOrderInvitation::class);
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    public function transform(PurchaseOrder $purchase_order)
 | 
					    public function transform(PurchaseOrder $purchase_order)
 | 
				
			||||||
    {
 | 
					    {
 | 
				
			||||||
        return [
 | 
					        return [
 | 
				
			||||||
@ -26,19 +38,18 @@ class PurchaseOrderTransformer extends EntityTransformer
 | 
				
			|||||||
            'user_id' => $this->encodePrimaryKey($purchase_order->user_id),
 | 
					            'user_id' => $this->encodePrimaryKey($purchase_order->user_id),
 | 
				
			||||||
            'project_id' => $this->encodePrimaryKey($purchase_order->project_id),
 | 
					            'project_id' => $this->encodePrimaryKey($purchase_order->project_id),
 | 
				
			||||||
            'assigned_user_id' => $this->encodePrimaryKey($purchase_order->assigned_user_id),
 | 
					            'assigned_user_id' => $this->encodePrimaryKey($purchase_order->assigned_user_id),
 | 
				
			||||||
            'vendor_id' => (string) $this->encodePrimaryKey($purchase_order->vendor_id),
 | 
					            'vendor_id' => (string)$this->encodePrimaryKey($purchase_order->vendor_id),
 | 
				
			||||||
            'amount' => (float) $purchase_order->amount,
 | 
					            'amount' => (float)$purchase_order->amount,
 | 
				
			||||||
            'balance' => (float) $purchase_order->balance,
 | 
					            'balance' => (float)$purchase_order->balance,
 | 
				
			||||||
            'client_id' => (string) $this->encodePrimaryKey($purchase_order->client_id),
 | 
					            'client_id' => (string)$this->encodePrimaryKey($purchase_order->client_id),
 | 
				
			||||||
            'vendor_id' => (string) $this->encodePrimaryKey($purchase_order->vendor_id),
 | 
					            'status_id' => (string)($purchase_order->status_id ?: 1),
 | 
				
			||||||
            'status_id' => (string) ($purchase_order->status_id ?: 1),
 | 
					            'design_id' => (string)$this->encodePrimaryKey($purchase_order->design_id),
 | 
				
			||||||
            'design_id' => (string) $this->encodePrimaryKey($purchase_order->design_id),
 | 
					            'created_at' => (int)$purchase_order->created_at,
 | 
				
			||||||
            'created_at' => (int) $purchase_order->created_at,
 | 
					            'updated_at' => (int)$purchase_order->updated_at,
 | 
				
			||||||
            'updated_at' => (int) $purchase_order->updated_at,
 | 
					            'archived_at' => (int)$purchase_order->deleted_at,
 | 
				
			||||||
            'archived_at' => (int) $purchase_order->deleted_at,
 | 
					            'is_deleted' => (bool)$purchase_order->is_deleted,
 | 
				
			||||||
            'is_deleted' => (bool) $purchase_order->is_deleted,
 | 
					 | 
				
			||||||
            'number' => $purchase_order->number ?: '',
 | 
					            'number' => $purchase_order->number ?: '',
 | 
				
			||||||
            'discount' => (float) $purchase_order->discount,
 | 
					            'discount' => (float)$purchase_order->discount,
 | 
				
			||||||
            'po_number' => $purchase_order->po_number ?: '',
 | 
					            'po_number' => $purchase_order->po_number ?: '',
 | 
				
			||||||
            'date' => $purchase_order->date ?: '',
 | 
					            'date' => $purchase_order->date ?: '',
 | 
				
			||||||
            'last_sent_date' => $purchase_order->last_sent_date ?: '',
 | 
					            'last_sent_date' => $purchase_order->last_sent_date ?: '',
 | 
				
			||||||
@ -51,36 +62,36 @@ class PurchaseOrderTransformer extends EntityTransformer
 | 
				
			|||||||
            'terms' => $purchase_order->terms ?: '',
 | 
					            'terms' => $purchase_order->terms ?: '',
 | 
				
			||||||
            'public_notes' => $purchase_order->public_notes ?: '',
 | 
					            'public_notes' => $purchase_order->public_notes ?: '',
 | 
				
			||||||
            'private_notes' => $purchase_order->private_notes ?: '',
 | 
					            'private_notes' => $purchase_order->private_notes ?: '',
 | 
				
			||||||
            'uses_inclusive_taxes' => (bool) $purchase_order->uses_inclusive_taxes,
 | 
					            'uses_inclusive_taxes' => (bool)$purchase_order->uses_inclusive_taxes,
 | 
				
			||||||
            'tax_name1' => $purchase_order->tax_name1 ? $purchase_order->tax_name1 : '',
 | 
					            'tax_name1' => $purchase_order->tax_name1 ? $purchase_order->tax_name1 : '',
 | 
				
			||||||
            'tax_rate1' => (float) $purchase_order->tax_rate1,
 | 
					            'tax_rate1' => (float)$purchase_order->tax_rate1,
 | 
				
			||||||
            'tax_name2' => $purchase_order->tax_name2 ? $purchase_order->tax_name2 : '',
 | 
					            'tax_name2' => $purchase_order->tax_name2 ? $purchase_order->tax_name2 : '',
 | 
				
			||||||
            'tax_rate2' => (float) $purchase_order->tax_rate2,
 | 
					            'tax_rate2' => (float)$purchase_order->tax_rate2,
 | 
				
			||||||
            'tax_name3' => $purchase_order->tax_name3 ? $purchase_order->tax_name3 : '',
 | 
					            'tax_name3' => $purchase_order->tax_name3 ? $purchase_order->tax_name3 : '',
 | 
				
			||||||
            'tax_rate3' => (float) $purchase_order->tax_rate3,
 | 
					            'tax_rate3' => (float)$purchase_order->tax_rate3,
 | 
				
			||||||
            'total_taxes' => (float) $purchase_order->total_taxes,
 | 
					            'total_taxes' => (float)$purchase_order->total_taxes,
 | 
				
			||||||
            'is_amount_discount' => (bool) ($purchase_order->is_amount_discount ?: false),
 | 
					            'is_amount_discount' => (bool)($purchase_order->is_amount_discount ?: false),
 | 
				
			||||||
            'footer' => $purchase_order->footer ?: '',
 | 
					            'footer' => $purchase_order->footer ?: '',
 | 
				
			||||||
            'partial' => (float) ($purchase_order->partial ?: 0.0),
 | 
					            'partial' => (float)($purchase_order->partial ?: 0.0),
 | 
				
			||||||
            'partial_due_date' => $purchase_order->partial_due_date ?: '',
 | 
					            'partial_due_date' => $purchase_order->partial_due_date ?: '',
 | 
				
			||||||
            'custom_value1' => (string) $purchase_order->custom_value1 ?: '',
 | 
					            'custom_value1' => (string)$purchase_order->custom_value1 ?: '',
 | 
				
			||||||
            'custom_value2' => (string) $purchase_order->custom_value2 ?: '',
 | 
					            'custom_value2' => (string)$purchase_order->custom_value2 ?: '',
 | 
				
			||||||
            'custom_value3' => (string) $purchase_order->custom_value3 ?: '',
 | 
					            'custom_value3' => (string)$purchase_order->custom_value3 ?: '',
 | 
				
			||||||
            'custom_value4' => (string) $purchase_order->custom_value4 ?: '',
 | 
					            'custom_value4' => (string)$purchase_order->custom_value4 ?: '',
 | 
				
			||||||
            'has_tasks' => (bool) $purchase_order->has_tasks,
 | 
					            'has_tasks' => (bool)$purchase_order->has_tasks,
 | 
				
			||||||
            'has_expenses' => (bool) $purchase_order->has_expenses,
 | 
					            'has_expenses' => (bool)$purchase_order->has_expenses,
 | 
				
			||||||
            'custom_surcharge1' => (float) $purchase_order->custom_surcharge1,
 | 
					            'custom_surcharge1' => (float)$purchase_order->custom_surcharge1,
 | 
				
			||||||
            'custom_surcharge2' => (float) $purchase_order->custom_surcharge2,
 | 
					            'custom_surcharge2' => (float)$purchase_order->custom_surcharge2,
 | 
				
			||||||
            'custom_surcharge3' => (float) $purchase_order->custom_surcharge3,
 | 
					            'custom_surcharge3' => (float)$purchase_order->custom_surcharge3,
 | 
				
			||||||
            'custom_surcharge4' => (float) $purchase_order->custom_surcharge4,
 | 
					            'custom_surcharge4' => (float)$purchase_order->custom_surcharge4,
 | 
				
			||||||
            'custom_surcharge_tax1' => (bool) $purchase_order->custom_surcharge_tax1,
 | 
					            'custom_surcharge_tax1' => (bool)$purchase_order->custom_surcharge_tax1,
 | 
				
			||||||
            'custom_surcharge_tax2' => (bool) $purchase_order->custom_surcharge_tax2,
 | 
					            'custom_surcharge_tax2' => (bool)$purchase_order->custom_surcharge_tax2,
 | 
				
			||||||
            'custom_surcharge_tax3' => (bool) $purchase_order->custom_surcharge_tax3,
 | 
					            'custom_surcharge_tax3' => (bool)$purchase_order->custom_surcharge_tax3,
 | 
				
			||||||
            'custom_surcharge_tax4' => (bool) $purchase_order->custom_surcharge_tax4,
 | 
					            'custom_surcharge_tax4' => (bool)$purchase_order->custom_surcharge_tax4,
 | 
				
			||||||
            'line_items' => $purchase_order->line_items ?: (array) [],
 | 
					            'line_items' => $purchase_order->line_items ?: (array)[],
 | 
				
			||||||
            'entity_type' => 'credit',
 | 
					            'entity_type' => 'credit',
 | 
				
			||||||
            'exchange_rate' => (float) $purchase_order->exchange_rate,
 | 
					            'exchange_rate' => (float)$purchase_order->exchange_rate,
 | 
				
			||||||
            'paid_to_date' => (float) $purchase_order->paid_to_date,
 | 
					            'paid_to_date' => (float)$purchase_order->paid_to_date,
 | 
				
			||||||
            'subscription_id' => $this->encodePrimaryKey($purchase_order->subscription_id),
 | 
					            'subscription_id' => $this->encodePrimaryKey($purchase_order->subscription_id),
 | 
				
			||||||
        ];
 | 
					        ];
 | 
				
			||||||
    }
 | 
					    }
 | 
				
			||||||
 | 
				
			|||||||
@ -18,6 +18,7 @@ use App\Models\Expense;
 | 
				
			|||||||
use App\Models\Invoice;
 | 
					use App\Models\Invoice;
 | 
				
			||||||
use App\Models\Payment;
 | 
					use App\Models\Payment;
 | 
				
			||||||
use App\Models\Project;
 | 
					use App\Models\Project;
 | 
				
			||||||
 | 
					use App\Models\PurchaseOrder;
 | 
				
			||||||
use App\Models\Quote;
 | 
					use App\Models\Quote;
 | 
				
			||||||
use App\Models\RecurringExpense;
 | 
					use App\Models\RecurringExpense;
 | 
				
			||||||
use App\Models\RecurringInvoice;
 | 
					use App\Models\RecurringInvoice;
 | 
				
			||||||
@ -153,6 +154,9 @@ trait GeneratesCounter
 | 
				
			|||||||
            case Project::class:
 | 
					            case Project::class:
 | 
				
			||||||
                return 'project_number_counter';
 | 
					                return 'project_number_counter';
 | 
				
			||||||
                break;
 | 
					                break;
 | 
				
			||||||
 | 
					            case PurchaseOrder::class:
 | 
				
			||||||
 | 
					                return 'purchase_order_number_counter';
 | 
				
			||||||
 | 
					                break;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
            default:
 | 
					            default:
 | 
				
			||||||
                return 'default_number_counter';
 | 
					                return 'default_number_counter';
 | 
				
			||||||
@ -188,6 +192,20 @@ trait GeneratesCounter
 | 
				
			|||||||
 | 
					
 | 
				
			||||||
        return $this->replaceUserVars($credit, $entity_number);
 | 
					        return $this->replaceUserVars($credit, $entity_number);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					    /**
 | 
				
			||||||
 | 
					     * Gets the next purchase order number.
 | 
				
			||||||
 | 
					     *
 | 
				
			||||||
 | 
					     * @param PurchaseOrder $purchase_order  The purchase order
 | 
				
			||||||
 | 
					     *
 | 
				
			||||||
 | 
					     * @return     string              The next purchase order number.
 | 
				
			||||||
 | 
					     */
 | 
				
			||||||
 | 
					    public function getNextPurchaseOrderNumber(Client $client, ?PurchaseOrder $purchase_order) :string
 | 
				
			||||||
 | 
					    {
 | 
				
			||||||
 | 
					        $entity_number = $this->getNextEntityNumber(PurchaseOrder::class, $client);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        return $this->replaceUserVars($purchase_order, $entity_number);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    }
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    /**
 | 
					    /**
 | 
				
			||||||
@ -558,6 +576,7 @@ trait GeneratesCounter
 | 
				
			|||||||
        $settings->invoice_number_counter = 1;
 | 
					        $settings->invoice_number_counter = 1;
 | 
				
			||||||
        $settings->quote_number_counter = 1;
 | 
					        $settings->quote_number_counter = 1;
 | 
				
			||||||
        $settings->credit_number_counter = 1;
 | 
					        $settings->credit_number_counter = 1;
 | 
				
			||||||
 | 
					        $settings->purchase_order_number_counter = 1;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
        $client->company->settings = $settings;
 | 
					        $client->company->settings = $settings;
 | 
				
			||||||
        $client->company->save();
 | 
					        $client->company->save();
 | 
				
			||||||
@ -622,6 +641,7 @@ trait GeneratesCounter
 | 
				
			|||||||
        $settings->task_number_counter = 1;
 | 
					        $settings->task_number_counter = 1;
 | 
				
			||||||
        $settings->expense_number_counter = 1;
 | 
					        $settings->expense_number_counter = 1;
 | 
				
			||||||
        $settings->recurring_expense_number_counter =1;
 | 
					        $settings->recurring_expense_number_counter =1;
 | 
				
			||||||
 | 
					        $settings->purchase_order_number_counter = 1;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
        $company->settings = $settings;
 | 
					        $company->settings = $settings;
 | 
				
			||||||
        $company->save();
 | 
					        $company->save();
 | 
				
			||||||
 | 
				
			|||||||
							
								
								
									
										31
									
								
								database/factories/PurchaseOrderInvitationFactory.php
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										31
									
								
								database/factories/PurchaseOrderInvitationFactory.php
									
									
									
									
									
										Normal file
									
								
							@ -0,0 +1,31 @@
 | 
				
			|||||||
 | 
					<?php
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					namespace Database\Factories;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					use App\Models\PurchaseOrderInvitation;
 | 
				
			||||||
 | 
					use Illuminate\Database\Eloquent\Factories\Factory;
 | 
				
			||||||
 | 
					use Illuminate\Support\Str;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					class PurchaseOrderInvitationFactory extends Factory
 | 
				
			||||||
 | 
					{
 | 
				
			||||||
 | 
					    /**
 | 
				
			||||||
 | 
					     * The name of the factory's corresponding model.
 | 
				
			||||||
 | 
					     *
 | 
				
			||||||
 | 
					     * @var string
 | 
				
			||||||
 | 
					     */
 | 
				
			||||||
 | 
					    protected $model = PurchaseOrderInvitation::class;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    /**
 | 
				
			||||||
 | 
					     * Define the model's default state.
 | 
				
			||||||
 | 
					     *
 | 
				
			||||||
 | 
					     * @return array
 | 
				
			||||||
 | 
					     */
 | 
				
			||||||
 | 
					    public function definition()
 | 
				
			||||||
 | 
					    {
 | 
				
			||||||
 | 
					        return [
 | 
				
			||||||
 | 
					            'key' => Str::random(40),
 | 
				
			||||||
 | 
					        ];
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
@ -0,0 +1,53 @@
 | 
				
			|||||||
 | 
					<?php
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					use Illuminate\Database\Migrations\Migration;
 | 
				
			||||||
 | 
					use Illuminate\Database\Schema\Blueprint;
 | 
				
			||||||
 | 
					use Illuminate\Support\Facades\Schema;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					class CreatePurchaseOrderInvitationsTable extends Migration
 | 
				
			||||||
 | 
					{
 | 
				
			||||||
 | 
					    /**
 | 
				
			||||||
 | 
					     * Run the migrations.
 | 
				
			||||||
 | 
					     *
 | 
				
			||||||
 | 
					     * @return void
 | 
				
			||||||
 | 
					     */
 | 
				
			||||||
 | 
					    public function up()
 | 
				
			||||||
 | 
					    {
 | 
				
			||||||
 | 
					        Schema::create('purchase_order_invitations', function (Blueprint $table) {
 | 
				
			||||||
 | 
					            $table->id();
 | 
				
			||||||
 | 
					            $table->unsignedInteger('company_id')->index();
 | 
				
			||||||
 | 
					            $table->unsignedInteger('user_id');
 | 
				
			||||||
 | 
					            $table->unsignedInteger('vendor_contact_id')->unique();
 | 
				
			||||||
 | 
					            $table->unsignedBigInteger('purchase_order_id')->index()->unique();
 | 
				
			||||||
 | 
					            $table->string('key')->index();
 | 
				
			||||||
 | 
					            $table->string('transaction_reference')->nullable();
 | 
				
			||||||
 | 
					            $table->string('message_id')->nullable()->index();
 | 
				
			||||||
 | 
					            $table->mediumText('email_error')->nullable();
 | 
				
			||||||
 | 
					            $table->text('signature_base64')->nullable();
 | 
				
			||||||
 | 
					            $table->datetime('signature_date')->nullable();
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					            $table->datetime('sent_date')->nullable();
 | 
				
			||||||
 | 
					            $table->datetime('viewed_date')->nullable();
 | 
				
			||||||
 | 
					            $table->datetime('opened_date')->nullable();
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					            $table->foreign('user_id')->references('id')->on('users')->onDelete('cascade')->onUpdate('cascade');
 | 
				
			||||||
 | 
					            $table->foreign('vendor_contact_id')->references('id')->on('vendor_contacts')->onDelete('cascade')->onUpdate('cascade');
 | 
				
			||||||
 | 
					            $table->foreign('purchase_order_id')->references('id')->on('purchase_orders')->onDelete('cascade')->onUpdate('cascade');
 | 
				
			||||||
 | 
					            $table->foreign('company_id')->references('id')->on('companies')->onDelete('cascade')->onUpdate('cascade');
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					            $table->timestamps(6);
 | 
				
			||||||
 | 
					            $table->softDeletes('deleted_at', 6);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        });
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    /**
 | 
				
			||||||
 | 
					     * Reverse the migrations.
 | 
				
			||||||
 | 
					     *
 | 
				
			||||||
 | 
					     * @return void
 | 
				
			||||||
 | 
					     */
 | 
				
			||||||
 | 
					    public function down()
 | 
				
			||||||
 | 
					    {
 | 
				
			||||||
 | 
					        Schema::dropIfExists('purchase_order_invitations');
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
@ -37,6 +37,7 @@ class PurchaseOrderTest extends TestCase
 | 
				
			|||||||
        Model::reguard();
 | 
					        Model::reguard();
 | 
				
			||||||
 | 
					
 | 
				
			||||||
        $this->makeTestData();
 | 
					        $this->makeTestData();
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    }
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    public function testPurchaseOrderRest()
 | 
					    public function testPurchaseOrderRest()
 | 
				
			||||||
@ -44,18 +45,18 @@ class PurchaseOrderTest extends TestCase
 | 
				
			|||||||
        $response = $this->withHeaders([
 | 
					        $response = $this->withHeaders([
 | 
				
			||||||
            'X-API-SECRET' => config('ninja.api_secret'),
 | 
					            'X-API-SECRET' => config('ninja.api_secret'),
 | 
				
			||||||
            'X-API-TOKEN' => $this->token,
 | 
					            'X-API-TOKEN' => $this->token,
 | 
				
			||||||
        ])->get('/api/v1/purchase_orders/'.$this->encodePrimaryKey($this->purchase_order->id));
 | 
					        ])->get('/api/v1/purchase_orders/' . $this->encodePrimaryKey($this->purchase_order->id));
 | 
				
			||||||
 | 
					
 | 
				
			||||||
        $response->assertStatus(200);
 | 
					        $response->assertStatus(200);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
        $response = $this->withHeaders([
 | 
					        $response = $this->withHeaders([
 | 
				
			||||||
            'X-API-SECRET' => config('ninja.api_secret'),
 | 
					            'X-API-SECRET' => config('ninja.api_secret'),
 | 
				
			||||||
            'X-API-TOKEN' => $this->token,
 | 
					            'X-API-TOKEN' => $this->token,
 | 
				
			||||||
        ])->get('/api/v1/purchase_orders/'.$this->encodePrimaryKey($this->purchase_order->id).'/edit');
 | 
					        ])->get('/api/v1/purchase_orders/' . $this->encodePrimaryKey($this->purchase_order->id) . '/edit');
 | 
				
			||||||
 | 
					
 | 
				
			||||||
        $response->assertStatus(200);
 | 
					        $response->assertStatus(200);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
        $credit_update = [
 | 
					        $purchase_order_update = [
 | 
				
			||||||
            'tax_name1' => 'dippy',
 | 
					            'tax_name1' => 'dippy',
 | 
				
			||||||
        ];
 | 
					        ];
 | 
				
			||||||
 | 
					
 | 
				
			||||||
@ -64,14 +65,14 @@ class PurchaseOrderTest extends TestCase
 | 
				
			|||||||
        $response = $this->withHeaders([
 | 
					        $response = $this->withHeaders([
 | 
				
			||||||
            'X-API-SECRET' => config('ninja.api_secret'),
 | 
					            'X-API-SECRET' => config('ninja.api_secret'),
 | 
				
			||||||
            'X-API-TOKEN' => $this->token,
 | 
					            'X-API-TOKEN' => $this->token,
 | 
				
			||||||
        ])->put('/api/v1/purchase_orders/'.$this->encodePrimaryKey($this->purchase_order->id), $credit_update)
 | 
					        ])->put('/api/v1/purchase_orders/' . $this->encodePrimaryKey($this->purchase_order->id), $purchase_order_update)
 | 
				
			||||||
            ->assertStatus(200);
 | 
					            ->assertStatus(200);
 | 
				
			||||||
    }
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    public function testPostNewPurchaseOrder()
 | 
					    public function testPostNewPurchaseOrder()
 | 
				
			||||||
    {
 | 
					    {
 | 
				
			||||||
        $purchase_order = [
 | 
					        $purchase_order = [
 | 
				
			||||||
            'status_id' => 1,
 | 
					            'status_id' => 1,
 | 
				
			||||||
            'number' => 'dfdfd',
 | 
					 | 
				
			||||||
            'discount' => 0,
 | 
					            'discount' => 0,
 | 
				
			||||||
            'is_amount_discount' => 1,
 | 
					            'is_amount_discount' => 1,
 | 
				
			||||||
            'number' => '34343xx43',
 | 
					            'number' => '34343xx43',
 | 
				
			||||||
@ -91,20 +92,21 @@ class PurchaseOrderTest extends TestCase
 | 
				
			|||||||
        ])->post('/api/v1/purchase_orders/', $purchase_order)
 | 
					        ])->post('/api/v1/purchase_orders/', $purchase_order)
 | 
				
			||||||
            ->assertStatus(200);
 | 
					            ->assertStatus(200);
 | 
				
			||||||
    }
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    public function testPurchaseOrderDelete()
 | 
					    public function testPurchaseOrderDelete()
 | 
				
			||||||
    {
 | 
					    {
 | 
				
			||||||
        $response = $this->withHeaders([
 | 
					        $response = $this->withHeaders([
 | 
				
			||||||
            'X-API-SECRET' => config('ninja.api_secret'),
 | 
					            'X-API-SECRET' => config('ninja.api_secret'),
 | 
				
			||||||
            'X-API-TOKEN' => $this->token,
 | 
					            'X-API-TOKEN' => $this->token,
 | 
				
			||||||
        ])->delete('/api/v1/purchase_orders/'.$this->encodePrimaryKey($this->purchase_order->id));
 | 
					        ])->delete('/api/v1/purchase_orders/' . $this->encodePrimaryKey($this->purchase_order->id));
 | 
				
			||||||
 | 
					
 | 
				
			||||||
        $response->assertStatus(200);
 | 
					        $response->assertStatus(200);
 | 
				
			||||||
    }
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    public function testPurchaseOrderUpdate()
 | 
					    public function testPurchaseOrderUpdate()
 | 
				
			||||||
    {
 | 
					    {
 | 
				
			||||||
        $data = [
 | 
					        $data = [
 | 
				
			||||||
            'status_id' => 1,
 | 
					            'status_id' => 1,
 | 
				
			||||||
            'number' => 'dfdfd',
 | 
					 | 
				
			||||||
            'discount' => 0,
 | 
					            'discount' => 0,
 | 
				
			||||||
            'is_amount_discount' => 1,
 | 
					            'is_amount_discount' => 1,
 | 
				
			||||||
            'number' => '3434343',
 | 
					            'number' => '3434343',
 | 
				
			||||||
@ -121,14 +123,14 @@ class PurchaseOrderTest extends TestCase
 | 
				
			|||||||
        $response = $this->withHeaders([
 | 
					        $response = $this->withHeaders([
 | 
				
			||||||
            'X-API-SECRET' => config('ninja.api_secret'),
 | 
					            'X-API-SECRET' => config('ninja.api_secret'),
 | 
				
			||||||
            'X-API-TOKEN' => $this->token,
 | 
					            'X-API-TOKEN' => $this->token,
 | 
				
			||||||
        ])->put('/api/v1/purchase_orders/'.$this->encodePrimaryKey($this->purchase_order->id), $data);
 | 
					        ])->put('/api/v1/purchase_orders/' . $this->encodePrimaryKey($this->purchase_order->id), $data);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
        $response->assertStatus(200);
 | 
					        $response->assertStatus(200);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
        $response = $this->withHeaders([
 | 
					        $response = $this->withHeaders([
 | 
				
			||||||
            'X-API-SECRET' => config('ninja.api_secret'),
 | 
					            'X-API-SECRET' => config('ninja.api_secret'),
 | 
				
			||||||
            'X-API-TOKEN' => $this->token,
 | 
					            'X-API-TOKEN' => $this->token,
 | 
				
			||||||
        ])->put('/api/v1/purchase_orders/'.$this->encodePrimaryKey($this->purchase_order->id), $data);
 | 
					        ])->put('/api/v1/purchase_orders/' . $this->encodePrimaryKey($this->purchase_order->id), $data);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
        $response->assertStatus(200);
 | 
					        $response->assertStatus(200);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
				
			|||||||
@ -36,6 +36,8 @@ use App\Models\GroupSetting;
 | 
				
			|||||||
use App\Models\InvoiceInvitation;
 | 
					use App\Models\InvoiceInvitation;
 | 
				
			||||||
use App\Models\Product;
 | 
					use App\Models\Product;
 | 
				
			||||||
use App\Models\Project;
 | 
					use App\Models\Project;
 | 
				
			||||||
 | 
					use App\Models\PurchaseOrder;
 | 
				
			||||||
 | 
					use App\Models\PurchaseOrderInvitation;
 | 
				
			||||||
use App\Models\Quote;
 | 
					use App\Models\Quote;
 | 
				
			||||||
use App\Models\QuoteInvitation;
 | 
					use App\Models\QuoteInvitation;
 | 
				
			||||||
use App\Models\RecurringExpense;
 | 
					use App\Models\RecurringExpense;
 | 
				
			||||||
@ -476,6 +478,26 @@ trait MockAccountData
 | 
				
			|||||||
        $this->purchase_order->save();
 | 
					        $this->purchase_order->save();
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        PurchaseOrderInvitation::factory()->create([
 | 
				
			||||||
 | 
					            'user_id' => $user_id,
 | 
				
			||||||
 | 
					            'company_id' => $this->company->id,
 | 
				
			||||||
 | 
					            'vendor_contact_id' => $vendor_contact->id,
 | 
				
			||||||
 | 
					            'purchase_order_id' => $this->purchase_order->id,
 | 
				
			||||||
 | 
					        ]);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        $purchase_order_invitations = PurchaseOrderInvitation::whereCompanyId($this->purchase_order->company_id)
 | 
				
			||||||
 | 
					            ->wherePurchaseOrderId($this->purchase_order->id);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        $this->purchase_order->setRelation('invitations', $purchase_order_invitations);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        $this->purchase_order->service()->markSent();
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        $this->purchase_order->setRelation('client', $this->client);
 | 
				
			||||||
 | 
					        $this->purchase_order->setRelation('company', $this->company);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        $this->purchase_order->save();
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					
 | 
				
			||||||
        $this->credit = CreditFactory::create($this->company->id, $user_id);
 | 
					        $this->credit = CreditFactory::create($this->company->id, $user_id);
 | 
				
			||||||
 | 
				
			|||||||
		Loading…
	
	
			
			x
			
			
		
	
		Reference in New Issue
	
	Block a user