873 lines
32 KiB
PHP
873 lines
32 KiB
PHP
<?php
|
|
|
|
namespace App\Repositories\Member\Transaction;
|
|
|
|
use App\Repositories\Member\Voucher\VoucherRepository;
|
|
use App\Models\Transaction;
|
|
use App\Models\Customer;
|
|
use App\Models\TransactionDetail;
|
|
use App\Models\TransactionStatus;
|
|
use App\Models\TransactionPayment;
|
|
use App\Models\XenditLink;
|
|
use App\Models\Location;
|
|
use App\Models\Items;
|
|
use App\Models\ItemReference;
|
|
use App\Models\Voucher;
|
|
use App\Models\Cart;
|
|
use Illuminate\Support\Facades\DB;
|
|
use App\Helpers\AutoNumbering;
|
|
use App\Models\CustomerPoint;
|
|
use App\Repositories\Member\ShippingRepository;
|
|
use App\Repositories\Pos\InvoiceRepository;
|
|
use Illuminate\Validation\ValidationException;
|
|
use App\ThirdParty\Xendit\Xendit;
|
|
use App\Models\TransactionShipping;
|
|
use Carbon\Carbon;
|
|
use Exception;
|
|
use App\Repositories\Auth\RoleRepository;
|
|
use Illuminate\Support\Facades\Notification;
|
|
use App\Notifications\Member\Transaction\NewOrder;
|
|
use App\Notifications\Member\Transaction\OrderPaid;
|
|
use App\Notifications\Member\Transaction\OrderProcessed;
|
|
use App\Notifications\Member\Transaction\OrderOnDelivery;
|
|
use App\Notifications\Member\Transaction\OrderDelivered;
|
|
use App\Notifications\Member\Transaction\OrderCanceled;
|
|
|
|
class TransactionRepository
|
|
{
|
|
|
|
var $shippingRepository;
|
|
var $invoiceRepository;
|
|
var $roleRepository;
|
|
var $voucherRepository;
|
|
var $xendit;
|
|
|
|
public function __construct(ShippingRepository $shippingRepository,
|
|
InvoiceRepository $invoiceRepository,
|
|
VoucherRepository $voucherRepository,
|
|
RoleRepository $roleRepository,
|
|
Xendit $xendit) {
|
|
$this->shippingRepository = $shippingRepository;
|
|
$this->invoiceRepository = $invoiceRepository;
|
|
$this->roleRepository = $roleRepository;
|
|
$this->voucherRepository = $voucherRepository;
|
|
$this->xendit = $xendit;
|
|
}
|
|
|
|
public function getList($params = [])
|
|
{
|
|
$customColumns = [
|
|
'user.name' => 'users.name',
|
|
];
|
|
|
|
$limit = @$params["limit"] ? (int) @$params["limit"] : 10;
|
|
$sortColumn = @$params["sort"]["column"] ? (@$customColumns[$params["sort"]["column"]] ? $customColumns[$params["sort"]["column"]] : $params["sort"]["column"]) : "id";
|
|
$sortDir = @$params["sort"]["dir"] ? $params["sort"]["dir"] : "desc";
|
|
|
|
$model = Transaction::select('transactions.*')
|
|
->leftJoin('address', 'address.id', 'transactions.address_id')
|
|
->leftJoin('users', 'users.id', 'transactions.user_id')
|
|
->when(@!$params['is_admin'], function ($query) {
|
|
$query->where('transactions.user_id', auth()->user()->id);
|
|
})
|
|
->when(@$params['status'], function ($query) use ($params) {
|
|
$query->where('transactions.status', $params['status']);
|
|
})
|
|
->when(@$params['filter']['multiple_status'] && !empty($params['filter']['multiple_status']), function($query) use ($params){
|
|
$query->whereIn("transactions.status", $params['filter']['multiple_status']);
|
|
})
|
|
->when(@$params['filter']['except'], function($query) use ($params){
|
|
$except = @$params['filter']['except'];
|
|
if (is_array($except)){
|
|
$query->whereNotIn("status", $except);
|
|
}else{
|
|
$query->where("status","<>", $except);
|
|
}
|
|
})
|
|
->when(@$params['filter']['start'], function($query) use ($params){
|
|
$query->whereDate("transactions.time", ">=", $params['filter']['start']);
|
|
})
|
|
->when(@$params['filter']['end'], function($query) use ($params){
|
|
$query->whereDate("transactions.time", "<=", $params['filter']['end']);
|
|
})
|
|
->when(@$params['search'], function($query) use ($params) {
|
|
$query->where(function($query) use ($params) {
|
|
$query->where('transactions.number', 'ilike', '%' . $params['search'] . '%')
|
|
->orWhere('users.name', 'ilike', '%' . $params['search'] . '%')
|
|
->orWhere('address.name', 'ilike', '%' . $params['search'] . '%');
|
|
});
|
|
})
|
|
->orderBy($sortColumn, $sortDir)
|
|
->paginate($limit);
|
|
|
|
return $model;
|
|
}
|
|
|
|
public function getListForExport($params = [])
|
|
{
|
|
$customColumns = [
|
|
'user.name' => 'users.name',
|
|
];
|
|
|
|
$limit = @$params["limit"] ? (int) @$params["limit"] : 10;
|
|
$sortColumn = @$params["sort"]["column"] ? (@$customColumns[$params["sort"]["column"]] ? $customColumns[$params["sort"]["column"]] : $params["sort"]["column"]) : "transactions.id";
|
|
$sortDir = @$params["sort"]["dir"] ? $params["sort"]["dir"] : "desc";
|
|
|
|
return Transaction::selectRaw("
|
|
transactions.*,
|
|
transaction_details.*,
|
|
coalesce(item_variants.description, items.name) as product_name,
|
|
item_reference.number as item_reference_number
|
|
")
|
|
->leftJoin('address', 'address.id', 'transactions.address_id')
|
|
->leftJoin('users', 'users.id', 'transactions.user_id')
|
|
->leftJoin('transaction_details', 'transaction_details.transaction_id', 'transactions.id')
|
|
->leftJoin('item_reference', 'item_reference.id', 'transaction_details.item_reference_id')
|
|
->leftJoin('items', 'items.id', 'item_reference.item_id')
|
|
->leftJoin('item_variants', 'item_variants.id', 'transaction_details.item_variant_id')
|
|
->when(@!$params['is_admin'], function ($query) {
|
|
$query->where('transactions.user_id', auth()->user()->id);
|
|
})
|
|
->when(@$params['status'], function ($query) use ($params) {
|
|
$query->where('transactions.status', $params['status']);
|
|
})
|
|
->when(@$params['filter']['multiple_status'] && !empty($params['filter']['multiple_status']), function($query) use ($params){
|
|
$query->whereIn("transactions.status", $params['filter']['multiple_status']);
|
|
})
|
|
->when(@$params['filter']['except'], function($query) use ($params){
|
|
$except = @$params['filter']['except'];
|
|
if (is_array($except)){
|
|
$query->whereNotIn("status", $except);
|
|
}else{
|
|
$query->where("status","<>", $except);
|
|
}
|
|
})
|
|
->when(@$params['filter']['start'], function($query) use ($params){
|
|
$query->whereDate("transactions.time", ">=", $params['filter']['start']);
|
|
})
|
|
->when(@$params['filter']['end'], function($query) use ($params){
|
|
$query->whereDate("transactions.time", "<=", $params['filter']['end']);
|
|
})
|
|
->when(@$params['search'], function($query) use ($params) {
|
|
$query->where(function($query) use ($params) {
|
|
$query->where('transactions.number', 'ilike', '%' . $params['search'] . '%')
|
|
->orWhere('users.name', 'ilike', '%' . $params['search'] . '%')
|
|
->orWhere('address.name', 'ilike', '%' . $params['search'] . '%');
|
|
});
|
|
})
|
|
->orderBy($sortColumn, $sortDir)
|
|
->get();
|
|
}
|
|
|
|
public function getCount($params = [])
|
|
{
|
|
$model = Transaction::select('transactions.*')
|
|
->leftJoin('address', 'address.id', 'transactions.address_id')
|
|
->leftJoin('users', 'users.id', 'transactions.user_id')
|
|
->when(@!$params['is_admin'], function ($query) {
|
|
$query->where('transactions.user_id', auth()->user()->id);
|
|
})
|
|
->when(@$params['status'], function ($query) use ($params) {
|
|
$query->where('transactions.status', $params['status']);
|
|
})
|
|
->when(@$params['filter']['multiple_status'] && !empty($params['filter']['multiple_status']), function($query) use ($params){
|
|
$query->whereIn("transactions.status", $params['filter']['multiple_status']);
|
|
})
|
|
->when(@$params['filter']['except'], function($query) use ($params){
|
|
$except = @$params['filter']['except'];
|
|
if (is_array($except)){
|
|
$query->whereNotIn("status", $except);
|
|
}else{
|
|
$query->where("status","<>", $except);
|
|
}
|
|
})
|
|
->select("status")
|
|
->addSelect(DB::raw("COUNT(*) as count"))
|
|
->groupBy("status")
|
|
->get();
|
|
|
|
return $model;
|
|
}
|
|
|
|
public function getlistItem(Transaction $transaction, $params = []) {
|
|
|
|
$limit = @$params["limit"] ? (int) @$params["limit"] : 10;
|
|
$sortColumn = @$params["sort"]["column"] ? $params["sort"]["column"] : "id";
|
|
$sortDir = @$params["sort"]["dir"] ? $params["sort"]["dir"] : "desc";
|
|
|
|
return TransactionDetail::select('transaction_details.*')
|
|
->leftJoin('item_reference', 'item_reference.id', 'transaction_details.item_reference_id')
|
|
->leftJoin('item_variants', 'item_variants.id', 'transaction_details.item_variant_id')
|
|
->where('transaction_id', $transaction->id)
|
|
->when(@$params['search'], function($query) use ($params) {
|
|
$query->where(function($query) use ($params) {
|
|
$query->where('item_variants.description', 'ilike', '%' . $params['search'] . '%')
|
|
->orWhere('item_reference.number', 'ilike', '%' . $params['search'] . '%');
|
|
});
|
|
})
|
|
->orderBy($sortColumn, $sortDir)
|
|
->paginate($limit);
|
|
}
|
|
|
|
public function setStatusTransaction($transactionId, $status, $note = '')
|
|
{
|
|
$user = auth()->user();
|
|
TransactionStatus::create([
|
|
'transaction_id' => $transactionId,
|
|
'time' => now(),
|
|
'note' => $note,
|
|
'status' => $status,
|
|
'user_id' => @$user->id ?? 0,
|
|
]);
|
|
}
|
|
|
|
public function getAmount($items)
|
|
{
|
|
$amount = 0;
|
|
|
|
foreach ($items as $detail)
|
|
{
|
|
$itemReference = ItemReference::findOrFail($detail['item_reference_id']);
|
|
$item = Items::findOrFail($itemReference->item_id);
|
|
$amount += $detail['qty'] * $item->unit_price;
|
|
}
|
|
|
|
return $amount;
|
|
}
|
|
|
|
|
|
public function createPayment($model){
|
|
|
|
$fees = [];
|
|
if ($model->shipping_price){
|
|
$fees[] =
|
|
[
|
|
"type" => "SHIPPING",
|
|
"value" => $model->shipping_price
|
|
];
|
|
}
|
|
if ($model->discount){
|
|
$fees[] =
|
|
[
|
|
"type" => "DISCOUNT",
|
|
"value" => $model->discount
|
|
];
|
|
}
|
|
|
|
$remaining_amount = ($model->subtotal + $model->shipping_price) - $model->discount;
|
|
|
|
$xendit_response = $this->xendit->createPaymentLink([
|
|
"external_id" => $model->number,
|
|
"amount" => $remaining_amount,
|
|
"items" => $model->details->map(function($cart){
|
|
return [
|
|
"name" => $cart->item->name,
|
|
"category" => @$cart->item->category->name ?? "GOODS",
|
|
"price" => $cart->unit_price,
|
|
"quantity" => $cart->qty
|
|
];
|
|
}),
|
|
"fees" => $fees
|
|
]);
|
|
|
|
|
|
if ($xendit_response){
|
|
$xendit_link = XenditLink::create([
|
|
"uid" => $xendit_response["id"],
|
|
"invoice_url" => $xendit_response["invoice_url"],
|
|
"user_id" => $xendit_response["user_id"],
|
|
"external_id" => $xendit_response["external_id"],
|
|
"status" => $xendit_response["status"],
|
|
"amount" => $xendit_response["amount"],
|
|
"expiry_date" => $xendit_response["expiry_date"]
|
|
]);
|
|
$payment = TransactionPayment::create([
|
|
"amount" => $remaining_amount,
|
|
"status" => "PENDING",
|
|
"transaction_id" => $model->id,
|
|
"method_type" => get_class($xendit_link),
|
|
"method_id" => $xendit_link->id
|
|
]);
|
|
}
|
|
$this->setStatusTransaction($model->id, 'WAIT_PAYMENT');
|
|
return $xendit_response;
|
|
}
|
|
|
|
|
|
public function create($data)
|
|
{
|
|
$model = DB::transaction(function () use ($data) {
|
|
$user = auth()->user();
|
|
$customer = Customer::where("user_id", $user->id)->first();
|
|
$location_id = $data["location_id"];
|
|
|
|
|
|
// validasi voucher
|
|
if ( @$data["vouchers"]){
|
|
$used_voucher = Voucher::whereIn("id", $data["vouchers"])->whereNotNull("used_at")->count();
|
|
if ($used_voucher){
|
|
throw ValidationException::withMessages([
|
|
"voucher" => "Voucher Telah digunakan "
|
|
]);
|
|
}
|
|
}
|
|
|
|
// get numbering
|
|
$auto = new AutoNumbering([
|
|
"type" => "TRX",
|
|
"location_id" => 0,
|
|
"prefix" => "TRX",
|
|
"pad" => 12
|
|
]);
|
|
$number = $auto->getCurrent();
|
|
$data["number"] = $number;
|
|
|
|
$items = collect(@$data["items"] ?? []);
|
|
|
|
$carts = Cart::where('user_id', $user->id)
|
|
->where("location_id", $data["location_id"])
|
|
->when(count($items) > 0, function($query) use ($items) {
|
|
$query->whereIn("item_reference_id", $items->pluck("item_reference_id"));
|
|
})
|
|
->get();
|
|
$carts = $carts->map(function($cart) use ($items){
|
|
$item = $items->firstWhere("item_reference_id", $cart->item_reference_id);
|
|
if ($item){
|
|
$cart->new_qty = $cart->qty - $item["qty"];
|
|
$cart->qty = $item["qty"];
|
|
}
|
|
return $cart;
|
|
});
|
|
|
|
if (count($carts) == 0){
|
|
throw ValidationException::withMessages([
|
|
"items" => "Tidak ada item di keranjang"
|
|
]);
|
|
}
|
|
|
|
// detail data process
|
|
$subtotal = 0;
|
|
$details = [];
|
|
foreach ($carts as $detail)
|
|
{
|
|
$convertion = 1;
|
|
if (@$detail->item->display_unit and @$detail->item->display_unit != @$detail->item->unit){
|
|
$convertions = DB::select("select to_qty / from_qty as conv from item_convertions where from_unit = ? and to_unit = ?", [$detail->item->display_unit, $detail->item->unit] );
|
|
$convertion = max((float) @$convertions[0]->conv, 1);
|
|
}
|
|
$d_price = @$detail->itemReference->discount->price ?? 0;
|
|
$s_price = @$detail->itemReference->price->price ?? 0;
|
|
$price = ( $s_price ? $s_price : $detail->item->net_price) * $convertion;
|
|
$price = ( $d_price ? $d_price : $price) * $convertion;
|
|
$total = $detail->qty * $price;
|
|
$details[] = [
|
|
'item_id' => $detail->item_id,
|
|
'item_variant_id' => $detail->item_variant_id,
|
|
'item_reference_id' => $detail->item_reference_id,
|
|
'qty' => $detail->qty,
|
|
'unit' => ($detail->item->display_unit ?? $detail->item->unit),
|
|
'unit_price' => $price,
|
|
'unit_cost' => $detail->item->unit_cost,
|
|
'total' => $total
|
|
];
|
|
$subtotal += $total;
|
|
}
|
|
|
|
|
|
// validasi voucher
|
|
if ( @$data["vouchers"]){
|
|
$used_vouchers = Voucher::whereIn("id", $data["vouchers"])->get();
|
|
foreach($used_vouchers as $v){
|
|
if ($subtotal < ((float) $v->min_sales)){
|
|
throw ValidationException::withMessages([
|
|
"voucher" => "Voucher minimal belanja ".$v->min_sales
|
|
]);
|
|
}
|
|
}
|
|
}
|
|
|
|
|
|
// get shipping_price
|
|
$list_shipping = $this->shippingRepository->getList($data);
|
|
$filtered_shipping = collect($list_shipping["pricing"])->filter(function($pricing) use ($data){
|
|
return $pricing["company"] == $data["courier_company"] &&
|
|
$pricing["type"] == $data["courier_type"];
|
|
})->values();
|
|
if (count($filtered_shipping) == 0){
|
|
throw ValidationException::withMessages([
|
|
"courier_company" => "Pilihan kurir tidak ditemukan"
|
|
]);
|
|
}
|
|
if ($subtotal >= 1000000){
|
|
$shipping_price = max($filtered_shipping[0]["price"] - 50000, 0);
|
|
}else{
|
|
$shipping_price = $filtered_shipping[0]["price"];
|
|
}
|
|
$valid_vouchers = $this->voucherRepository->getValidByItems($carts, $customer->id);
|
|
$vouchers = @$data["vouchers"] ? Voucher::whereIn("id", $data["vouchers"])
|
|
->whereIn("id",$valid_vouchers)
|
|
->get(): collect([]);
|
|
|
|
// discount
|
|
$discount = $vouchers->reduce(function($acc, $voucher){
|
|
return $acc + ($voucher->nominal);
|
|
},0);
|
|
|
|
$subtotal2 = $subtotal + $shipping_price;
|
|
$amount = max(0, $subtotal2 - $discount);
|
|
$discount = min($subtotal2, $discount);
|
|
|
|
|
|
// discount points
|
|
$discount_point = 0;
|
|
$use_customer_points = @$data["use_customer_points"] ?? 0;
|
|
if ($use_customer_points > 0){
|
|
$current_point = auth()->user()->customer->point;
|
|
|
|
// use_customer_points
|
|
if ($use_customer_points > $current_point){
|
|
throw ValidationException::withMessages([
|
|
"use_customer_points" => "Point tidak cukup. Poin anda " . number_format($current_point, 0, ",", ".")
|
|
]);
|
|
}
|
|
|
|
|
|
// convert point to amount
|
|
$point_to_amount = $use_customer_points * 1000;
|
|
|
|
$discount_point = min($point_to_amount, $amount);
|
|
|
|
$amount = max(0, $amount - $discount_point);
|
|
}
|
|
|
|
|
|
$model = Transaction::create([
|
|
'number' => $data['number'],
|
|
'address_id' => $data['address_id'],
|
|
'location_id' => $data['location_id'],
|
|
'courier_company' => $data['courier_company'],
|
|
'courier_type' => $data['courier_type'],
|
|
'shipping_price' => $shipping_price,
|
|
'user_id' => auth()->user()->id,
|
|
'customer_id' => @$customer->id,
|
|
'time' => now(),
|
|
'subtotal' => $subtotal,
|
|
'discount' => $discount,
|
|
'point' => $discount_point,
|
|
'amount' => $amount,
|
|
'status' => 'WAIT_PAYMENT',
|
|
]);
|
|
$model->details()->createMany($details);
|
|
|
|
|
|
$subtotal_remaining = $subtotal2;
|
|
foreach ($vouchers as $voucher) {
|
|
if ($subtotal_remaining <= 0){
|
|
continue;
|
|
}
|
|
|
|
$voucher->fill([
|
|
"used_at" => Carbon::now(),
|
|
"reference_used_id" => $model->id,
|
|
"reference_used_type" => get_class($model)
|
|
]);
|
|
$voucher->save();
|
|
|
|
TransactionPayment::create([
|
|
"amount" => min($voucher->nominal, $subtotal_remaining),
|
|
"status" => "PAID",
|
|
"transaction_id" => $model->id,
|
|
"method_type" => get_class($voucher),
|
|
"method_id" => $voucher->id
|
|
]);
|
|
|
|
$subtotal_remaining = max(0,$subtotal_remaining - $voucher->nominal);
|
|
}
|
|
|
|
if ($use_customer_points > 0){
|
|
$cp = CustomerPoint::create([
|
|
"customer_id" => $model->customer_id,
|
|
"point" => -1 * $use_customer_points,
|
|
"reference_type" => get_class($model),
|
|
"reference_id" => $model->id,
|
|
"description" => "Discount Point",
|
|
]);
|
|
|
|
$current_point = auth()->user()->customer->point;
|
|
|
|
if ($current_point < 0){
|
|
throw ValidationException::withMessages([
|
|
"use_customer_points" => "Point anda telah habis"
|
|
]);
|
|
}
|
|
|
|
TransactionPayment::create([
|
|
"amount" => $discount_point,
|
|
"status" => "PAID",
|
|
"transaction_id" => $model->id,
|
|
"method_type" => get_class($cp),
|
|
"method_id" => $cp->id
|
|
]);
|
|
}
|
|
|
|
// create payment
|
|
$fees = [
|
|
[
|
|
"type" => "SHIPPING",
|
|
"value" => $shipping_price
|
|
]
|
|
];
|
|
if ($discount){
|
|
$fees[] =
|
|
[
|
|
"type" => "DISCOUNT",
|
|
"value" => $discount
|
|
];
|
|
}
|
|
$remaining_amount = $amount;
|
|
if ($amount > 0){
|
|
$xendit_response = $this->xendit->createPaymentLink([
|
|
"external_id" => $model->number,
|
|
"amount" => $remaining_amount,
|
|
"items" => $carts->map(function($cart){
|
|
$detail = $cart;
|
|
$convertion = 1;
|
|
if (@$detail->item->display_unit and @$detail->item->display_unit != @$detail->item->unit){
|
|
$convertions = DB::select("select to_qty / from_qty as conv from item_convertions where from_unit = ? and to_unit = ?", [$detail->item->display_unit, $detail->item->unit] );
|
|
$convertion = max((float) @$convertions[0]->conv, 1);
|
|
}
|
|
|
|
$d_price = @$detail->itemReference->discount->price ?? 0;
|
|
$s_price = @$detail->itemReference->price->price ?? 0;
|
|
$price = ( $s_price ? $s_price : $detail->item->net_price) * $convertion;
|
|
$price = ( $d_price ? $d_price : $price) * $convertion;
|
|
|
|
return [
|
|
"name" => $cart->item->name,
|
|
"category" => @$cart->item->category->name ?? "GOODS",
|
|
"price" => $price,
|
|
"quantity" => $cart->qty
|
|
];
|
|
}),
|
|
"fees" => $fees
|
|
]);
|
|
|
|
if ($xendit_response){
|
|
|
|
$xendit_link = XenditLink::create([
|
|
"uid" => $xendit_response["id"],
|
|
"invoice_url" => $xendit_response["invoice_url"],
|
|
"user_id" => $xendit_response["user_id"],
|
|
"external_id" => $xendit_response["external_id"],
|
|
"status" => $xendit_response["status"],
|
|
"amount" => $xendit_response["amount"],
|
|
"expiry_date" => $xendit_response["expiry_date"]
|
|
]);
|
|
|
|
$payment = TransactionPayment::create([
|
|
"amount" => $remaining_amount,
|
|
"status" => "PENDING",
|
|
"transaction_id" => $model->id,
|
|
"method_type" => get_class($xendit_link),
|
|
"method_id" => $xendit_link->id
|
|
]);
|
|
}
|
|
|
|
$this->setStatusTransaction($model->id, 'WAIT_PAYMENT');
|
|
}else{
|
|
$model->status = 'WAIT_PROCESS';
|
|
$model->save();
|
|
$this->setStatusTransaction($model->id, 'WAIT_PROCESS');
|
|
}
|
|
|
|
|
|
// clear cart
|
|
|
|
foreach($carts as $cart){
|
|
if ($cart->new_qty <= 0){
|
|
$cart->delete();
|
|
}else{
|
|
$new_qty = $cart->new_qty;
|
|
unset($cart->new_qty);
|
|
$cart->update([
|
|
"qty" => $new_qty
|
|
]);
|
|
}
|
|
}
|
|
|
|
return $model;
|
|
});
|
|
|
|
return $model;
|
|
}
|
|
|
|
public function webhookPayment($data)
|
|
{
|
|
$paymentLink = XenditLink::where("uid", $data["id"])->firstOrFail();
|
|
$paymentLink->fill([
|
|
"payment_id" => @$data["payment_id"],
|
|
"paid_amount" => @$data["paid_amount"],
|
|
"payment_method" => @$data["payment_method"],
|
|
"bank_code" => @$data["bank_code"],
|
|
"payment_channel" => @$data["payment_channel"],
|
|
"payment_destination" => @$data["payment_destination"],
|
|
"received_amount" => @$data["adjusted_received_amount"],
|
|
"status" => @$data["status"],
|
|
"paid_at" => @$data["paid_at"]
|
|
]);
|
|
$paymentLink->save();
|
|
$paymentLink->payment()->update([
|
|
"status" => $paymentLink->status,
|
|
]);
|
|
|
|
$transaction = Transaction::find($paymentLink->payment->transaction_id);
|
|
if ($transaction && @$data["status"] == "PAID"){
|
|
|
|
if ($transaction->status != "WAIT_PROCESS"){ // once notify for first
|
|
$roleRepository = $this->roleRepository;
|
|
$users = $roleRepository->findUserByPermission("transaction.online");
|
|
$notification = new NewOrder($transaction);
|
|
Notification::send($users, $notification);
|
|
|
|
$notification2 = new OrderPaid($transaction);
|
|
$transaction->customer->user->notify($notification2);
|
|
}
|
|
|
|
$this->setStatusTransaction($transaction->id,'WAIT_PROCESS');
|
|
$transaction->status = 'WAIT_PROCESS';
|
|
$transaction->save();
|
|
}else if ($transaction && @$data["status"] == "EXPIRED"){
|
|
|
|
if ($transaction->status != "CANCELED"){
|
|
$this->cancel($transaction->id,"Oleh System");
|
|
}
|
|
}
|
|
|
|
return $paymentLink;
|
|
}
|
|
|
|
public function payment($id)
|
|
{
|
|
$model = DB::transaction(function () use ($id) {
|
|
|
|
$model = Transaction::findOrfail($id);
|
|
|
|
TransactionPayment::create([
|
|
'transaction_id' => $model->id,
|
|
'amount' => $model->amount,
|
|
'status' => 'PAID',
|
|
]);
|
|
|
|
$this->setStatusTransaction($model->id, 'WAIT_PROCESS');
|
|
|
|
$model->status = 'WAIT_PROCESS';
|
|
$model->save();
|
|
|
|
return $model;
|
|
});
|
|
|
|
return $model;
|
|
}
|
|
|
|
public function process($id)
|
|
{
|
|
$repository = $this->invoiceRepository;
|
|
$model = DB::transaction(function () use ($id, $repository) {
|
|
|
|
$model = Transaction::findOrfail($id);
|
|
|
|
$this->setStatusTransaction($model->id, 'ON_PROCESS');
|
|
|
|
$model->status = 'ON_PROCESS';
|
|
$model->save();
|
|
|
|
$invoice = $this->invoiceRepository->createFromOnline($model);
|
|
|
|
$vouchers = $model->vouchers;
|
|
foreach ($vouchers as $voucher) {
|
|
$repository->checkAffiliatorVoucher($invoice, $voucher);
|
|
}
|
|
|
|
return $model;
|
|
});
|
|
|
|
$user = @$model->customer->user;
|
|
if ($user){
|
|
$notification2 = new OrderProcessed($model);
|
|
$user->notify($notification2);
|
|
}
|
|
|
|
return $model;
|
|
}
|
|
|
|
public function deliver($id)
|
|
{
|
|
$model = DB::transaction(function () use ($id) {
|
|
|
|
$model = Transaction::findOrfail($id);
|
|
|
|
$shipping = TransactionShipping::where("transaction_id",$model->id)->first();
|
|
if ($shipping){
|
|
return $model;
|
|
}
|
|
// order shippping
|
|
$data = $this->shippingRepository->order($model);
|
|
|
|
if(empty($data)) {
|
|
throw new Exception('error failed create order');
|
|
}
|
|
|
|
$weight_total = collect($data["items"])->reduce(function($acc, $item){
|
|
$item = (object) $item;
|
|
return $acc + ($item->weight * $item->quantity);
|
|
},0);
|
|
|
|
$shipping = TransactionShipping::create([
|
|
"transaction_id" => $model->id,
|
|
|
|
"origin_address" => $data["origin"]["address"],
|
|
"origin_name" => $data["origin"]["contact_name"],
|
|
"origin_phone" => $data["origin"]["contact_phone"],
|
|
"origin_postal_code" => $data["origin"]["postal_code"],
|
|
"origin_latitude" => $data["origin"]["coordinate"]["latitude"],
|
|
"origin_longitude" => $data["origin"]["coordinate"]["longitude"],
|
|
"origin_note" => $data["origin"]["note"],
|
|
|
|
|
|
"destination_address" => @$data["destination"]["address"],
|
|
"destination_name" => @$data["destination"]["contact_name"],
|
|
"destination_phone" => @$data["destination"]["contact_phone"],
|
|
"destination_postal_code" => @$data["destination"]["postal_code"],
|
|
"destination_latitude" => @$data["destination"]["coordinate"]["latitude"],
|
|
"destination_longitude" => @$data["destination"]["coordinate"]["longitude"],
|
|
"destination_note" => @$data["destination"]["note"],
|
|
|
|
"shipper_name" => @$data["shipper"]["name"],
|
|
"shipper_phone" => @$data["shipper"]["phone"],
|
|
"shipper_email" => @$data["shipper"]["email"],
|
|
|
|
"uid" => $data["id"],
|
|
"tracking_id" => @$data["courier"]["tracking_id"],
|
|
"waybill_id" => @$data["courier"]["waybill_id"],
|
|
"company" => @$data["courier"]["company"],
|
|
"driver_name" => @$data["courier"]["driver_name"],
|
|
"driver_phone" => @$data["courier"]["driver_phone"],
|
|
"driver_photo_url" => @$data["courier"]["driver_photo_url"],
|
|
"driver_plate_number" => @$data["courier"]["driver_plate_number"],
|
|
"type" => @$data["courier"]["type"],
|
|
"insurance_amount" => @$data["insurance"]["amount"],
|
|
"insurance_fee" => @$data["insurance"]["fee"],
|
|
"weight_total" => $weight_total,
|
|
"price" => @$data["price"],
|
|
"note" => @$data["note"],
|
|
"status" => @$data["status"]
|
|
]);
|
|
|
|
$this->setStatusTransaction($model->id, 'ON_DELIVERY');
|
|
|
|
$model->status = 'ON_DELIVERY';
|
|
$model->save();
|
|
|
|
|
|
return $model;
|
|
});
|
|
|
|
|
|
$user = @$model->customer->user;
|
|
if ($user){
|
|
$notification2 = new OrderOnDelivery($model);
|
|
$user->notify($notification2);
|
|
}
|
|
|
|
return $model;
|
|
}
|
|
|
|
public function close($id)
|
|
{
|
|
$model = DB::transaction(function () use ($id) {
|
|
|
|
$model = Transaction::findOrfail($id);
|
|
|
|
$this->setStatusTransaction($model->id, 'CLOSED');
|
|
|
|
$model->status = 'CLOSED';
|
|
$model->save();
|
|
|
|
return $model;
|
|
});
|
|
|
|
return $model;
|
|
}
|
|
|
|
public function delivered($id)
|
|
{
|
|
$model = DB::transaction(function () use ($id) {
|
|
|
|
$model = Transaction::findOrfail($id);
|
|
|
|
$this->setStatusTransaction($model->id, 'DELIVERED');
|
|
|
|
$model->status = 'DELIVERED';
|
|
$model->save();
|
|
|
|
return $model;
|
|
});
|
|
|
|
$user = @$model->customer->user;
|
|
if ($user){
|
|
$notification2 = new OrderDelivered($model);
|
|
$user->notify($notification2);
|
|
}
|
|
|
|
return $model;
|
|
}
|
|
|
|
public function cancel($id, $note = "")
|
|
{
|
|
$model = DB::transaction(function () use ($id, $note) {
|
|
|
|
$model = Transaction::findOrfail($id);
|
|
$model->vouchers()->update([
|
|
"used_at" => null,
|
|
"reference_used_id" => null,
|
|
"reference_used_type" => null
|
|
]);
|
|
|
|
$this->setStatusTransaction($model->id, 'CANCELED', $note);
|
|
|
|
$model->status = 'CANCELED';
|
|
$model->save();
|
|
|
|
|
|
|
|
|
|
$customer_point = CustomerPoint::where("customer_id", $model->customer_id)
|
|
->where("reference_id", $model->id)
|
|
->where("reference_type", get_class($model))
|
|
->orderBy("id", "asc")
|
|
->first();
|
|
|
|
if ($customer_point){
|
|
CustomerPoint::create([
|
|
"customer_id" => $model->customer_id,
|
|
"point" => -1 * $customer_point->point,
|
|
"reference_type" => get_class($model),
|
|
"reference_id" => $model->id,
|
|
"description" => "Refund Discount Point",
|
|
]);
|
|
}
|
|
|
|
|
|
return $model;
|
|
});
|
|
|
|
$user = @$model->customer->user;
|
|
if ($user){
|
|
$notification2 = new OrderCanceled($model);
|
|
$user->notify($notification2);
|
|
}
|
|
|
|
return $model;
|
|
}
|
|
}
|