Merge branch 'transaction-invoice' into 'development'

Transaction invoice

See merge request CIEFWorldwideSdnBhd/shipping-portal!105
This commit is contained in:
Leong Chee Siong
2022-02-12 04:00:37 +00:00
13 changed files with 483 additions and 93 deletions
@@ -0,0 +1,13 @@
<?php
namespace App\Classes\General\Interfaces;
use Illuminate\Database\Eloquent\Relations\MorphMany;
interface Transactionable
{
public function transactions(): morphMany;
}
@@ -0,0 +1,34 @@
<?php
namespace App\Classes\Modules\SegmentConstants\Services;
use App\Classes\General\Eloquent\AbstractFetchRecord;
use Illuminate\Database\Eloquent\Builder;
use App\Models\SegmentConstant;
class FetchesSegmentConstant extends AbstractFetchRecord
{
/** @var SegmentConstant */
private $repository;
/**
* FetchesSegment constructor.
* @param SegmentConstant $repository
*/
public function __construct(SegmentConstant $repository)
{
$this->repository = $repository;
}
/**
* @return Builder
*/
public function getRepository(): Builder
{
return $this->repository->newQuery();
}
}
@@ -0,0 +1,192 @@
<?php
namespace App\Classes\Modules\Transactions\ControllersLogic;
use App\Classes\General\Abstracts\AbstractControllerLogic;
use App\Classes\Modules\PackingLists\Services\FetchesPackingList;
use App\Classes\Modules\SegmentConstants\Services\FetchesSegmentConstant;
use App\Classes\Modules\Transactions\Services\GeneratesTransactionBillNumber;
use App\Classes\Modules\Transactions\Services\CreatesTransaction;
use App\Classes\Modules\Transactions\DataTransferObjects\TransactionObject;
use App\Classes\ValueObjects\Constants\OrderRoleTypes;
use App\Classes\ValueObjects\Constants\TransactionType;
use App\Classes\ValueObjects\Constants\PaymentMethodType;
use App\Classes\ValueObjects\Constants\ApprovalStatus;
// use App\Classes\Modules\Documents\DataTransferObjects\DocumentObject;
// use App\Classes\Modules\Transactions\Services\FetchesTransaction;
// use App\Classes\Modules\Transactions\Services\UpdatesTransactionStatus;
// use App\Classes\Modules\Documents\Services\CreatesDocument;
// use App\Classes\Modules\Documents\Services\CreatesFiles;
// use App\Classes\ValueObjects\Constants\DocumentType;
// use App\Models\Document;
// use App\Models\Transaction;
// use Barryvdh\DomPDF\PDF;
// use Carbon\Carbon;
use Illuminate\Http\JsonResponse;
use Illuminate\Http\Request;
use Illuminate\Support\Facades\Storage;
use Illuminate\Support\Str;
// use Meneses\LaravelLaravelMpdf\Facades\LaravelLaravelMpdf;
// use Meneses\LaravelMpdf\Facades\LaravelMpdf;
class CreateShippingInvoiceTransactionLogic extends AbstractControllerLogic
{
/**
* @return array
*/
protected function notification():array {
return [
'title' => 'Create Supplier Transactions',
'message' => 'You have successfully created currency supplier transactions'
];
}
/** @var FetchesPackingList */
private $fetchesPackingList;
/** @var FetchesSegmentConstant */
private $fetchesSegmentConstant;
/** @var GeneratesTransactionBillNumber */
private $generatesTransactionBillNumber;
/** @var CreatesTransaction */
private $createsTransaction;
// /** @var FetchesTransaction */
// private $fetchesTransaction;
// /** @var UpdatesTransactionStatus */
// private $updatesTransactionStatus;
// /** @var CreatesDocument */
// private $createsDocument;
// /** @var CreatesFiles */
// private $createsFile;
// /** @var PDF */
// private $pdf;
/**
* CreateSupplierTransactionLogic constructor.
* @param FetchesPackingList $fetchesPackingList
* @param GeneratesTransactionBillNumber $generatesTransactionBillNumber
* @param CreatesTransaction $createsTransaction
* @param FetchesTransaction $fetchesTransaction
* @param UpdatesTransactionStatus $updatesTransactionStatus
* @param PDF $pdf
*/
public function __construct(
FetchesPackingList $fetchesPackingList,
FetchesSegmentConstant $fetchesSegmentConstant,
GeneratesTransactionBillNumber $generatesTransactionBillNumber,
CreatesTransaction $createsTransaction
// UpdatesTransactionStatus $updatesTransactionStatus,
// CreatesDocument $createsDocument,
// CreatesFiles $createsFile,
// PDF $pdf
)
{
$this->fetchesPackingList = $fetchesPackingList;
$this->fetchesSegmentConstant = $fetchesSegmentConstant;
$this->generatesTransactionBillNumber = $generatesTransactionBillNumber;
$this->createsTransaction = $createsTransaction;
// $this->updatesTransactionStatus = $updatesTransactionStatus;
// $this->createsDocument = $createsDocument;
// $this->createsFile = $createsFile;
// $this->pdf = $pdf;
}
public function logic(Request $request) : JsonResponse
{
$packing_list = $this->fetchesPackingList->execute(['id' => $request->input('packing_list_id')]);
$cbm = $packing_list->packages->sum(function($package) {
return ($package->width / 100) * ($package->height / 100) *($package->length / 100) * ($package->quantity);
});
$order = $packing_list->owner()->first();
$address = $order->addresses()->first();
$base_price_constant = $this->fetchesSegmentConstant->execute(['id' => 1]);
$warehouse_rate_constant = $this->fetchesSegmentConstant->execute(['id' => 2]);
$state_rate_constant = $this->fetchesSegmentConstant->execute(['id' => 3]);
$center_postcode_constant = $this->fetchesSegmentConstant->execute(['id' => 4]);
$outstation_postcode_constant = $this->fetchesSegmentConstant->execute(['id' => 5]);
$base_price = 0;
$warehouse_rate = 0;
$state_rate = 0;
$state_select = [];
$with_out = false;
if ($base_price_constant) {
$base_price = $base_price_constant->value->price;
}
if ($warehouse_rate_constant) {
$package_warehouse = $order->OrderRoles()->where('role_id', '=', OrderRoleTypes::ORIGIN_WAREHOUSE)->first()->appointee->reference;
foreach ($warehouse_rate_constant->value->config as $key_warehouse => $row_warehouse) {
if ($row_warehouse->warehouse_name == $package_warehouse) {
$warehouse_rate = $row_warehouse->rate;
}
}
}
if ($state_rate_constant) {
foreach ($state_rate_constant->value->config as $key_state => $row_state) {
if ($row_state->status_id == $address->state_id) {
$state_select = $row_state;
}
}
}
if ($outstation_postcode_constant) {
foreach ($outstation_postcode_constant->value as $key_out => $row_out) {
if($row_out == $address->postcode) {
$with_out = true;
}
}
}
if (!empty($state_select)) {
$state_rate = $state_select->rate;
if ($with_out) {
$state_rate = $state_select->rate + $state_select->outstation_rate;
}
}
$price_cbm = $base_price + $warehouse_rate + $state_rate;
$total_cbm = $price_cbm * $cbm;
$billNumber = $this->generatesTransactionBillNumber->execute('SHIP-');
$object = new TransactionObject(
$billNumber,
TransactionType::SHIPPING_INVOICE,
1,
$order->company_module_id,
1,
PaymentMethodType::CASH,
$total_cbm,
$total_cbm,
1,
1,
0,
0,
0,
null,
ApprovalStatus::PENDING_SUBMISSION
);
$transactions = $this->createsTransaction->execute($packing_list, $object);
return $this->response([]);
}
}
@@ -76,7 +76,24 @@ class TransactionObject implements DataTransferObject
* @param int|null $status
* @param array|null $details
*/
public function __construct(string $billNo, string $transactionType, int $issuer, int $receiver, int $recipientBankAccountId, int $paymentMethod, float $amount, float $originalAmount, int $currencyId, int $originalCurrencyId, float $currencyRate, float $tax, float $serviceCharge, ?Carbon $expiresOn, ?int $status = ApprovalStatus::PENDING_SUBMISSION, ?array $details = [])
public function __construct(
string $billNo,
string $transactionType,
int $issuer,
int $receiver,
int $recipientBankAccountId,
int $paymentMethod,
float $amount,
float $originalAmount,
int $currencyId,
int $originalCurrencyId,
float $currencyRate,
float $tax,
float $serviceCharge,
?Carbon $expiresOn,
?int $status = ApprovalStatus::PENDING_SUBMISSION,
?array $details = []
)
{
$this->billNo = $billNo;
$this->transactionType = $transactionType;
@@ -5,7 +5,7 @@ namespace App\Classes\Modules\Transactions\Services;
use App\Classes\General\Eloquent\AbstractUpdateRecord;
use App\Classes\General\Eloquent\AbstractUpdateRelationshipRecord;
use App\Classes\Modules\Transactions\DataTransferObjects\TransactionObject;
use App\Models\Booking;
use App\Models\PackingList;
use App\Models\Transaction;
class CreatesTransaction extends AbstractUpdateRelationshipRecord
@@ -15,7 +15,7 @@ class CreatesTransaction extends AbstractUpdateRelationshipRecord
* @return \Illuminate\Database\Eloquent\Model
* @throws \App\Classes\Exceptions\MalformedRequestException
*/
public function execute(Booking $booking, TransactionObject $object) {
public function execute(PackingList $packing_list, TransactionObject $object) {
$model = new Transaction();
$model->bill_no = $object->getBillNo();
$model->type = $object->getTransactionType();
@@ -33,8 +33,6 @@ class CreatesTransaction extends AbstractUpdateRelationshipRecord
$model->expires_on = $object->getExpiresOn();
$model->status = $object->getStatus();
return $this->handler($booking->transactions(), $model);
return $this->handler($packing_list->transactions(), $model);
}
}
@@ -5,19 +5,19 @@ namespace App\Classes\ValueObjects\Constants;
class SegmentConstants
{
public const STANDARD_SEGMENT = 1;
public const CUSTOM_SEGMENT = 2;
public const SYSTEM_PRIMARY_CURRENCY = 'SYSTEM_PRIMARY_CURRENCY';
public const BASE_PRICE = 'BASE_PRICE';
public const SUPPLIER_CURRENCIES = 'SUPPLIER_CURRENCIES';
public const WAREHOUSE_RATE = 'WAREHOUSE_RATE';
public const PAYMENT_ATTEMPT_DURATION_LIMIT = 'PAYMENT_ATTEMPT_DURATION_LIMIT';
public const STATE_RATE = 'STATE_RATE';
public const SERVICE_TYPE = 'SERVICE_TYPE';
public const CENTER_POSTCODE = 'CENTER_POSTCODE';
public const CUSTOM_SERVICE_TYPE = 'CUSTOM_SERVICE_TYPE';
public const OUTSTATION_POSTCODE = 'OUTSTATION_POSTCODE';
public const CUSTOMER_RATE = 'CUSTOMER_RATE';
}
@@ -4,24 +4,26 @@ namespace App\Classes\ValueObjects\Constants;
final class TransactionType {
public const PAYMENT_ATTEMPT = 0;
public const SHIPPING_INVOICE = 1;
// public const PAYMENT_ATTEMPT = 0;
public const PAYMENT = 1;
// public const PAYMENT = 1;
public const INVOICE = 2;
// public const INVOICE = 2;
public const BILL = 3;
// public const BILL = 3;
public const PERFORMA = 4;
// public const PERFORMA = 4;
public const TOP_UP = 5;
// public const TOP_UP = 5;
public const REFUND = 6;
// public const REFUND = 6;
public const PURCHASE_ORDER = 7;
// public const PURCHASE_ORDER = 7;
public const SUPPLIER_DELIVER = 8;
// public const SUPPLIER_DELIVER = 8;
public const SHIPPING_COST = 9;
// public const SHIPPING_COST = 9;
}
@@ -0,0 +1,21 @@
<?php
namespace App\Http\Controllers\Transactions;
use Illuminate\Http\JsonResponse;
use Illuminate\Http\Request;
use App\Classes\Modules\Transactions\ControllersLogic\CreateShippingInvoiceTransactionLogic;
class CreateShippingInvoiceTransactionController
{
/**
* @param Request $request
* @param CreateShippingInvoiceTransactionLogic $logic
* @return JsonResponse
*/
public function create(Request $request, CreateShippingInvoiceTransactionLogic $logic) : JsonResponse {
return $logic->execute($request);
}
}
+11 -1
View File
@@ -5,6 +5,8 @@ namespace App\Models;
use App\Classes\General\Interfaces\Steppable;
use App\Classes\General\Interfaces\Transportable;
use App\Classes\General\Interfaces\Packable;
use App\Classes\General\Interfaces\Transactionable;
use App\Classes\ValueObjects\Constants\ApprovalStatus;
use Carbon\Carbon;
use Illuminate\Database\Eloquent\Relations\BelongsToMany;
@@ -16,7 +18,7 @@ use Staudenmeir\EloquentHasManyDeep\HasManyDeep;
use Staudenmeir\EloquentHasManyDeep\HasRelationships;
use Staudenmeir\EloquentHasManyDeep\HasTableAlias;
class PackingList extends AbstractModel implements Transportable, Steppable, Packable
class PackingList extends AbstractModel implements Transportable, Steppable, Packable, Transactionable
{
use HasTableAlias;
use HasRelationships;
@@ -55,6 +57,14 @@ class PackingList extends AbstractModel implements Transportable, Steppable, Pac
return $this->hasMany(Package::class, 'packing_list_id');
}
/**
* @return MorphMany
*/
public function transactions(): MorphMany
{
return $this->MorphMany(Transaction::class, 'owner');
}
/**
* @return HasManyDeep
*/
+4 -13
View File
@@ -15,12 +15,8 @@ use Illuminate\Database\Eloquent\SoftDeletes;
*/
class SegmentConstant extends AbstractModel
{
use SoftDeletes;
protected $table = 'segment_constants';
protected $dates = ['deleted_at'];
public function getDetailAttribute($value)
{
return $value ? json_decode($value) : [];
@@ -34,14 +30,9 @@ class SegmentConstant extends AbstractModel
return $this->BelongsTo(Segment::class, 'segment_id', 'id');
}
/**
* @return mixed
*/
public function service(){
return $this->hasOne(ServiceType::class, 'id', 'detail->id')
->whereIn('reference', [SegmentConstants::SERVICE_TYPE, SegmentConstants::CUSTOM_SERVICE_TYPE]);
public function getValueAttribute($value)
{
$value = $value ? json_decode($value) : [];
return $value;
}
}
+149 -41
View File
@@ -1,54 +1,162 @@
<?php
namespace Database\Seeders;
use App\Classes\Modules\Currencies\Services\FetchesCurrency;
use App\Classes\Modules\Segments\DataTransferObjects\ConstantObject;
use App\Classes\Modules\Segments\Services\CreatesConstant;
use App\Classes\Modules\Segments\Services\FetchesSegment;
use App\Classes\ValueObjects\Constants\SegmentConstants;
use App\Classes\ValueObjects\Constants\WarehouseReferences;
use Illuminate\Database\Seeder;
use Illuminate\Support\Facades\DB;
class SegmentConstantsTableSeeder extends Seeder
{
/** @var FetchesCurrency */
private $fetchesCurrency;
/** @var FetchesSegment */
private $fetchesSegment;
/** @var CreatesConstant */
private $createsSegmentConstant;
/**
* SegmentConstantsTableSeeder constructor.
* @param FetchesCurrency $fetchesCurrency
* @param FetchesSegment $fetchesSegment
* @param CreatesConstant $createsSegmentConstant
*/
public function __construct(FetchesCurrency $fetchesCurrency, FetchesSegment $fetchesSegment, CreatesConstant $createsSegmentConstant)
{
$this->fetchesCurrency = $fetchesCurrency;
$this->fetchesSegment = $fetchesSegment;
$this->createsSegmentConstant = $createsSegmentConstant;
}
/**
* Run the database seeds.
*
* @return void
* @throws \App\Classes\Exceptions\MalformedRequestException
*/
public function run()
{
DB::beginTransaction();
$object = new ConstantObject('System Primary Currency',
SegmentConstants::SYSTEM_PRIMARY_CURRENCY,
['id' => $this->fetchesCurrency->execute(['name' => country('my')->getName()])->id]);
$this->createsSegmentConstant->execute($this->fetchesSegment->execute(['Standard Segment']), $object);
DB::table('segment_constants')->insert([
[
'id' => 1,
'segment_id' => 1,
'reference' => SegmentConstants::BASE_PRICE,
'value' => json_encode([
'id'=> 1,
'price' => 500,
]),
],
[
'id' => 2,
'segment_id' => 1,
'reference' => SegmentConstants::WAREHOUSE_RATE,
'value' => json_encode([
'id'=> 1,
'config' => [
[
'warehouse_name' => WarehouseReferences::VT_GUANG_ZHOU,
'rate' => 10
],
[
'warehouse_name' => WarehouseReferences::YD_GUANG_ZHOU,
'rate' => 10
],
[
'warehouse_name' => WarehouseReferences::VT_YIWU,
'rate' => 10
],
]
]),
],
[
'id' => 3,
'segment_id' => 1,
'reference' => SegmentConstants::STATE_RATE,
'value' => json_encode([
'id'=> 1,
'config' => [
[
'status_id' => 1,
'rate' => 10,
'outstation_rate' => 2
],
[
'status_id' => 2,
'rate' => 10,
'outstation_rate' => 2
],
[
'status_id' => 3,
'rate' => 10,
'outstation_rate' => 2
],
[
'status_id' => 4,
'rate' => 10,
'outstation_rate' => 2
],
[
'status_id' => 5,
'rate' => 10,
'outstation_rate' => 2
],
[
'status_id' => 6,
'rate' => 10,
'outstation_rate' => 2
],
[
'status_id' => 7,
'rate' => 10,
'outstation_rate' => 2
],
[
'status_id' => 8,
'rate' => 10,
'outstation_rate' => 2
],
[
'status_id' => 9,
'rate' => 10,
'outstation_rate' => 2
],
[
'status_id' => 10,
'rate' => 10,
'outstation_rate' => 2
],
[
'status_id' => 11,
'rate' => 10,
'outstation_rate' => 2
],
[
'status_id' => 12,
'rate' => 10,
'outstation_rate' => 2
],
[
'status_id' => 13,
'rate' => 20,
'outstation_rate' => 2
],
[
'status_id' => 14,
'rate' => 20,
'outstation_rate' => 2
],
[
'status_id' => 15,
'rate' => 10,
'outstation_rate' => 2
],
[
'status_id' => 16,
'rate' => 10,
'outstation_rate' => 2
]
]
]),
],
[
'id' => 4,
'segment_id' => 1,
'reference' => SegmentConstants::CENTER_POSTCODE,
'value' => json_encode(['80050','80100','80150','80200','80250','80300','80350','80400','80500','80506','80508','80516','80519','80534','80536','80542','80546','80558','80560','80564','80568','80578','80584','80586','80590','80592','80594','80596','80600','80604','80608','80620','80622','80628','80644','80648','80662','80664','80668','80670','80672','80673','80676','80700','80710','80720','80730','80900','80902','80904','80906','80908','80988','80990','81000','81100','81200','81300','81310']),
],
[
'id' => 5,
'segment_id' => 1,
'reference' => SegmentConstants::OUTSTATION_POSTCODE,
'value' => json_encode(['80000']),
],
[
'id' => 6,
'segment_id' => 2,
'reference' => SegmentConstants::CUSTOMER_RATE,
'value' => json_encode([
'id'=> 1,
'price' => 15,
]),
],
]);
DB::commit();
}
}
+14 -12
View File
@@ -2,24 +2,26 @@
namespace Database\Seeders;
use App\Classes\Modules\Segments\DataTransferObjects\SegmentObject;
use App\Classes\Modules\Segments\Services\CreatesSegment;
use App\Classes\ValueObjects\Constants\SegmentConstants;
use Illuminate\Database\Seeder;
use Illuminate\Support\Facades\DB;
class SegmentsTableSeeder extends Seeder
{
/**
*/
public function run()
{
DB::table('segments')->insert([
'name' => 'Standard Segment',
'type' => SegmentConstants::STANDARD_SEGMENT
]);
DB::table('segments')->insert(
[
[
'id' => 1,
'company_module_id' => 1,
'name' => 'Default Segment',
],
[
'id' => 2,
'company_module_id' => 2,
'name' => 'Normal Member',
],
]
);
}
}
+6 -4
View File
@@ -5,11 +5,13 @@ use Illuminate\Support\Facades\Route;
Route::group(['prefix' => 'transactions', 'namespace' => 'Transactions', 'as' => 'transaction.'], function () {
Route::get('/list', 'ListTransactionsController@list')->name('list');
Route::delete('/suspend/{id}', 'SuspendTransactionController@suspend')->name('suspend');
// Route::delete('/suspend/{id}', 'SuspendTransactionController@suspend')->name('suspend');
route::post('/supplier/{id}/bill/create', 'CreateSupplierTransactionController@create')->name('supplier.create');
route::post('{id}/bill/verification', 'CreatePaymentProofDocumentController@verify')->name('bill.verification');
route::post('/shipping-invoice/create', 'CreateShippingInvoiceTransactionController@create')->name('supplier.create');
Route::post('booking/{id}/details/update', 'CreatePurchaseOrderTransactionController@create')->name('po.create');
// route::post('{id}/bill/verification', 'CreatePaymentProofDocumentController@verify')->name('bill.verification');
// Route::post('booking/{id}/details/update', 'CreatePurchaseOrderTransactionController@create')->name('po.create');
});