mirror of
				https://github.com/invoiceninja/invoiceninja.git
				synced 2025-11-03 23:27:31 -05:00 
			
		
		
		
	Fixes for purchase orders
This commit is contained in:
		
							parent
							
								
									4a2ecdb6a7
								
							
						
					
					
						commit
						f9685035cd
					
				@ -279,11 +279,8 @@ 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 = [
 | 
				
			||||||
        'purchase_order_number_pattern'      => 'purchase_order_number_pattern',
 | 
					        'purchase_order_number_pattern'      => 'string',
 | 
				
			||||||
        'purchase_order_number_counter'      => 'int',
 | 
					        'purchase_order_number_counter'      => 'int',
 | 
				
			||||||
        'page_numbering_alignment'           => 'string',
 | 
					        'page_numbering_alignment'           => 'string',
 | 
				
			||||||
        'page_numbering'                     => 'bool',
 | 
					        'page_numbering'                     => 'bool',
 | 
				
			||||||
 | 
				
			|||||||
@ -1,11 +1,18 @@
 | 
				
			|||||||
<?php
 | 
					<?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;
 | 
					namespace App\Services\PurchaseOrder;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					
 | 
				
			||||||
use App\Models\Client;
 | 
					use App\Models\Vendor;
 | 
				
			||||||
use App\Models\Credit;
 | 
					 | 
				
			||||||
use App\Models\PurchaseOrder;
 | 
					use App\Models\PurchaseOrder;
 | 
				
			||||||
use App\Services\AbstractService;
 | 
					use App\Services\AbstractService;
 | 
				
			||||||
use App\Utils\Traits\GeneratesCounter;
 | 
					use App\Utils\Traits\GeneratesCounter;
 | 
				
			||||||
@ -15,15 +22,15 @@ class ApplyNumber extends AbstractService
 | 
				
			|||||||
{
 | 
					{
 | 
				
			||||||
    use GeneratesCounter;
 | 
					    use GeneratesCounter;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    private Client $client;
 | 
					    public Vendor $vendor;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    private PurchaseOrder $purchase_order;
 | 
					    private PurchaseOrder $purchase_order;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    private bool $completed = true;
 | 
					    private bool $completed = true;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    public function __construct(Client $client, PurchaseOrder $purchase_order)
 | 
					    public function __construct(Vendor $vendor, PurchaseOrder $purchase_order)
 | 
				
			||||||
    {
 | 
					    {
 | 
				
			||||||
        $this->client = $client;
 | 
					        $this->vendor = $vendor;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
        $this->purchase_order = $purchase_order;
 | 
					        $this->purchase_order = $purchase_order;
 | 
				
			||||||
    }
 | 
					    }
 | 
				
			||||||
@ -43,7 +50,7 @@ class ApplyNumber extends AbstractService
 | 
				
			|||||||
        $x=1;
 | 
					        $x=1;
 | 
				
			||||||
        do{
 | 
					        do{
 | 
				
			||||||
            try{
 | 
					            try{
 | 
				
			||||||
                $this->purchase_order->number = $this->getNextPurchaseOrderNumber($this->client, $this->purchase_order);
 | 
					                $this->purchase_order->number = $this->getNextPurchaseOrderNumber($this->purchase_order);
 | 
				
			||||||
                $this->purchase_order->saveQuietly();
 | 
					                $this->purchase_order->saveQuietly();
 | 
				
			||||||
                $this->completed = false;
 | 
					                $this->completed = false;
 | 
				
			||||||
            }
 | 
					            }
 | 
				
			||||||
 | 
				
			|||||||
@ -1,10 +1,19 @@
 | 
				
			|||||||
<?php
 | 
					<?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;
 | 
					namespace App\Services\PurchaseOrder;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					 | 
				
			||||||
use App\Factory\PurchaseOrderInvitationFactory;
 | 
					use App\Factory\PurchaseOrderInvitationFactory;
 | 
				
			||||||
 | 
					use App\Factory\VendorContactFactory;
 | 
				
			||||||
use App\Models\PurchaseOrder;
 | 
					use App\Models\PurchaseOrder;
 | 
				
			||||||
use App\Models\PurchaseOrderInvitation;
 | 
					use App\Models\PurchaseOrderInvitation;
 | 
				
			||||||
use App\Services\AbstractService;
 | 
					use App\Services\AbstractService;
 | 
				
			||||||
@ -21,17 +30,18 @@ class CreateInvitations extends AbstractService
 | 
				
			|||||||
    {
 | 
					    {
 | 
				
			||||||
        $this->purchase_order = $purchase_order;
 | 
					        $this->purchase_order = $purchase_order;
 | 
				
			||||||
    }
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    private function createBlankContact()
 | 
					    private function createBlankContact()
 | 
				
			||||||
    {
 | 
					    {
 | 
				
			||||||
        $new_contact = PurchaseOrderInvitationFactory::create($this->purchase_order->company_id, $this->purchase_order->user_id);
 | 
					        $new_contact = VendorContactFactory::create($this->purchase_order->company_id, $this->purchase_order->user_id);
 | 
				
			||||||
        $new_contact->client_id = $this->purchase_order->client_id;
 | 
					        $new_contact->vendor_id = $this->purchase_order->vendor_id;
 | 
				
			||||||
        $new_contact->contact_key = Str::random(40);
 | 
					        $new_contact->contact_key = Str::random(40);
 | 
				
			||||||
        $new_contact->is_primary = true;
 | 
					        $new_contact->is_primary = true;
 | 
				
			||||||
        $new_contact->save();
 | 
					        $new_contact->save();
 | 
				
			||||||
    }
 | 
					    }
 | 
				
			||||||
    public function run()
 | 
					    public function run()
 | 
				
			||||||
    {
 | 
					    {
 | 
				
			||||||
        $contacts = $this->purchase_order->vendor->contacts;
 | 
					        $contacts = $this->purchase_order->vendor->contacts()->where('send_email', true)->get();
 | 
				
			||||||
 | 
					
 | 
				
			||||||
        if($contacts->count() == 0){
 | 
					        if($contacts->count() == 0){
 | 
				
			||||||
            $this->createBlankContact();
 | 
					            $this->createBlankContact();
 | 
				
			||||||
@ -41,14 +51,14 @@ class CreateInvitations extends AbstractService
 | 
				
			|||||||
        }
 | 
					        }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
        $contacts->each(function ($contact) {
 | 
					        $contacts->each(function ($contact) {
 | 
				
			||||||
            $invitation = PurchaseOrderInvitation::whereCompanyId($this->purchase_order->company_id)
 | 
					            $invitation = PurchaseOrderInvitation::where('company_id', $this->purchase_order->company_id)
 | 
				
			||||||
                ->whereClientContactId($contact->id)
 | 
					                ->where('vendor_contact_id', $contact->id)
 | 
				
			||||||
                ->whereCreditId($this->purchase_order->id)
 | 
					                ->where('purchase_order_id', $this->purchase_order->id)
 | 
				
			||||||
                ->withTrashed()
 | 
					                ->withTrashed()
 | 
				
			||||||
                ->first();
 | 
					                ->first();
 | 
				
			||||||
 | 
					
 | 
				
			||||||
            if (! $invitation) {
 | 
					            if (! $invitation) {
 | 
				
			||||||
                $ii = PurchaseOrderInvitation::create($this->purchase_order->company_id, $this->purchase_order->user_id);
 | 
					                $ii = PurchaseOrderInvitationFactory::create($this->purchase_order->company_id, $this->purchase_order->user_id);
 | 
				
			||||||
                $ii->key = $this->createDbHash($this->purchase_order->company->db);
 | 
					                $ii->key = $this->createDbHash($this->purchase_order->company->db);
 | 
				
			||||||
                $ii->purchase_order_id = $this->purchase_order->id;
 | 
					                $ii->purchase_order_id = $this->purchase_order->id;
 | 
				
			||||||
                $ii->vendor_contact_id = $contact->id;
 | 
					                $ii->vendor_contact_id = $contact->id;
 | 
				
			||||||
@ -78,7 +88,7 @@ class CreateInvitations extends AbstractService
 | 
				
			|||||||
                }
 | 
					                }
 | 
				
			||||||
            }
 | 
					            }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
            $ii = PurchaseOrderInvitation::create($this->purchase_order->company_id, $this->purchase_order->user_id);
 | 
					            $ii = PurchaseOrderInvitationFactory::create($this->purchase_order->company_id, $this->purchase_order->user_id);
 | 
				
			||||||
            $ii->key = $this->createDbHash($this->purchase_order->company->db);
 | 
					            $ii->key = $this->createDbHash($this->purchase_order->company->db);
 | 
				
			||||||
            $ii->purchase_order_id = $this->purchase_order->id;
 | 
					            $ii->purchase_order_id = $this->purchase_order->id;
 | 
				
			||||||
            $ii->vendor_contact_id = $contact->id;
 | 
					            $ii->vendor_contact_id = $contact->id;
 | 
				
			||||||
 | 
				
			|||||||
@ -1,5 +1,13 @@
 | 
				
			|||||||
<?php
 | 
					<?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;
 | 
					namespace App\Services\PurchaseOrder;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
				
			|||||||
@ -28,17 +28,6 @@ class PurchaseOrderService
 | 
				
			|||||||
        $this->purchase_order = $purchase_order;
 | 
					        $this->purchase_order = $purchase_order;
 | 
				
			||||||
    }
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    /**
 | 
					 | 
				
			||||||
     * Saves the purchase order.
 | 
					 | 
				
			||||||
     * @return \App\Models\PurchaseOrder object
 | 
					 | 
				
			||||||
     */
 | 
					 | 
				
			||||||
    public function save(): ?PurchaseOrder
 | 
					 | 
				
			||||||
    {
 | 
					 | 
				
			||||||
        $this->purchase_order->saveQuietly();
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
        return $this->purchase_order;
 | 
					 | 
				
			||||||
    }
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
    public function createInvitations()
 | 
					    public function createInvitations()
 | 
				
			||||||
    {
 | 
					    {
 | 
				
			||||||
 | 
					
 | 
				
			||||||
@ -86,4 +75,15 @@ class PurchaseOrderService
 | 
				
			|||||||
        return $this;
 | 
					        return $this;
 | 
				
			||||||
    }
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    /**
 | 
				
			||||||
 | 
					     * Saves the purchase order.
 | 
				
			||||||
 | 
					     * @return \App\Models\PurchaseOrder object
 | 
				
			||||||
 | 
					     */
 | 
				
			||||||
 | 
					    public function save(): ?PurchaseOrder
 | 
				
			||||||
 | 
					    {
 | 
				
			||||||
 | 
					        $this->purchase_order->saveQuietly();
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        return $this->purchase_order;
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
				
			|||||||
@ -196,20 +196,6 @@ 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);
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
    }
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    /**
 | 
					    /**
 | 
				
			||||||
@ -376,7 +362,7 @@ trait GeneratesCounter
 | 
				
			|||||||
 | 
					
 | 
				
			||||||
        $purchase_order_number = $this->checkEntityNumber(PurchaseOrder::class, $purchase_order, $counter, $purchase_order->company->settings->counter_padding, $purchase_order->company->settings->purchase_order_number_pattern);
 | 
					        $purchase_order_number = $this->checkEntityNumber(PurchaseOrder::class, $purchase_order, $counter, $purchase_order->company->settings->counter_padding, $purchase_order->company->settings->purchase_order_number_pattern);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
        $this->incrementCounter($purchase_order->company, 'purchase_order_number_pattern');
 | 
					        $this->incrementCounter($purchase_order->company, 'purchase_order_number_counter');
 | 
				
			||||||
 | 
					
 | 
				
			||||||
        $entity_number = $purchase_order_number;
 | 
					        $entity_number = $purchase_order_number;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
				
			|||||||
@ -39,6 +39,11 @@ class CreatePurchaseOrderInvitationsTable extends Migration
 | 
				
			|||||||
            $table->softDeletes('deleted_at', 6);
 | 
					            $table->softDeletes('deleted_at', 6);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
        });
 | 
					        });
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        Schema::table('purchase_orders', function (Blueprint $table) {
 | 
				
			||||||
 | 
					            $table->unsignedInteger('client_id')->nullable()->change();
 | 
				
			||||||
 | 
					        });
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    }
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    /**
 | 
					    /**
 | 
				
			||||||
 | 
				
			|||||||
@ -83,7 +83,7 @@ class PurchaseOrderTest extends TestCase
 | 
				
			|||||||
            'custom_value3' => 0,
 | 
					            'custom_value3' => 0,
 | 
				
			||||||
            'custom_value4' => 0,
 | 
					            'custom_value4' => 0,
 | 
				
			||||||
            'status' => 1,
 | 
					            'status' => 1,
 | 
				
			||||||
            'client_id' => $this->encodePrimaryKey($this->client->id),
 | 
					            'vendor_id' => $this->encodePrimaryKey($this->vendor->id),
 | 
				
			||||||
        ];
 | 
					        ];
 | 
				
			||||||
 | 
					
 | 
				
			||||||
        $response = $this->withHeaders([
 | 
					        $response = $this->withHeaders([
 | 
				
			||||||
@ -117,7 +117,7 @@ class PurchaseOrderTest extends TestCase
 | 
				
			|||||||
            'custom_value3' => 0,
 | 
					            'custom_value3' => 0,
 | 
				
			||||||
            'custom_value4' => 0,
 | 
					            'custom_value4' => 0,
 | 
				
			||||||
            'status' => 1,
 | 
					            'status' => 1,
 | 
				
			||||||
            'client_id' => $this->encodePrimaryKey($this->client->id),
 | 
					            'vendor_id' => $this->encodePrimaryKey($this->vendor->id),
 | 
				
			||||||
        ];
 | 
					        ];
 | 
				
			||||||
 | 
					
 | 
				
			||||||
        $response = $this->withHeaders([
 | 
					        $response = $this->withHeaders([
 | 
				
			||||||
 | 
				
			|||||||
@ -450,22 +450,12 @@ trait MockAccountData
 | 
				
			|||||||
 | 
					
 | 
				
			||||||
        $this->quote->save();
 | 
					        $this->quote->save();
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
        $this->purchase_order = PurchaseOrderFactory::create($this->company->id, $user_id);
 | 
					        $this->purchase_order = PurchaseOrderFactory::create($this->company->id, $user_id);
 | 
				
			||||||
        $this->purchase_order->client_id = $this->client->id;
 | 
					        $this->purchase_order->vendor_id = $this->vendor->id;
 | 
				
			||||||
 | 
					 | 
				
			||||||
 | 
					
 | 
				
			||||||
        $this->purchase_order->amount = 10;
 | 
					        $this->purchase_order->amount = 10;
 | 
				
			||||||
        $this->purchase_order->balance = 10;
 | 
					        $this->purchase_order->balance = 10;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
        // $this->credit->due_date = now()->addDays(200);
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
        $this->purchase_order->tax_name1 = '';
 | 
					        $this->purchase_order->tax_name1 = '';
 | 
				
			||||||
        $this->purchase_order->tax_name2 = '';
 | 
					        $this->purchase_order->tax_name2 = '';
 | 
				
			||||||
        $this->purchase_order->tax_name3 = '';
 | 
					        $this->purchase_order->tax_name3 = '';
 | 
				
			||||||
 | 
				
			|||||||
		Loading…
	
	
			
			x
			
			
		
	
		Reference in New Issue
	
	Block a user