File "OrderApiController.php"
Full Path: /home/clickysoft/public_html/jmapi5.clickysoft.net/app/Http/Controllers/Api/V1/Admin/OrderApiController.php
File size: 69.46 KB
MIME-type: text/x-php
Charset: utf-8
<?php
namespace App\Http\Controllers\Api\V1\Admin;
use App\Http\Controllers\Controller;
use App\Http\Controllers\Traits\MediaUploadingTrait;
use App\Http\Requests\Admin\AddOrderPartialPaymentRequest;
use App\Http\Requests\Admin\AddOrderPaymentRequest;
use App\Http\Requests\Admin\AddOrderProductRequest;
use App\Http\Requests\Admin\StoreOrderRequest;
use App\Http\Requests\Admin\UpdateOrderRequest;
use App\Http\Requests\User\OrderCustomizationSvgRequest;
use App\Http\Requests\User\OrderTotalsRequest;
use App\Http\Requests\User\ShippingQuoteRequest;
use App\Http\Resources\Admin\OrderInfoEditResource;
use App\Http\Resources\Admin\OrderInfoResource;
use App\Http\Resources\Admin\OrderNotesResource;
use App\Http\Resources\Admin\OrderResource;
use App\Http\Resources\Admin\WorkOrder;
use App\Models\Coupon;
use App\Models\Order;
use App\Models\OrderInvoice;
use App\Models\OrderItemCustomizationData;
use App\Models\OrderItemCustomizationSvg;
use App\Models\OrderItems;
use App\Models\OrderItemVariation;
use App\Models\OrderNotes;
use App\Models\OrderPartialPayments;
use App\Models\ProductVariationRange;
use App\Models\PurchaseOrderToCreate;
use App\Models\SiteSetting;
use App\Models\Status;
use App\Models\User;
use App\Notifications\OrderQuoteUserNotification;
use App\Rules\ValidateDate;
use Illuminate\Support\Facades\Gate;
use GuzzleHttp\Client;
use GuzzleHttp\Exception\GuzzleException;
use Illuminate\Http\Request;
use Illuminate\Support\Facades\DB;
use Illuminate\Support\Facades\Log;
use Illuminate\Support\Facades\Storage;
use Psr\Container\ContainerExceptionInterface;
use Psr\Container\NotFoundExceptionInterface;
use Symfony\Component\HttpFoundation\Response;
class OrderApiController extends Controller
{
use MediaUploadingTrait;
public function index(Request $request)
{
abort_if(Gate::denies('order_access'), Response::HTTP_FORBIDDEN, '403 Forbidden');
if ($request->has('pd')) {
$orders = $this->getPDOrders($request);
} else {
//Get NonPDOrders
$orders = $this->getNoNPDOrders($request);
}
$widget_data = $this->getCalendarWidgetData();
OrderResource::withoutWrapping();
return OrderResource::collection($orders)->additional(["calendar_widget_data" => $widget_data[0], 'pd' => $widget_data[1]]);
}
public function getPDOrders(Request $request)
{
$old_date = now()->subDays(3)->startOfDay();
$exclude_status_ids = [
1, //Pending
10, //Cancelled
13, //Completed
14 //Picked / Shipped
];
return Order::where('date_scheduled', '<=', $old_date)->whereNotIn('current_status_id', $exclude_status_ids)
->when($order_number = $request->get('order_number'), function ($query) use ($order_number) {
$query->where('order_number', 'LIKE', '%' . $order_number . '%');
})->when($status_id = $request->get('status_id'), function ($query) use ($status_id) {
$query->where('current_status_id', $status_id);
})->when($delivery_date = $request->get('delivery_date'), function ($query) use ($delivery_date) {
$query->whereDate('date_scheduled', $delivery_date);
})->when($order_type = $request->get('order_type'), function ($query) use ($order_type) {
$query->where('order_type', $order_type);
})->when($request->filled('name'), function ($query) use ($request) {
$query->whereHas('user', function ($query) use ($request) {
$query->where('name', 'like', "%{$request->get('name')}%");
});
})->when($request->filled('email'), function ($query) use ($request) {
$query->whereHas('user', function ($query) use ($request) {
$query->where('email', 'like', "%{$request->get('email')}%");
});
})->when($request->filled('company'), function ($query) use ($request) {
$query->where('billing_company_name', 'like', "%{$request->get('company')}%");
$query->orWhereHas('user', function ($query) use ($request) {
$query->where('company', 'like', "%{$request->get('company')}%");
});
})->when($request->filled('payment_status'), function ($query) use ($request) {
$query->where('payment_status', $request->payment_status);
})->when($request->filled('payment_type'), function ($query) use ($request) {
$query->where('payment_type', $request->payment_type);
})->when($request->filled('payment_mode'), function ($query) use ($request) {
$query->where('payment_mode', $request->payment_mode);
})->when($request->filled('rush_order'), function ($query) use ($request) {
$query->where('rush_order', $request->rush_order);
})->when($request->filled('product_number'), function ($query) use ($request) {
$query->whereHas('items.product', function ($query) use ($request) {
$query->where('sku', 'LIKE', "%{$request->get('product_number')}%");
});
})->when(auth()->user()->user_type == 2, function ($query) {
$query->where('assigned_to_id', auth()->id());
})
->with([
'user',
'current_status',
'assigned_to',
])
->orderBy('id', 'DESC')
->paginate(50)
->appends(request()->query());
}
public function getNoNPDOrders(Request $request)
{
return Order::when($order_number = $request->get('order_number'), function ($query) use ($order_number) {
$query->where('order_number', 'LIKE', '%' . $order_number . '%');
})->when($status_id = $request->get('status_id'), function ($query) use ($status_id) {
$query->where('current_status_id', $status_id);
})->when($delivery_date = $request->get('delivery_date'), function ($query) use ($delivery_date) {
$query->whereDate('date_scheduled', $delivery_date);
})->when($order_type = $request->get('order_type'), function ($query) use ($order_type) {
$query->where('order_type', $order_type);
})->when($request->filled('name'), function ($query) use ($request) {
$query->whereHas('user', function ($query) use ($request) {
$query->where('name', 'like', "%{$request->get('name')}%");
});
})->when($request->filled('email'), function ($query) use ($request) {
$query->whereHas('user', function ($query) use ($request) {
$query->where('email', 'like', "%{$request->get('email')}%");
});
})->when($request->filled('company'), function ($query) use ($request) {
$query->where('billing_company_name', 'like', "%{$request->get('company')}%");
$query->orWhereHas('user', function ($query) use ($request) {
$query->where('company', 'like', "%{$request->get('company')}%");
});
})->when($request->filled('payment_status'), function ($query) use ($request) {
$query->where('payment_status', $request->payment_status);
})->when($request->filled('payment_type'), function ($query) use ($request) {
$query->where('payment_type', $request->payment_type);
})->when($request->filled('payment_mode'), function ($query) use ($request) {
$query->where('payment_mode', $request->payment_mode);
})->when($request->filled('rush_order'), function ($query) use ($request) {
$query->where('rush_order', $request->rush_order);
})->when($request->filled('is_completed'), function ($query) use ($request) {
if ($request->is_completed == 1) {
$query->where('current_status_id', 13);
} else {
$query->where('current_status_id', '<>', 13);
}
})->when($request->filled('product_number'), function ($query) use ($request) {
$query->whereHas('items.product', function ($query) use ($request) {
$query->where('sku', 'LIKE', "%{$request->get('product_number')}%");
});
})->when(auth()->user()->user_type == 2, function ($query) {
$query->where('assigned_to_id', auth()->id());
})
->with([
'user',
'current_status',
'assigned_to',
])
->orderBy('id', 'DESC')
->paginate(50)
->appends(request()->query());
}
public function update_order_status(Request $request, Order $order)
{
abort_if(Gate::denies('order_edit'), Response::HTTP_FORBIDDEN, '403 Forbidden');
$request->validate([
'status_id' => 'required|exists:statuses,id',
'notes' => 'nullable|string|max:300',
]);
//Exclude In Assembly/Cleaning status
if ($request->get('status_id') == 12) {
return \response()
->json([
'message' => "Can not update order status.",
'errors' => ['status_id' => ['Invalid status selected.']]
])
->setStatusCode(Response::HTTP_UNPROCESSABLE_ENTITY);
}
if ($order->order_type == 'Quote') {
return \response()
->json([
'message' => "Can not update order status.",
'errors' => ['status_id' => ['Quote order status can not be updated.']]
])
->setStatusCode(Response::HTTP_UNPROCESSABLE_ENTITY);
}
$status = Status::find($request->get('status_id'));
if ($status->name == 'Order Acknowledgement') {
$order->createPurchaseOrderItem();
} else if ($status->name == 'Canceled') {
$order->deletePurchaseOrderItem();
} else if ($status->name == 'Complete/Customer Notified') {
$request->validate([
'stock_location_id' => 'required|exists:stock_locations,id',
]);
$order->stock_location_id = $request->stock_location_id;
} else if ($status->name == 'Products Received/Shelved') {
$request->validate([
'stock_location_id' => 'required|exists:stock_locations,id',
]);
$order->stock_location_id = $request->stock_location_id;
} else if ($status->name == 'Picked/Shipped') {
if ($order->delivery_type == 'Shipping') {
$request->validate([
'tracking_number' => 'required|alpha_num',
]);
$order->tracking_number = $request->tracking_number;
} else {
$request->validate([
'pickup_by' => 'required|string',
]);
$order->pickup_by = $request->pickup_by;
}
}
$order->current_status_id = $request->get('status_id');
$order->statuses()->attach($request->get('status_id'), ['notes' => $request->get('notes'), 'user_id' => auth()->id()]);
$order->save();
$order->createInvoice(); //Generate invoice with latest information
//Send Order Status Update Email
$order->sendOrderStatusUpdatedMail($request->get('notes'));
return (new OrderResource($order))
->response()
->setStatusCode(Response::HTTP_CREATED);
}
public function add_order_payment(AddOrderPaymentRequest $request, Order $order)
{
abort_if(Gate::denies('order_edit'), Response::HTTP_FORBIDDEN, '403 Forbidden');
DB::beginTransaction();
$order->payment_type = $request->get('payment_type');
if ($request->get('payment_type') == 'Credit Card') {
//Charge via vault_id if we are receiving vault_id
if ($request->get('vault_id')) {
//Charge customer using vault it just created.
$charge_response = chargeByVaultId(
$order->billing_address_id,
$request->get('vault_id'),
$request->get('amount'),
);
if (!$charge_response['success']) {
return \response()
->json([
'message' => "Can not process payment.",
'errors' => ["error" => $charge_response["error"]]
], Response::HTTP_INTERNAL_SERVER_ERROR);
}
} else {
//If customers allowed to save card
if ($request->get('save_card', false)) {
//Check if PayJunction customerId exists. Create if not present.
if (!auth()->user()->pj_id) {
$customerCreated = createPJCustomer(
$order->billing_address_id,
$order->user,
);
if (!$customerCreated) {
return \response()
->json([
'message' => "Can not process payment.",
'errors' => ["error" => ["Customer creation failed."]]
], Response::HTTP_INTERNAL_SERVER_ERROR);
}
}
$card_data = [
"cardNumber" => $request->get('card_number'),
"cardExpMonth" => $request->get('expiry_month'),
"cardExpYear" => $request->get('expiry_year'),
"cvv" => $request->get('ccv')
];
$vaultId = createPJCustomerVault(
$order->user,
$order->billing_address_id,
$card_data,
);
if (!$vaultId['success']) {
return \response()
->json([
'message' => "Can not process payment.",
'errors' => ["error" => ["Customer vault creation failed. Make sure you enter valid card credentials."]]
], Response::HTTP_INTERNAL_SERVER_ERROR);
}
//Charge customer using vault it just created.
$charge_response = chargeByVaultId(
$order->billing_address_id,
$vaultId['vault_id'],
$request->get('amount'),
);
} else {
//Charge by card information
$card_data = [
'card_number' => $request->get('card_number'),
'expiry_month' => $request->get('expiry_month'),
'expiry_year' => $request->get('expiry_year'),
'ccv' => $request->get('ccv'),
];
$charge_response = chargeByCard(
$order->billing_address_id,
$request->get('amount'),
$card_data,
);
}
if (!$charge_response['success']) {
return \response()
->json([
'message' => "Can not process payment.",
'errors' => ["error" => $charge_response["error"]]
], Response::HTTP_INTERNAL_SERVER_ERROR);
}
$charge_response['response']->order_id = $order->id;
$charge_response['response']->save();
$order->amount_paid = $charge_response['response']->amount_total;
$order->payment_id = $charge_response['response']->id;
}
} else if ($request->get('payment_type') == 'Purchase Order') {
$purchase_order_copy = $order->storePDF($request->file('purchase_order_copy'), $order->user_id, 'order');
$order->purchase_order_number = $request->get('purchase_order_number');
$order->purchase_order_copy = $purchase_order_copy;
$order->amount_paid = $request->get('amount');
} else if ($request->get('payment_type') == 'Check') {
$order->cheque_number = $request->get('cheque_number');
$order->amount_paid = $request->get('amount');
} else if ($request->get('payment_type') == 'Cash') {
$order->amount_paid = $request->get('amount');
}
$order->payment_status = 'Paid';
$order->payment_date = new \DateTime();
$order->save();
DB::commit();
return (new OrderResource($order))
->response()
->setStatusCode(Response::HTTP_CREATED);
}
public function update_order_type(Request $request, Order $order)
{
abort_if(Gate::denies('order_edit'), Response::HTTP_FORBIDDEN, '403 Forbidden');
$request->validate([
'order_type' => 'required|in:Order',
]);
if ($order->order_type == 'Order') {
return \response()
->json([
'message' => "Can not updated order type.",
'errors' => ['order_type' => ['The selected order type is already order.']]
])
->setStatusCode(Response::HTTP_UNPROCESSABLE_ENTITY);
}
$order->order_type = $request->get('order_type');
$approved_status = Status::where('name', 'Order Acknowledgement')->first();
$order->statuses()->attach($approved_status->id);
$order->current_status_id = $approved_status->id;
$order->save();
$order->createPurchaseOrderItem();
$data = [
'order_number' => $order->order_number,
];
$order->user->notify((new OrderQuoteUserNotification($data))->delay(now()->addSeconds(5)));
return (new OrderResource($order))
->response()
->setStatusCode(Response::HTTP_CREATED);
}
public function update_order_payment(Request $request, Order $order)
{
abort_if(Gate::denies('order_edit'), Response::HTTP_FORBIDDEN, '403 Forbidden');
$request->validate([
'payment_status' => 'required|in:' . implode(',', array_keys(Order::PAYMENT_STATUS_RADIO)),
]);
$order->payment_status = $request->get('payment_status');
$order->save();
return (new OrderResource($order))
->response()
->setStatusCode(Response::HTTP_CREATED);
}
public function update_date_scheduled(Request $request, Order $order)
{
abort_if(Gate::denies('order_edit'), Response::HTTP_FORBIDDEN, '403 Forbidden');
$request->validate([
'date_scheduled' => [
'required',
'date',
'after:today',
new ValidateDate,
],
]);
$order->date_scheduled = $request->get('date_scheduled');
$order->save();
return (new OrderResource($order))
->response()
->setStatusCode(Response::HTTP_CREATED);
}
public function update_date_ship_by(Request $request, Order $order)
{
abort_if(Gate::denies('order_edit'), Response::HTTP_FORBIDDEN, '403 Forbidden');
$request->validate([
'date_pick_or_ship_by' => [
'required',
'date',
'after:today',
new ValidateDate,
],
]);
$order->date_pick_or_ship_by = $request->get('date_pick_or_ship_by');
$order->save();
return (new OrderResource($order))
->response()
->setStatusCode(Response::HTTP_CREATED);
}
public function waive_off_sales_tax(Request $request, Order $order)
{
abort_if(Gate::denies('order_edit'), Response::HTTP_FORBIDDEN, '403 Forbidden');
$request->validate([
'waive_off_sales_tax' => 'required|boolean'
]);
$order->waive_off_sales_tax = $request->waive_off_sales_tax;
$order->save();
return (new OrderResource($order))
->response()
->setStatusCode(Response::HTTP_CREATED);
}
public function assign_order(Request $request, Order $order)
{
abort_if(Gate::denies('order_edit'), Response::HTTP_FORBIDDEN, '403 Forbidden');
$request->validate([
'user_id' => 'required|exists:users,id',
]);
$order->assigned_to_id = $request->user_id;
$order->save();
return (new OrderResource($order))
->response()
->setStatusCode(Response::HTTP_CREATED);
}
public function copyOrder(Order $order)
{
abort_if(Gate::denies('order_create'), Response::HTTP_FORBIDDEN, '403 Forbidden');
$date = now();
if ($date->isWeekend()) {
$day = $date->format('D');
$date = $day == 'Sat' ? $date->addDays(2) : $date->addDay();
}
$date = $date->format('m/d/Y');
$current_status = Status::where('name', 'Pending')->first();
$order_request = [
'user_id' => $order->user_id,
'order_type' => $order->order_type,
'rush_order' => $order->rush_order,
'event_date' => $date,
'date_scheduled' => $date,
'date_pick_or_ship_by' => $date,
'current_status_id' => $current_status->id,
'description' => $order->description,
'billing_address_id' => $order->billing_address_id,
'delivery_type' => $order->delivery_type,
'payment_status' => 'Unpaid',
'payment_mode' => 'Full',
'payment_type' => 'None',
];
if ($order->coupon_code != null) {
$order_request['coupon_code'] = $order->coupon_code;
}
//Collection Delivery Information
if ($order->delivery_type == 'Shipping') {
$order_request['shipping_address_id'] = $order->shipping_address_id;
if ($order->career_code == '3ps') {
$order_request['third_party_shipping'] = true;
$order_request['shipping_total_amount'] = $order->shipping_charges;
}
$order_request['career_code'] = $order->career_code;
$order_request['service_code'] = $order->service_code;
$order_request['package_type_code'] = $order->package_type_code;
$order_request['is_residential'] = $order->is_residential;
} else {
$order_request['pickup_location_id'] = $order->pickup_location_id;
}
//Collect Sells Tax Information
if ($order->waive_off_sales_tax == 1) {
$order_request['waive_off_sales_tax'] = 1;
$order_request['waive_off_sales_tax_reason'] = $order->waive_off_sales_tax_reason;
$order_request['resale_number'] = $order->resale_number;
}
$order_request['products'] = $this->getOrderProducts($order);
$request = new StoreOrderRequest();
$request->merge($order_request);
$response = $this->callPostRoute('/api/v1/admin/add-order?order_id=' . $order->id, $order_request);
$status = $response['status'];
unset($response['status']);
return response()->json($response)->setStatusCode($status);
}
/**
* @throws GuzzleException
*/
private function callPostRoute($url, $data)
{
$url = url($url);
$client = new Client();
$headers = [
'Authorization' => 'Bearer ' . request()->bearerToken(),
'accept' => 'application/json',
'Content-Type' => 'application/json',
];
$request = new \GuzzleHttp\Psr7\Request('POST', $url, $headers, json_encode($data));
$response = $client->sendAsync($request)->wait();
$statusCode = $response->getStatusCode();
if ($statusCode == 201) {
$response = json_decode($response->getBody(), true);
$order_id = $response['data']['id'];
return [
'success' => true,
'data' => $order_id,
'status' => 200,
];
} else {
return [
'success' => false,
'data' => null,
'status' => 422,
];
}
}
private function getOrderProducts(Order $order)
{
$products = [];
foreach ($order->items as $item) {
$price_range = ProductVariationRange::where('product_price_id', $item->price_id)
->where('qty_from', '<=', $item->quantity)
->where('qty_to', '>=', $item->quantity)
->first();
if ($price_range) {
$product = [
'product_id' => $item->product_id,
'price_id' => $item->price_id,
'quantity' => $item->quantity,
'notes' => $item->notes,
];
//Do not copy old artwork files (CR)
/*if ($item->customization != null) {
$product['customization'] = $item->customization == '[]' ? [] : $item->customization;
}*/
//Commenting due to data not available on local
/*if ($item->template != null) {
$exists = Storage::disk('order')->exists($order->template);
if ($exists) {
$path = Storage::disk('order')->path($order->template);
$file = new File($path);
$product['template'] = $file;
}
}*/
$products[] = $product;
}
}
return $products;
}
public function orderNotes(Request $request, Order $order)
{
abort_if(Gate::denies('order_edit'), Response::HTTP_FORBIDDEN, '403 Forbidden');
$request->validate([
'note' => 'required|string|max:500',
'note_document' => 'sometimes|mimes:pdf,doc,docx,xls,xlsx,jpg,jpeg,png,bmp,gif|max:20480'
], [
'note_document.max' => 'The note document may not be greater than 20MB',
]);
$note = OrderNotes::create([
'order_id' => $order->id,
'note' => $request->note,
'user_id' => auth()->id(),
]);
if ($request->hasFile('note_document')) {
$note->addMediaFromRequest('note_document')
->toMediaCollection('note_attachments', 'order')->save();
}
return \response()
->json(['message' => 'Note created successfully'])
->setStatusCode(Response::HTTP_CREATED);
}
public function getOrderNotes(Order $order)
{
abort_if(Gate::denies('order_access'), Response::HTTP_FORBIDDEN, '403 Forbidden');
OrderNotesResource::withoutWrapping();
return OrderNotesResource::collection($order->notes);
}
public function store(StoreOrderRequest $request)
{
$orderObj = new Order();
$order_totals = $orderObj->getOrderTotals($request);
$charge_response = null;
$charged_successfully = false;
$is_partial = $request->get('payment_mode') == 'Partial';
//Check if partial amount is greater than order total
if ($is_partial && $request->get('payment_amount') > $order_totals['grand_total']) {
return \response()
->json([
'message' => "Can not create order.",
'errors' => ["error" => "Partial amount is greater than order total ($" . $order_totals['grand_total'] . ")."]
], Response::HTTP_UNPROCESSABLE_ENTITY);
}
if ($request->get('payment_type') == 'Credit Card') {
if ($is_partial && $request->get('payment_amount') > 0) {
$charge_response = handleOrderCharge($request, ['grand_total' => $request->get('payment_amount')]);
$charged_successfully = $charge_response['charged_successfully'];
if (!$charged_successfully) {
return \response()
->json([
'message' => "Can not create order.",
'errors' => $charge_response["errors"]
], $charge_response["error_code"]);
}
} else if ($request->get('payment_status') == "Paid") {
$charge_response = handleOrderCharge($request, $order_totals);
$charged_successfully = $charge_response['charged_successfully'];
if (!$charged_successfully) {
return \response()
->json([
'message' => "Can not create order.",
'errors' => $charge_response["errors"]
], $charge_response["error_code"]);
}
}
}
$shipping_data = [];
//Billing Info of Order
$billing_address = $orderObj->getOrderAddress($request['billing_address_id'], 'billing');
if ($request['delivery_type'] == 'Shipping') {
$shipping_address = $orderObj->getOrderAddress($request['shipping_address_id'], 'shipping');
$shipping_data = getOrderShippingResponse($request);
$shipping_data['is_residential'] = $request->get('is_residential', false);
}
DB::beginTransaction();
try {
$cancellation_charges = SiteSetting::where('key', 'Cancel Order Fee')->first();
if ($is_partial) {
$payment_info['payment_type'] = 'None';
$payment_info['payment_status'] = 'Unpaid';
$payment_info['payment_date'] = null;
} else {
$payment_info = [
'payment_type' => $request->payment_type,
'payment_status' => $charged_successfully ? 'Paid' : $request->get('payment_status', 'Unpaid'),
'payment_date' => $charged_successfully || $request->get('payment_status') == 'Paid' ? new \DateTime() : null,
];
}
$order = Order::create(
array_merge(
$billing_address ?? [],
$shipping_address ?? [],
$shipping_data,
$payment_info,
[
'user_id' => $request->get('user_id'),
'current_status_id' => $request->get('current_status_id'),
'billing_address_id' => $request->get('billing_address_id'),
'shipping_address_id' => $request->get('delivery_type') == 'Shipping' ? $request->get('shipping_address_id') : null,
'pickup_location_id' => $request->get('delivery_type') == 'Pickup' ? $request->get('pickup_location_id') : null,
'date_scheduled' => $request->get('date_scheduled'),
'date_pick_or_ship_by' => $request->get('date_pick_or_ship_by'),
'event_date' => $request->get('event_date'),
'delivery_type' => $request->get('delivery_type'),
'order_type' => $request->get('order_type'),
'waive_off_sales_tax' => $request->get('waive_off_sales_tax'),
'waive_off_sales_tax_reason' => $request->get('waive_off_sales_tax_reason'),
'resale_number' => $request->get('resale_number'),
'rush_order' => $request->get('rush_order'),
'description' => $request->get('description'),
'admin_approved' => 1,
'created_by_user_id' => auth()->id(),
'payment_mode' => $request->get('payment_mode'),
'cancellation_charges' => $cancellation_charges->value ?? 0,
'items_total' => $order_totals['items_total'],
'state_sales_tax' => $order_totals['sales_tax']['percentage'],
'sales_tax_amount' => $order_totals['sales_tax']['amount'],
'rush_order_fee' => $order_totals['rush_order']['percentage'],
'rush_order_amount' => $order_totals['rush_order']['amount'],
],
)
);
if (isset($order_totals['discount']['order_discount'])) {
$order->coupon_id = $order_totals['discount']['coupon_id'];
$order->discount_type = $order_totals['discount']['discount_type'];
$order->discount_value = $order_totals['discount']['discount_value'];
$order->discount_total = $order_totals['discount']['order_discount'];
$coupon = Coupon::find($order->coupon_id);
$coupon->redemption_count = $coupon->redemption_count + 1;
$coupon->save();
}
$order->storeOrderProducts($request['products'], $request['user_id']);
$order->createPurchaseOrderItem();
$statuses[] = $request->current_status_id;
//Commenting prepopulating statuses on Client CR
/*if (!$is_duplicate) {
if (isset($response['artwork_check'])){
$artwork_status = Status::where('name', 'Artwork Received')->first();
$proof_received = Status::where('name', 'Proof sign off received')->first();
$statuses[] = $artwork_status->id;
$statuses[] = $proof_received->id;
} else {
$artwork_no_proof_status = Status::where('name', 'No proof needed')->first();
$statuses[] = $artwork_no_proof_status->id;
}
}*/
$order->order_number = $order->str_random2();
$order->statuses()->attach($statuses);
$order->grand_total = $order_totals['grand_total'];
//Handling payment info if order is partial
if ($is_partial) {
if ($request->get('payment_amount') > 0) {
//Creating partial record here
$partial_record = [
'order_id' => $order->id,
'charged_by_id' => auth()->id(),
'payment_type' => $request->get('payment_type'),
'amount' => $request->get('payment_amount'),
];
if ($request->payment_type == 'Purchase Order') {
$purchase_order_copy = $order->storePDF($request->file('purchase_order_copy'), $order->user_id, 'order');
$partial_record['purchase_order_number'] = $request->purchase_order_number;
$partial_record['purchase_order_copy'] = $purchase_order_copy;
} else if ($request->payment_type == 'Check') {
$partial_record['cheque_number'] = $request->get('cheque_number');
}
$partial = OrderPartialPayments::create($partial_record);
if ($charged_successfully) {
$charge_response['response']->order_id = $partial->id;
$charge_response['response']->save();
$partial->payment_id = $charge_response['response']->id;
$partial->save();
}
}
$order->paid_order_amount = $request->get('payment_amount', 0);
$order->remaining_order_amount = $order_totals['grand_total'] - $request->get('payment_amount', 0);
//Check if order is fully paid via partial
if ($order->remaining_order_amount == 0) {
$order->payment_status = 'Paid';
$order->payment_date = new \DateTime();
}
} else {
if ($request->payment_type == 'Purchase Order') {
$purchase_order_copy = $order->storePDF($request->file('purchase_order_copy'), $order->user_id, 'order');
$order->purchase_order_number = $request->purchase_order_number;
$order->purchase_order_copy = $purchase_order_copy;
} else if ($request->payment_type == 'Check') {
$order->cheque_number = $request->get('cheque_number');
}
if ($charged_successfully) {
$charge_response['response']->order_id = $order->id;
$charge_response['response']->save();
$order->payment_id = $charge_response['response']->id;
}
if ($order->payment_status == 'Paid') {
$order->paid_order_amount = $order_totals['grand_total'];
$order->remaining_order_amount = 0;
} else {
$order->remaining_order_amount = $order_totals['grand_total'];
}
}
$order->save();
$order->createInvoice(); //Generate invoice with latest information
if ($request->has('order_id')) {
$order->copyOrderNotes($request->get('order_id'));
}
//Send Order Status Update Email
$order->sendOrderStatusUpdatedMail($request->get('notes'));
DB::commit();
if ($charged_successfully) {
updatePJTransaction($charge_response['response']->transaction_id, $order->order_number);
}
return (new OrderResource($order))
->response()
->setStatusCode(Response::HTTP_CREATED);
} catch (\Exception $e) {
DB::rollBack();
if ($charged_successfully) {
$void_response = voidPJTransaction($charge_response['response']->transaction_id);
if ($void_response['success']) {
$charge_response['response']->delete();
} else {
Log::info('Transaction id : ' . $charge_response['response']->transaction_id . " was not voided.");
}
}
Log::info('DB Error : Admin Order Store');
Log::info($e->getMessage());
return \response()
->json([
'message' => "Can not create order.",
'errors' => ["error" => ["Unable to create order."]]
])
->setStatusCode(Response::HTTP_INTERNAL_SERVER_ERROR);
}
}
public function show(Order $order)
{
abort_if(Gate::denies('order_show'), Response::HTTP_FORBIDDEN, '403 Forbidden');
return new OrderInfoResource($order->load(['user', 'current_status', 'assigned_to', 'shipping_address', 'billing_address', 'items']));
}
public function showOrderInfo(Order $order)
{
abort_if(Gate::denies('order_show'), Response::HTTP_FORBIDDEN, '403 Forbidden');
return new OrderInfoEditResource($order->load(['user', 'current_status', 'assigned_to', 'shipping_address', 'billing_address', 'items']));
}
public function update(UpdateOrderRequest $request, Order $order)
{
$is_partial = $request->get('payment_mode') == 'Partial';
if ($order->payment_mode == 'Partial' && (!$is_partial)) {
return \response()
->json([
'message' => "Can not edit order.",
'errors' => ["error" => "Payment mode 'Partial' can not be converted 'Full'."]
], Response::HTTP_UNPROCESSABLE_ENTITY);
}
$shipping_data = [
'carrier_code' => null,
'service_code' => null,
'package_type_code' => null,
'shipping_charges' => null,
];
//Billing Info of Order
$billing_address = $order->getOrderAddress($request['billing_address_id'], 'billing');
if ($request['delivery_type'] == 'Shipping') {
//Shipping Info of Order
$shipping_address = $order->getOrderAddress($request['shipping_address_id'], 'shipping');
$shipping_data = getOrderShippingResponse($request);
$shipping_data['is_residential'] = $request->get('is_residential', false);
}
DB::beginTransaction();
$order_totals = $order->getOrderTotals($request, $order);
$amount_to_check = round($order_totals['grand_total'] - $order->paid_order_amount, 2);
$payment_amount = (float)$request->get('payment_amount');
if ($is_partial && $payment_amount > 0 && $payment_amount > $amount_to_check) {
return \response()
->json([
'message' => "Can not edit order.",
'errors' => ["error" => "Partial payment amount can not be greater than remaining amount ($" . $amount_to_check . ")."]
], Response::HTTP_UNPROCESSABLE_ENTITY);
}
$charge_response = null;
$charged_successfully = false;
if ($request->get('payment_status') == "Paid" && $order->payment_status != "Paid") {
if ($request->get('payment_type') == 'Credit Card') {
$charge_response = handleOrderCharge($request, $order_totals);
$charged_successfully = $charge_response['charged_successfully'];
if (!$charged_successfully) {
return \response()
->json([
'message' => "Can not update order.",
'errors' => $charge_response["errors"]
], $charge_response["error_code"]);
}
}
} else if ($is_partial && $request->get('payment_type') == 'Credit Card' && $request->get('payment_amount') > 0) {
$charge_response = handleOrderCharge($request, ['grand_total' => $order->remaining_order_amount]);
$charged_successfully = $charge_response['charged_successfully'];
if (!$charged_successfully) {
return \response()
->json([
'message' => "Can not update order.",
'errors' => $charge_response["errors"]
], $charge_response["error_code"]);
}
}
try {
$orderAmounts = [
'items_total' => $order_totals['items_total'],
'state_sales_tax' => $order_totals['sales_tax']['percentage'],
'sales_tax_amount' => $order_totals['sales_tax']['amount'],
'rush_order_fee' => $order_totals['rush_order']['percentage'],
'rush_order_amount' => $order_totals['rush_order']['amount'],
];
if ($is_partial) {
$payment_info['payment_type'] = 'None';
$payment_info['payment_status'] = 'Unpaid';
$payment_info['payment_date'] = null;
} else {
$payment_info = [
'payment_type' => $request->payment_type,
'payment_status' => $charged_successfully ? 'Paid' : $request->get('payment_status', 'Unpaid'),
'payment_date' => $charged_successfully || $request->get('payment_status') == 'Paid' ? new \DateTime() : null,
];
}
$order->update(
array_merge(
[
'user_id' => $request->get('user_id'),
'current_status_id' => $request->get('current_status_id'),
'billing_address_id' => $request->get('billing_address_id'),
'shipping_address_id' => $request->get('delivery_type') == 'Shipping' ? $request->get('shipping_address_id') : null,
'pickup_location_id' => $request->get('delivery_type') == 'Pickup' ? $request->get('pickup_location_id') : null,
'date_scheduled' => $request->get('date_scheduled'),
'date_pick_or_ship_by' => $request->get('date_pick_or_ship_by'),
'event_date' => $request->get('event_date'),
'delivery_type' => $request->get('delivery_type'),
'order_type' => $request->get('order_type'),
'waive_off_sales_tax' => $request->get('waive_off_sales_tax'),
'waive_off_sales_tax_reason' => $request->get('waive_off_sales_tax_reason'),
'resale_number' => $request->get('resale_number'),
'rush_order' => $request->get('rush_order'),
'description' => $request->get('description'),
'payment_mode' => $request->get('payment_mode'),
],
$payment_info,
$billing_address ?? [],
$shipping_address ?? [],
$orderAmounts,
$shipping_data,
)
);
if (isset($order_totals['discount']['order_discount'])) {
$order->coupon_id = $order_totals['discount']['coupon_id'];
$order->discount_type = $order_totals['discount']['discount_type'];
$order->discount_value = $order_totals['discount']['discount_value'];
$order->discount_total = $order_totals['discount']['order_discount'];
$coupon = Coupon::find($order->coupon_id);
$coupon->redemption_count = $coupon->redemption_count + 1;
$coupon->save();
} else if ($order->coupon_id != null) {
$order->coupon_id = null;
$order->discount_type = null;
$order->discount_value = null;
$order->discount_total = null;
}
if ($request->current_status_id != $order->current_status_id) {
$order->statuses()->attach($request->current_status_id);
}
$order->storeOrderProducts($request['products'], $request['user_id']);
$order->createPurchaseOrderItem();
$order->grand_total = $order_totals['grand_total'];
$order->remaining_order_amount = $order_totals['grand_total'] - $order->paid_order_amount; //To ensure we don't lose any amount if the grand total changes.
//Handling payment info if order is partial
if ($is_partial) {
if ($request->get('payment_amount') > 0) {
//Creating partial record here
$partial_record = [
'order_id' => $order->id,
'charged_by_id' => auth()->id(),
'payment_type' => $request->get('payment_type'),
'amount' => $request->get('payment_amount'),
];
if ($request->payment_type == 'Purchase Order') {
$partial_record['purchase_order_number'] = $request->purchase_order_number;
if ($request->hasFile('purchase_order_copy')) {
$purchase_order_copy = $order->storePDF($request->file('purchase_order_copy'), $order->user_id, 'order');
$partial_record['purchase_order_copy'] = $purchase_order_copy;
}
} else if ($request->payment_type == 'Check') {
$partial_record['cheque_number'] = $request->get('cheque_number');
}
$partial = OrderPartialPayments::create($partial_record);
if ($charged_successfully) {
$charge_response['response']->order_id = $partial->id;
$charge_response['response']->save();
$partial->payment_id = $charge_response['response']->id;
$partial->save();
}
$order->increment('paid_order_amount', $request->get('payment_amount'));
$order->decrement('remaining_order_amount', $request->get('payment_amount'));
}
$order->save();
} else {
if ($request->payment_type == 'Purchase Order') {
$order->purchase_order_number = $request->purchase_order_number;
if ($request->hasFile('purchase_order_copy')) {
$purchase_order_copy = $order->storePDF($request->file('purchase_order_copy'), $order->user_id, 'order');
$order->purchase_order_copy = $purchase_order_copy;
}
} else if ($request->payment_type == 'Check') {
$order->cheque_number = $request->get('cheque_number');
}
if ($charged_successfully) {
$charge_response['response']->order_id = $order->id;
$charge_response['response']->save();
$order->payment_id = $charge_response['response']->id;
}
if ($order->payment_status == 'Paid') {
$order->paid_order_amount = $order_totals['grand_total'];
$order->remaining_order_amount = 0;
}
}
$order->save();
if ($order->remaining_order_amount <= 0) {
$order->payment_status = 'Paid';
$order->payment_date = new \DateTime();
}
$order->save();
$order->createInvoice(); //Generate invoice with latest information
DB::commit();
if ($charged_successfully) {
updatePJTransaction($charge_response['response']->transaction_id, $order->order_number);
}
return (new OrderResource($order))
->response()
->setStatusCode(Response::HTTP_CREATED);
} catch (\Exception $e) {
DB::rollBack();
Log::info($e->getMessage() . " on line " . $e->getLine());
if ($charged_successfully) {
$void_response = voidPJTransaction($charge_response['response']->transaction_id);
if ($void_response['success']) {
$charge_response['response']->delete();
} else {
Log::info('Transaction id : ' . $charge_response['response']->transaction_id . " was not voided.");
}
}
return \response()
->json([
'message' => "Can not update order.",
'errors' => ["error" => ["Unable to update order."]]
])
->setStatusCode(Response::HTTP_INTERNAL_SERVER_ERROR);
}
}
public function addProductsToOrder(AddOrderProductRequest $request)
{
abort_if(Gate::denies('order_create'), Response::HTTP_FORBIDDEN, '403 Forbidden');
DB::beginTransaction();
try {
$order = Order::find($request->get('order_id'));
$order->storeOrderProducts($request['products'], $order['user_id'], true);
$order->updateOrderCalculation();
$order->createPurchaseOrderItem();
DB::commit();
return (new OrderResource($order))
->response()
->setStatusCode(Response::HTTP_CREATED);
} catch (\Exception $e) {
DB::rollBack();
Log::info('DB Error : Admin Order Add Product');
Log::info($e->getMessage());
return \response()
->json([
'message' => "Can not create order.",
'errors' => ["error" => ["Unable to create order."]]
])
->setStatusCode(Response::HTTP_INTERNAL_SERVER_ERROR);
}
}
public function getPaymentTypes()
{
return \response()
->json(['data' => Order::PAYMENT_TYPE_RADIO], Response::HTTP_OK);
}
public function getPaymentModes()
{
return \response()
->json(['data' => Order::PAYMENT_MODE_RADIO], Response::HTTP_OK);
}
public function getWaiveOffReasons()
{
return \response()
->json(['data' => Order::WAIVE_OFF_OPTIONS], Response::HTTP_OK);
}
public function getPaymentStatuses()
{
return \response()
->json(['data' => Order::PAYMENT_STATUS_RADIO], Response::HTTP_OK);
}
public function getCalendarWidgetData()
{
$start_week = now()->startOfWeek();
$end_week = now()->startOfWeek()->addDays(13);
$orders = Order::whereBetween('date_scheduled', [$start_week, $end_week])
->select('date_scheduled', DB::raw('count(*) as total'))
->groupBy('date_scheduled')
->get();
$old_date = now()->subDays(3)->startOfDay();
$exclude_status_ids = [
1, //Pending
10, //Cancelled
13, //Completed
14 //Picked / Shipped
];
for ($i = $start_week; $i <= $end_week; $i->addDay()) {
$order = $orders->where('date_scheduled', $i)->first();
$total = $order->total ?? 0;
$color = match (true) {
in_array($total, range(1, 5)) => '#008000',
in_array($total, range(6, 11)) => '#1890ff',
in_array($total, range(12, 18)) => '#FFA500',
$total > 18 => '#FF0000',
default => '',
};
$data[] = [
'date' => $i->format('Y-m-d'),
'day' => substr($i->format('D'), 0, 1),
'total' => $order->total ?? 0,
'color' => $color,
];
}
$pd_orders = Order::where('date_scheduled', '<=', $old_date)->whereNotIn('current_status_id', $exclude_status_ids)->count();
return [$data ?? [], $pd_orders];
}
public function generateInvoice(Order $order)
{
abort_if(Gate::denies('invoice_show'), Response::HTTP_FORBIDDEN, '403 Forbidden');
$invoice = $order->createInvoice();
return response()
->json(['data' => $invoice->invoiceUrl ?? ''], Response::HTTP_OK);
}
public function viewInvoice(Order $order)
{
abort_if(Gate::denies('invoice_show'), Response::HTTP_FORBIDDEN, '403 Forbidden');
return response()
->json(['data' => $order->invoice->invoiceUrl ?? ''], Response::HTTP_OK);
}
public function getServices()
{
$api_key = config('app.web_ship_api_key');
$customer_id = config('app.web_ship_customer_id');
$base_url = config('app.web_ship_base_url');
$endpoint = "{$base_url}/customers/{$customer_id}/services";
$client = new Client();
$headers = [
'Authorization' => $api_key,
];
try {
$request = new \GuzzleHttp\Psr7\Request('GET', $endpoint, $headers);
$res = $client->sendAsync($request)->wait();
$statusCode = $res->getStatusCode();
if ($statusCode == 200) {
$services = json_decode($res->getBody(), true);
return response()
->json(['data' => $services], Response::HTTP_OK);
} else {
return response()
->json([
'errors' => 'Something went wrong',
'error' => ['Something went wrong']
], 422);
}
} catch (GuzzleException $exception) {
return response()
->json([
'errors' => 'Something went wrong',
'error' => [$exception->getMessage()]
], 422);
}
}
public function getShippingQuote(ShippingQuoteRequest $request)
{
$customer_id = config('app.web_ship_customer_id');
$base_url = config('app.web_ship_base_url');
$endpoint = "{$base_url}/customers/{$customer_id}/quote";
$request_body = prepareDataForShippingQuote($request);
$response = getShippingQuoteServices($request_body, $endpoint);
if ($response['success']) {
return response()
->json(['data' => $response['data']], Response::HTTP_OK);
} else {
return response()
->json([
'errors' => 'Something went wrong',
'error' => ['Something went wrong']
], 422);
}
}
public function updateBookingNumber(Request $request, Order $order)
{
$request->validate(['book_number' => 'required|string']);
$order->book_number = $request->book_number;
$order->save();
return (new OrderResource($order))
->response()
->setStatusCode(Response::HTTP_CREATED);
}
public function checkProductQuantity(Request $request)
{
$request->validate([
'price_id' => 'required|exists:product_prices,id',
'quantity' => 'required|int|min:1',
]);
$price_range = ProductVariationRange::where('product_price_id', $request->get('price_id'))
->where('qty_from', '<=', $request->get('quantity'))
->where('qty_to', '>=', $request->get('quantity'))->first();
if ($price_range) {
return \response()->json(['success' => true, 'message' => 'Quantity available.'])->setStatusCode(Response::HTTP_OK);
} else {
return \response()
->json([
'message' => "Quantity not available.",
'errors' => ['price_id' => ['Product quantity not available.']]
])
->setStatusCode(Response::HTTP_UNPROCESSABLE_ENTITY);
}
}
public function getOrderShippingLabel(Order $order)
{
if ($order->book_number == null) {
return response()
->json([
'errors' => 'Book number not found',
'error' => ['Order is not associated with any book number.']
], 422);
}
$customer_id = config('app.web_ship_customer_id');
$base_url = config('app.web_ship_base_url');
$endpoint = "{$base_url}/customers/{$customer_id}/shipments/28809441/label/PDF";
$api_key = config('app.web_ship_api_key');
$client = new Client();
$headers = [
'Authorization' => $api_key,
'accept' => 'application/json',
'Content-Type' => 'application/json',
];
try {
$request = new \GuzzleHttp\Psr7\Request('GET', $endpoint, $headers);
$res = $client->send($request);
$statusCode = $res->getStatusCode();
if ($statusCode == 200 && $res->getHeaderLine('Content-Type') == "application/pdf") {
$label = 'shipping-label.pdf';
Storage::disk('public')->put($label, $res->getBody()->getContents());
return \response()->json(['data' => asset("storage/{$label}")])
->setStatusCode(Response::HTTP_OK);
} else {
return \response()
->json([
'message' => "Something went wrong!",
'errors' => ['shipping_label' => ['Unable to fetch shipping label.']]
])
->setStatusCode(Response::HTTP_UNPROCESSABLE_ENTITY);
}
} catch (GuzzleException $exception) {
// Log::info('getOrderShippingLabel error');
// Log::info($exception->getMessage());
return \response()
->json([
'message' => "Something went wrong!",
'errors' => ['shipping_label' => ['Unable to fetch shipping label.']]
])
->setStatusCode(Response::HTTP_UNPROCESSABLE_ENTITY);
}
}
public function getCustomerVaults(Request $request)
{
abort_if(Gate::denies('order_create'), Response::HTTP_FORBIDDEN, '403 Forbidden');
$request->validate([
'user_id' => 'required|exists:users,id',
]);
$user = User::where('id', $request->user_id)->where('user_type', '<>', 1)->first();
if (!$user) {
return \response()->json([
'message' => 'User not found',
'errors' => ['error' => 'User not found.'],
])->setStatusCode(Response::HTTP_UNPROCESSABLE_ENTITY);
}
$customer_id = $user->pj_customer_id;
if (!$customer_id) {
return \response()->json([
'message' => 'Customer id not associated',
'errors' => ['error' => 'Customer id not associated with user.'],
])->setStatusCode(Response::HTTP_UNPROCESSABLE_ENTITY);
}
$vaults = getCustomerVaults($customer_id);
return \response()
->json(['data' => $vaults])
->setStatusCode(Response::HTTP_OK);
}
public function getOrderTotals(OrderTotalsRequest $request)
{
$orderObj = new Order();
return \response()->json([
'data' => $orderObj->getOrderTotals($request)
])
->setStatusCode(Response::HTTP_OK);
}
public function getWorkOrder(Order $order)
{
return new WorkOrder($order->load(['user', 'current_status', 'assigned_to', 'shipping_address', 'billing_address', 'items']));
}
public function getOrderItemCustomizationSvg(OrderCustomizationSvgRequest $request)
{
// Generate a unique filename for the SVG file
$filename = 'svg_' . time() . '.svg';
$svg = OrderItemCustomizationSvg::create([
'order_id' => $request->order_id,
'order_item_id' => $request->order_item_id,
'customization_index' => $request->customization_index,
'file_content' => $request->file_content,
'file_name' => $filename,
]);
Storage::disk('customization_svg')->put($filename, $request->input('file_content'));
return \response()->json(['data' => $svg]);
}
public function deleteOrder(Order $order)
{
$item_ids = $order->items->pluck('id')->toArray();
OrderInvoice::where('order_id', $order->id)->delete();
OrderItemCustomizationSvg::where('order_id', $order->id)->delete();
OrderItemCustomizationData::whereIn('id', $item_ids)->delete();
OrderItemVariation::where('order_id', $order->id)->delete();
OrderNotes::where('order_id', $order->id)->delete();
DB::table('order_status')->where('order_id', $order->id)->delete();
OrderItems::where('order_id', $order->id)->delete();
PurchaseOrderToCreate::where('order_id', $order->id)->delete();
$order->delete();
return response()
->json(['message' => 'Order deleted successfully.'], Response::HTTP_OK);
}
public function addOrderPartialPayment(AddOrderPartialPaymentRequest $request, Order $order)
{
abort_if(Gate::denies('order_edit'), Response::HTTP_FORBIDDEN, '403 Forbidden');
if ($order->payment_mode != 'Partial') {
return \response()
->json([
'message' => "Can not add payment.",
'errors' => ["payment_amount" => "The partial payment is not applicable on this order."]
], Response::HTTP_UNPROCESSABLE_ENTITY);
}
if ($order->remaining_order_amount == 0) {
return \response()
->json([
'message' => "Can not add payment.",
'errors' => ["error" => "This order has been fully paid."]
], Response::HTTP_UNPROCESSABLE_ENTITY);
}
if ($request->get('payment_amount') > $order->remaining_order_amount) {
return \response()
->json([
'message' => "Can not add payment.",
'errors' => ["payment_amount" => "Partial amount is greater than remaining amount ($" . $order->remaining_order_amount . ")."]
], Response::HTTP_UNPROCESSABLE_ENTITY);
}
DB::beginTransaction();
try {
$charge_response = null;
$charged_successfully = false;
$order_totals['grand_total'] = $request->get('payment_amount');
if ($request->get('payment_type') == 'Credit Card') {
$request->merge([
'billing_address_id' => $order->billing_address_id,
'user_id' => $order->user_id,
]);
$charge_response = handleOrderCharge($request, $order_totals);
$charged_successfully = $charge_response['charged_successfully'] ?? false;
if (!$charged_successfully) {
return \response()
->json([
'message' => "Can not add payment.",
'errors' => $charge_response["errors"]
], $charge_response["error_code"]);
}
}
$partial_record = [
'order_id' => $order->id,
'charged_by_id' => auth()->id(),
'payment_type' => $request->get('payment_type'),
'amount' => $request->get('payment_amount'),
];
if ($request->payment_type == 'Purchase Order') {
$purchase_order_copy = $order->storePDF($request->file('purchase_order_copy'), $order->user_id, 'order');
$partial_record['purchase_order_number'] = $request->purchase_order_number;
$partial_record['purchase_order_copy'] = $purchase_order_copy;
} else if ($request->payment_type == 'Check') {
$partial_record['cheque_number'] = $request->get('cheque_number');
}
$partial = OrderPartialPayments::create($partial_record);
if ($charged_successfully) {
$charge_response['response']->order_id = $partial->id;
$charge_response['response']->save();
$partial->payment_id = $charge_response['response']->id;
$partial->save();
}
$order->increment('paid_order_amount', $request->get('payment_amount'));
$order->decrement('remaining_order_amount', $request->get('payment_amount'));
//Check if order is fully paid via partial
if ($order->remaining_order_amount == 0) {
$order->payment_status = 'Paid';
$order->payment_date = new \DateTime();
}
$order->save();
DB::commit();
if ($charged_successfully) {
updatePJTransaction($charge_response['response']->transaction_id, $order->order_number);
}
return response()
->json(['message' => 'Partial payment added successfully.'])
->setStatusCode(Response::HTTP_CREATED);
} catch (\Exception $e) {
DB::rollBack();
Log::info('Partial Payment Error on line :' . $e->getLine());
Log::info($e->getMessage());
if ($charged_successfully) {
$void_response = voidPJTransaction($charge_response['response']->transaction_id);
if ($void_response['success']) {
$charge_response['response']->delete();
} else {
Log::info('Transaction id : ' . $charge_response['response']->transaction_id . " was not voided.");
}
}
return \response()
->json([
'message' => "Can not add payment.",
'errors' => ["payment_amount" => ["Unable to add partial payment."]]
])
->setStatusCode(Response::HTTP_INTERNAL_SERVER_ERROR);
}
}
public function deleteOrderPartialPayment(OrderPartialPayments $orderPartialPayment)
{
abort_if(Gate::denies('order_edit'), Response::HTTP_FORBIDDEN, '403 Forbidden');
$order = Order::find($orderPartialPayment->order_id);
$order->payment_status = 'Unpaid';
$order->payment_date = null;
$order->increment('remaining_order_amount', $orderPartialPayment->amount);
$order->decrement('paid_order_amount', $orderPartialPayment->amount);
$order->save();
if ($orderPartialPayment->payment_id != null) {
$orderPartialPayment->payment->delete();
} else if ($orderPartialPayment->purchase_order_copy && (Storage::disk('order')->exists($orderPartialPayment->purchase_order_copy))) {
Storage::disk('order')->delete($orderPartialPayment->purchase_order_copy);
}
$orderPartialPayment->delete();
return response()
->json(['message' => 'Partial payment deleted successfully.'])
->setStatusCode(Response::HTTP_CREATED);
}
/**
* @throws ContainerExceptionInterface
* @throws NotFoundExceptionInterface
*/
public function checkItemPriceChange(Request $request): \Illuminate\Http\JsonResponse
{
$request->validate([
'item_id' => 'required|exists:order_items,id',
'quantity' => 'required|numeric|min:1',
]);
$item = OrderItems::find($request->get('item_id'));
$price_range = ProductVariationRange::where('product_price_id', $item->price_id)
->where('qty_from', '<=', $item->quantity)
->where('qty_to', '>=', $item->quantity)
->first();
if ($price_range->price != $item->price && request()->get('quantity') > $item->quantity) {
return response()
->json([
'message' => "Quantity can not be increased.",
'errors' => ['quantity' => ['Product quantity can not be increased due to change in price. Please add the item as a new product to proceed.']]
])
->setStatusCode(Response::HTTP_UNPROCESSABLE_ENTITY);
} else {
return response()->json(['success' => true, 'message' => 'Quantity can be updated.'])->setStatusCode(Response::HTTP_OK);
}
}
}