Skip to content

Commit

Permalink
Merge pull request #149 from Blair2004/purchase-order-improvements
Browse files Browse the repository at this point in the history
Purchase order improvements
  • Loading branch information
Blair2004 authored Mar 14, 2021
2 parents 9a4dc13 + 44bfde2 commit 3313f0b
Show file tree
Hide file tree
Showing 42 changed files with 1,383 additions and 423 deletions.
65 changes: 65 additions & 0 deletions app/Console/Commands/RecreateBarcodeForProductsCommand.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,65 @@
<?php

namespace App\Console\Commands;

use Illuminate\Console\Command;
use App\Services\BarcodeService;
use App\Services\ProductService;
use App\Models\Product;

class RecreateBarcodeForProductsCommand extends Command
{
/**
* The name and signature of the console command.
*
* @var string
*/
protected $signature = 'ns:products {operation}';

/**
* The console command description.
*
* @var string
*/
protected $description = 'Perform various bulk operations on products';

/**
* The barcode service used to generate barcode
*
* @var ProductService $barcodeService
*/
protected $productService;

/**
* Create a new command instance.
*
* @return void
*/
public function __construct(
ProductService $productService
)
{
parent::__construct();

$this->productService = $productService;
}

/**
* Execute the console command.
*
* @return int
*/
public function handle()
{
if ( $this->argument( 'operation' ) === 'refresh-barcode' ) {
$products = $this->withProgressBar( Product::get(), function( $product ) {
$this->productService->generateProductBarcode( $product );
});

$this->newLine();
return $this->info( __( 'The product barcodes has been refreshed successfully.' ) );
}

return $this->error( __( 'Invalid operation provided.' ) );
}
}
10 changes: 10 additions & 0 deletions app/Crud/ProductCrud.php
Original file line number Diff line number Diff line change
Expand Up @@ -302,6 +302,16 @@ public function getForm( $entry = null )
'label' => __( 'Units' ),
'fields' => [
[
'type' => 'switch',
'description' => __( 'The product won\'t be visible on the grid and fetched only using the barcode reader or associated barcode.' ),
'options' => Helper::kvToJsOptions([
true => __( 'Yes' ),
false => __( 'No' ),
]),
'name' => 'accurate_tracking',
'label' => __( 'Accurate Tracking' ),
'value' => $entry->accurate_tracking ?? false,
], [
'type' => 'select',
'options' => Helper::toJsOptions( $groups, [ 'id', 'name' ] ),
'name' => 'unit_group',
Expand Down
39 changes: 39 additions & 0 deletions app/Events/ProductAfterCreatedEvent.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,39 @@
<?php

namespace App\Events;

use App\Models\Product;
use Illuminate\Broadcasting\Channel;
use Illuminate\Broadcasting\InteractsWithSockets;
use Illuminate\Broadcasting\PresenceChannel;
use Illuminate\Broadcasting\PrivateChannel;
use Illuminate\Contracts\Broadcasting\ShouldBroadcast;
use Illuminate\Foundation\Events\Dispatchable;
use Illuminate\Queue\SerializesModels;

class ProductAfterCreatedEvent
{
use Dispatchable, InteractsWithSockets, SerializesModels;

public $product;

/**
* Create a new event instance.
*
* @return void
*/
public function __construct( Product $product )
{
$this->product = $product;
}

/**
* Get the channels the event should broadcast on.
*
* @return \Illuminate\Broadcasting\Channel|array
*/
public function broadcastOn()
{
return new PrivateChannel('channel-name');
}
}
39 changes: 39 additions & 0 deletions app/Events/ProductAfterUpdatedEvent.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,39 @@
<?php

namespace App\Events;

use App\Models\Product;
use Illuminate\Broadcasting\Channel;
use Illuminate\Broadcasting\InteractsWithSockets;
use Illuminate\Broadcasting\PresenceChannel;
use Illuminate\Broadcasting\PrivateChannel;
use Illuminate\Contracts\Broadcasting\ShouldBroadcast;
use Illuminate\Foundation\Events\Dispatchable;
use Illuminate\Queue\SerializesModels;

class ProductAfterUpdatedEvent
{
use Dispatchable, InteractsWithSockets, SerializesModels;

public $product;

/**
* Create a new event instance.
*
* @return void
*/
public function __construct( Product $product )
{
$this->product = $product;
}

/**
* Get the channels the event should broadcast on.
*
* @return \Illuminate\Broadcasting\Channel|array
*/
public function broadcastOn()
{
return new PrivateChannel('channel-name');
}
}
9 changes: 6 additions & 3 deletions app/Http/Controllers/Dashboard/CategoryController.php
Original file line number Diff line number Diff line change
Expand Up @@ -231,12 +231,15 @@ public function getCategories( $id = '0' )
$category = ProductCategory::where( 'id', $id )
->displayOnPOS()
->with( 'subCategories' )
->with( 'products.galleries' )
->first();

return [
'products' => $category->products,
'categories' => $category->subCategories()
'products' => $category->products()
->with( 'galleries' )
->trackingDisabled()
->get(),
'categories' => $category
->subCategories()
->displayOnPOS()
->get(),
'previousCategory' => ProductCategory::find( $category->parent_id ) ?? null, // means should return to the root
Expand Down
69 changes: 65 additions & 4 deletions app/Http/Controllers/Dashboard/ProductsController.php
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,7 @@
use App\Classes\Output;
use App\Crud\ProductHistoryCrud;
use App\Crud\ProductUnitQuantitiesCrud;
use App\Exceptions\NotAllowedException;
use App\Exceptions\NotFoundException;
use App\Http\Controllers\DashboardController;
use App\Models\ProcurementProduct;
Expand All @@ -25,6 +26,7 @@
use App\Models\Unit;
use App\Models\ProductUnitQuantity;
use App\Services\CrudService;
use App\Services\DateService;
use App\Services\Helper;
use App\Services\ProductService;
use App\Services\Options;
Expand All @@ -37,13 +39,20 @@ class ProductsController extends DashboardController
/** @var ProductService */
protected $productService;

/**
* @var DateService
*/
protected $dateService;

public function __construct(
ProductService $productService
ProductService $productService,
DateService $dateService
)
{
parent::__construct();

$this->productService = $productService;
$this->dateService = $dateService;
}

public function saveProduct( Request $request )
Expand Down Expand Up @@ -523,19 +532,71 @@ public function createAdjustment( Request $request )

public function searchUsingArgument( $reference )
{
$product = Product::barcode( $reference )
$procurementProduct = ProcurementProduct::barcode( $reference )->first();
$productUnitQuantity = ProductUnitQuantity::barcode( $reference )->first();
$product = Product::barcode( $reference )
->searchable()
->with( 'unit_quantities' )
->first();

if ( $procurementProduct instanceof ProcurementProduct ) {

$product = $procurementProduct->product;

/**
* check if the product has expired
* and the sales are disallowed.
*/
if (
$this->dateService->copy()->greaterThan( $procurementProduct->expiration_date ) &&
$product->expires &&
$product->on_expiration === Product::EXPIRES_PREVENT_SALES ) {
throw new NotAllowedException( __( 'Unable to add the product to the cart as it has expired.' ) );
}

/**
* We need to add a reference of the procurement product
* in order to deplete the available quantity accordingly.
* Will also be helpful to track how products are sold.
*/
$product->procurement_product_id = $procurementProduct->id;

} else if ( $productUnitQuantity instanceof ProductUnitQuantity ) {

/**
* if a product unit quantity is loaded. Then we make sure to return the parent
* product with the selected unit quantity.
*/
$productUnitQuantity->load( 'unit' );

$product = Product::find( $productUnitQuantity->product_id );
$product->load( 'unit_quantities' );
$product->selectedUnitQuantity = $productUnitQuantity;

} else if ( $product instanceof Product ) {

$product->load( 'unit_quantities' );

if ( $product->accurate_tracking ) {
throw new NotAllowedException( __( 'Unable to add a product that has accurate tracking enabled, using an ordinary barcode.' ) );
}
}

if ( $product instanceof Product ) {
return [
'type' => 'product',
'product' => $product
];
}

throw new NotFoundException( __( 'The product request cannot be found.' ) );
throw new NotFoundException( __( 'There is no products matching the current request.' ) );
}

public function printLabels()
{
return $this->view( 'pages.dashboard.products.print-labels', [
'title' => __( 'Print Labels' ),
'description' => __( 'Customize and print products labels.' ),
]);
}
}

2 changes: 1 addition & 1 deletion app/Http/Middleware/CheckApplicationHealthMiddleware.php
Original file line number Diff line number Diff line change
Expand Up @@ -49,7 +49,7 @@ public function handle(Request $request, Closure $next)
}

/**
* we'll check here is a module is missing a
* we'll check here is a module has a missing
* dependency to disable it
* @var ModulesService
*/
Expand Down
38 changes: 37 additions & 1 deletion app/Listeners/ProductEventsSubscriber.php
Original file line number Diff line number Diff line change
@@ -1,11 +1,14 @@
<?php
namespace App\Listeners;

use App\Events\ProductAfterCreatedEvent;
use App\Services\ProductService;
use App\Events\ProductAfterDeleteEvent;
use App\Events\ProductAfterStockAdjustmentEvent;
use App\Events\ProductAfterUpdatedEvent;
use App\Events\ProductBeforeDeleteEvent;
use App\Jobs\HandleStockAdjustmentJob;
use App\Services\BarcodeService;
use App\Services\ProcurementService;
use App\Services\ReportService;

Expand All @@ -20,14 +23,19 @@ class ProductEventsSubscriber
/** @var ReportService */
protected $reportService;

/** @var BarcodeService */
protected $barcodeService;

public function __construct(
ProductService $productService,
ProcurementService $procurementService,
ReportService $reportService
ReportService $reportService,
BarcodeService $barcodeService
) {
$this->productService = $productService;
$this->procurementService = $procurementService;
$this->reportService = $reportService;
$this->barcodeService = $barcodeService;
}

public function subscribe( $events )
Expand All @@ -46,6 +54,16 @@ public function subscribe( $events )
ProductAfterStockAdjustmentEvent::class,
[ ProductEventsSubscriber::class, 'afterStockAdjustment' ]
);

$events->listen(
ProductAfterCreatedEvent::class,
[ ProductEventsSubscriber::class, 'generateBarcode' ]
);

$events->listen(
ProductAfterUpdatedEvent::class,
[ ProductEventsSubscriber::class, 'generateBarcode' ]
);
}

public function beforeDeleteProduct( ProductBeforeDeleteEvent $event )
Expand All @@ -67,6 +85,24 @@ public function beforeDeleteProduct( ProductBeforeDeleteEvent $event )
});
}

public function generateBarcode( $event )
{
$this->barcodeService->generateBarcode(
$event->product->barcode,
$event->product->barcode_type
);

/**
* save barcode for unit quantities
*/
$event->product->unit_quantities->each( function( $unitQuantity ) use ( $event ) {
$this->barcodeService->generateBarcode(
$unitQuantity->barcode,
$event->product->barcode_type
);
});
}

public function afterStockAdjustment( ProductAfterStockAdjustmentEvent $event )
{
HandleStockAdjustmentJob::dispatch( $event )
Expand Down
Loading

0 comments on commit 3313f0b

Please sign in to comment.