mirror of
https://gitlab.com/CIEFWorldwideSdnBhd/shipping-portal.git
synced 2026-08-19 04:24:12 +00:00
no message
This commit is contained in:
@@ -0,0 +1,163 @@
|
||||
<?php
|
||||
|
||||
namespace App\Http\Controllers\Orders;
|
||||
|
||||
use App\Classes\ValueObjects\Constants\BusinessType;
|
||||
use App\Classes\ValueObjects\Constants\DocumentType;
|
||||
use App\Classes\ValueObjects\Constants\OrderRoleTypes;
|
||||
use App\Classes\ValueObjects\Constants\RemarkTypes;
|
||||
use App\Classes\ValueObjects\Constants\TransactionType;
|
||||
use App\Models\CompanyModule;
|
||||
use App\Models\Order;
|
||||
use Illuminate\Http\JsonResponse;
|
||||
use Illuminate\Http\Request;
|
||||
use Illuminate\Support\Facades\DB;
|
||||
|
||||
class MoveOrderToCustomerController
|
||||
{
|
||||
public function orderInfo(Request $request): JsonResponse
|
||||
{
|
||||
$ref = $request->query('reference');
|
||||
if (!$ref) {
|
||||
return response()->json(['error' => 'reference required'], 422);
|
||||
}
|
||||
$order = Order::where('reference', $ref)->with('companyModule')->first();
|
||||
if (!$order) {
|
||||
return response()->json(['error' => 'Order not found'], 404);
|
||||
}
|
||||
$cm = $order->companyModule;
|
||||
return response()->json([
|
||||
'order_id' => $order->id,
|
||||
'reference' => $order->reference,
|
||||
'from_company_module_id' => $order->company_module_id,
|
||||
'from_customer_name' => $cm->name ?? '',
|
||||
'from_customer_marking' => $cm->getMarking(),
|
||||
]);
|
||||
}
|
||||
|
||||
public function customers(Request $request): JsonResponse
|
||||
{
|
||||
$list = CompanyModule::where('type', BusinessType::IMPORTER)
|
||||
->whereHas('connections', fn ($q) => $q->whereNotNull('invitee_reference')->where('invitee_reference', '!=', ''))
|
||||
->get()
|
||||
->map(fn ($cm) => ['id' => $cm->id, 'name' => $cm->name, 'marking' => $cm->getMarking()])
|
||||
->filter(fn ($r) => (string) $r['marking'] !== '')
|
||||
->values();
|
||||
|
||||
return response()->json($list);
|
||||
}
|
||||
|
||||
public function move(Request $request): JsonResponse
|
||||
{
|
||||
$ref = $request->input('order_reference');
|
||||
$targetId = (int) $request->input('target_company_module_id');
|
||||
if (!$ref || !$targetId) {
|
||||
return response()->json(['success' => false, 'error' => 'order_reference and target_company_module_id required', 'log' => []]);
|
||||
}
|
||||
|
||||
$order = Order::with('companyModule')->where('reference', $ref)->first();
|
||||
if (!$order) {
|
||||
return response()->json(['success' => false, 'error' => 'Order not found', 'log' => []]);
|
||||
}
|
||||
|
||||
$from = $order->company_module_id;
|
||||
if ($from == $targetId) {
|
||||
return response()->json(['success' => false, 'error' => 'Order already belongs to target customer', 'log' => []]);
|
||||
}
|
||||
|
||||
$target = CompanyModule::find($targetId);
|
||||
if (!$target) {
|
||||
return response()->json(['success' => false, 'error' => 'Target customer not found', 'log' => []]);
|
||||
}
|
||||
|
||||
$log = [];
|
||||
$log[] = 'Changing order: company_module_id ' . $from . ' → ' . $targetId;
|
||||
$log[] = 'Changing order_roles: company_module_id ' . $from . ' → ' . $targetId;
|
||||
$log[] = 'Changing packing list: no update (remain linked to order)';
|
||||
|
||||
try {
|
||||
DB::beginTransaction();
|
||||
|
||||
$now = now();
|
||||
DB::table('orders')->where('id', $order->id)->update(['company_module_id' => $targetId, 'updated_at' => $now]);
|
||||
DB::table('order_roles')
|
||||
->where('order_id', $order->id)
|
||||
->where('role_id', OrderRoleTypes::IMPORTER)
|
||||
->update(['company_module_id' => $targetId, 'updated_at' => $now]);
|
||||
|
||||
$marking = $target->getMarking() ?: (string) $targetId;
|
||||
DB::table('remarks')->insert([
|
||||
'owner_type' => Order::class,
|
||||
'owner_id' => $order->id,
|
||||
'commenter_id' => auth()->id() ?? 1,
|
||||
'content' => 'Order moved to customer (marking: ' . $marking . ') on ' . $now->toDateTimeString(),
|
||||
'type' => RemarkTypes::INTERNAL,
|
||||
'created_at' => $now,
|
||||
'updated_at' => $now,
|
||||
]);
|
||||
|
||||
$transactions = $order->transactions()->get();
|
||||
$createShipInv = app(\App\Classes\Modules\Transactions\Processors\CreateShippingInvoiceTransactionDocProcessor::class);
|
||||
$createSalesOrder = app(\App\Classes\Modules\Transactions\Processors\CreateSalesOrderDocProcessor::class);
|
||||
$createShipEInv = app(\App\Classes\Modules\Transactions\Processors\CreateShippingEInvoiceDocProcessor::class);
|
||||
$createStorageInv = app(\App\Classes\Modules\Transactions\Processors\CreateStorageInvoiceTransactionDocProcessor::class);
|
||||
$createStorageEInv = app(\App\Classes\Modules\Transactions\Processors\CreateStorageEInvoiceDocProcessor::class);
|
||||
|
||||
foreach ($transactions as $tx) {
|
||||
if ($tx->type == TransactionType::SHIPPING_INVOICE) {
|
||||
try {
|
||||
$tx->documents()->where('document_type', DocumentType::SHIPPING_INVOICE)->delete();
|
||||
$createShipInv->execute($tx);
|
||||
$log[] = 'Regenerating Shipping Invoice PDF: transaction #' . $tx->id;
|
||||
} catch (\Throwable $e) {
|
||||
$log[] = 'Regenerating Shipping Invoice PDF: transaction #' . $tx->id . ' — failed: ' . $e->getMessage();
|
||||
}
|
||||
try {
|
||||
$tx->documents()->where('document_type', DocumentType::SALES_ORDER)->delete();
|
||||
$createSalesOrder->execute($tx);
|
||||
$log[] = 'Regenerating Sales Order PDF: transaction #' . $tx->id;
|
||||
} catch (\Throwable $e) {
|
||||
$log[] = 'Regenerating Sales Order PDF: transaction #' . $tx->id . ' — failed: ' . $e->getMessage();
|
||||
}
|
||||
$isEInv = $tx->owner->owner->companyModule->company->e_invoice ?? 0;
|
||||
if ($isEInv == 1) {
|
||||
try {
|
||||
$tx->documents()->where('document_type', DocumentType::SHIPPING_EINVOICE)->delete();
|
||||
$createShipEInv->execute($tx);
|
||||
$log[] = 'Regenerating E-Invoice PDF: transaction #' . $tx->id;
|
||||
} catch (\Throwable $e) {
|
||||
$log[] = 'Regenerating E-Invoice PDF: transaction #' . $tx->id . ' — failed: ' . $e->getMessage();
|
||||
}
|
||||
}
|
||||
} elseif ($tx->type == TransactionType::STORAGE_INVOICE) {
|
||||
try {
|
||||
$tx->documents()->where('document_type', DocumentType::STORAGE_INVOICE)->delete();
|
||||
$createStorageInv->execute($tx);
|
||||
$log[] = 'Regenerating Storage Invoice PDF: transaction #' . $tx->id;
|
||||
} catch (\Throwable $e) {
|
||||
$log[] = 'Regenerating Storage Invoice PDF: transaction #' . $tx->id . ' — failed: ' . $e->getMessage();
|
||||
}
|
||||
$isEInv = $tx->owner->owner->companyModule->company->e_invoice ?? 0;
|
||||
if ($isEInv == 1) {
|
||||
try {
|
||||
$tx->documents()->where('document_type', DocumentType::STORAGE_EINVOICE)->delete();
|
||||
$createStorageEInv->execute($tx);
|
||||
$log[] = 'Regenerating Storage E-Invoice PDF: transaction #' . $tx->id;
|
||||
} catch (\Throwable $e) {
|
||||
$log[] = 'Regenerating Storage E-Invoice PDF: transaction #' . $tx->id . ' — failed: ' . $e->getMessage();
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
$log[] = 'Done.';
|
||||
DB::commit();
|
||||
} catch (\Throwable $e) {
|
||||
DB::rollBack();
|
||||
$log[] = 'Error: ' . $e->getMessage();
|
||||
return response()->json(['success' => false, 'error' => $e->getMessage(), 'log' => $log]);
|
||||
}
|
||||
|
||||
return response()->json(['success' => true, 'log' => $log]);
|
||||
}
|
||||
}
|
||||
@@ -12,6 +12,6 @@ class VerifyCsrfToken extends Middleware
|
||||
* @var array
|
||||
*/
|
||||
protected $except = [
|
||||
//
|
||||
'move-order/api/move',
|
||||
];
|
||||
}
|
||||
|
||||
@@ -0,0 +1,104 @@
|
||||
@extends('layouts.base_portal')
|
||||
@section('inner_content')
|
||||
<div class="row d-none" :class="[{'d-flex': $store.getters.isAdmin}]" v-if="$store.getters.isAdmin">
|
||||
<div class="col-12">
|
||||
<h4>Move Order to Customer</h4>
|
||||
<div class="card mb-3">
|
||||
<div class="card-body">
|
||||
<div class="row mb-2">
|
||||
<div class="col-md-4">
|
||||
<label>Order number</label>
|
||||
<div class="d-flex">
|
||||
<input type="text" id="orderRef" class="form-control" placeholder="e.g. 845287762">
|
||||
<button type="button" class="btn btn-primary ml-2" id="btnLoad">Load</button>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<div class="row mb-2">
|
||||
<div class="col-md-6">
|
||||
<label>From customer</label>
|
||||
<div id="fromCustomer" class="form-control" style="min-height:38px;"></div>
|
||||
</div>
|
||||
</div>
|
||||
<div class="row mb-2">
|
||||
<div class="col-md-6">
|
||||
<label>To customer</label>
|
||||
<select id="toCustomer" class="form-control" style="width:100%;">
|
||||
<option value="">— Select —</option>
|
||||
</select>
|
||||
</div>
|
||||
</div>
|
||||
<div class="row mb-2">
|
||||
<div class="col">
|
||||
<button type="button" class="btn btn-danger" id="btnMove">Move order</button>
|
||||
</div>
|
||||
</div>
|
||||
<div class="row mt-3">
|
||||
<div class="col-12">
|
||||
<label>Log</label>
|
||||
<pre id="log" class="bg-dark text-light p-3" style="min-height:120px; max-height:280px; overflow:auto; font-size:12px;"></pre>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
@endsection
|
||||
|
||||
@push('scripts')
|
||||
<script>
|
||||
(function(){
|
||||
var logEl = document.getElementById('log');
|
||||
if (!logEl) return;
|
||||
var orderInfoUrl = {!! json_encode(route('move-order.orderInfo')) !!};
|
||||
var customersUrl = {!! json_encode(route('move-order.customers')) !!};
|
||||
var moveUrl = {!! json_encode(route('move-order.move')) !!};
|
||||
function log(msg){ logEl.textContent += msg + '\n'; logEl.scrollTop = logEl.scrollHeight; }
|
||||
function clearLog(){ logEl.textContent = ''; }
|
||||
|
||||
fetch(customersUrl, { headers: {'Accept':'application/json'}, credentials: 'same-origin' })
|
||||
.then(function(r){ return r.json(); })
|
||||
.then(function(arr){
|
||||
var sel = document.getElementById('toCustomer');
|
||||
if (!sel) return;
|
||||
sel.innerHTML = '<option value="">— Select —</option>';
|
||||
(arr||[]).forEach(function(c){ var o=document.createElement('option'); o.value=c.id; o.textContent=(c.marking||'')+' - '+(c.name||''); sel.appendChild(o); });
|
||||
if (window.$ && $.fn.select2) {
|
||||
$(sel).select2({ placeholder: '— Select —', allowClear: false, width: '100%' });
|
||||
}
|
||||
});
|
||||
|
||||
document.getElementById('btnLoad').onclick = function(){
|
||||
var ref = (document.getElementById('orderRef').value||'').trim();
|
||||
if(!ref){ log('Enter order number'); return; }
|
||||
clearLog(); log('Loading order...');
|
||||
fetch(orderInfoUrl + '?reference=' + encodeURIComponent(ref), { headers: {'Accept':'application/json'}, credentials: 'same-origin' })
|
||||
.then(function(r){ return r.json(); })
|
||||
.then(function(d){
|
||||
if(d.error){ log('Error: ' + d.error); return; }
|
||||
var from = document.getElementById('fromCustomer'); if(from) from.innerHTML = (d.from_customer_marking || '') + ' - ' + (d.from_customer_name || '');
|
||||
log('Loaded: ' + d.reference + ' (from: ' + (d.from_customer_marking||'') + ')');
|
||||
})
|
||||
.catch(function(e){ log('Error: ' + e.message); });
|
||||
};
|
||||
|
||||
document.getElementById('btnMove').onclick = function(){
|
||||
var ref = (document.getElementById('orderRef').value||'').trim();
|
||||
var toId = document.getElementById('toCustomer').value;
|
||||
if(!ref){ log('Enter order number'); return; }
|
||||
if(!toId){ log('Select To customer'); return; }
|
||||
clearLog(); log('Moving order...');
|
||||
var body = JSON.stringify({ order_reference: ref, target_company_module_id: parseInt(toId,10) });
|
||||
var headers = { 'Accept':'application/json', 'Content-Type':'application/json' };
|
||||
fetch(moveUrl, { method: 'POST', headers: headers, body: body, credentials: 'same-origin' })
|
||||
.then(function(r){ return r.json(); })
|
||||
.then(function(d){
|
||||
(d.log||[]).forEach(function(l){ log(l); });
|
||||
if(d.error && !d.success) log('Error: ' + d.error);
|
||||
if(d.success) log('Success.');
|
||||
})
|
||||
.catch(function(e){ log('Error: ' + e.message); });
|
||||
};
|
||||
})();
|
||||
</script>
|
||||
@endpush
|
||||
@@ -49,6 +49,7 @@ use Illuminate\Support\Facades\Storage;
|
||||
use App\Classes\General\AWSS3Helper;
|
||||
use App\Classes\Jobs\Commands\V2\YD\ProcessYDByTrakingNoDataV2Job;
|
||||
use App\Classes\Jobs\Commands\V2\YD\ProcessYDPortalDataV2Job;
|
||||
use App\Http\Controllers\Orders\MoveOrderToCustomerController;
|
||||
use Illuminate\Support\Facades\Artisan;
|
||||
use Illuminate\Support\Facades\Log;
|
||||
|
||||
@@ -1404,6 +1405,14 @@ Route::get('/downloads', function () {
|
||||
return view('pages.downloads.index');
|
||||
})->name('admin.downloads');
|
||||
|
||||
Route::group(['prefix' => 'move-order', 'as' => 'move-order.'], function () {
|
||||
Route::get('/', function () {
|
||||
return view('pages.orders.move_order');
|
||||
})->name('index');
|
||||
Route::get('api/order-info', [MoveOrderToCustomerController::class, 'orderInfo'])->name('orderInfo');
|
||||
Route::get('api/customers', [MoveOrderToCustomerController::class, 'customers'])->name('customers');
|
||||
Route::post('api/move', [MoveOrderToCustomerController::class, 'move'])->name('move');
|
||||
});
|
||||
|
||||
Route::get('/maintenance', function () {
|
||||
return response()->view('errors.503', [], 503);
|
||||
|
||||
Reference in New Issue
Block a user