feat: add new transaction type and update cash transaction handling in TransactionService
This commit is contained in:
parent
1f47ec1939
commit
f32544ccce
@ -10,6 +10,7 @@ enum CashTransactionType: string
|
||||
|
||||
case DEPOSIT = 'deposit';
|
||||
case EXPENSE = 'expense';
|
||||
case TRANSACTION = 'transaction';
|
||||
case WITHDRAWAL = 'withdrawal';
|
||||
case EMPLOYEE_ADVANCE = 'employee_advance';
|
||||
case SALARY = 'salary';
|
||||
@ -19,6 +20,7 @@ public function label(): string
|
||||
return match ($this) {
|
||||
self::DEPOSIT => 'Deposit',
|
||||
self::EXPENSE => 'Pengeluaran',
|
||||
self::TRANSACTION => 'Transaksi',
|
||||
self::WITHDRAWAL => 'Withdrawal',
|
||||
self::EMPLOYEE_ADVANCE => 'Kasbon',
|
||||
self::SALARY => 'Gaji',
|
||||
|
||||
@ -75,6 +75,12 @@ protected function expenseType(Builder $query): void
|
||||
$query->where('type', CashTransactionType::EXPENSE);
|
||||
}
|
||||
|
||||
#[Scope]
|
||||
protected function transactionType(Builder $query): void
|
||||
{
|
||||
$query->where('type', CashTransactionType::TRANSACTION);
|
||||
}
|
||||
|
||||
#[Scope]
|
||||
protected function transfer(Builder $query): void
|
||||
{
|
||||
|
||||
@ -2,6 +2,7 @@
|
||||
|
||||
namespace App\Services\Admin\Manage;
|
||||
|
||||
use App\Enums\CashTransactionType;
|
||||
use App\Enums\OrderChannel;
|
||||
use App\Enums\OrderStatus;
|
||||
use App\Enums\PaymentType;
|
||||
@ -14,6 +15,7 @@
|
||||
use App\Models\ProductVariant;
|
||||
use App\Models\User;
|
||||
use App\Services\Concerns\HasStockAdjustment;
|
||||
use App\Services\Concerns\HandlesCashTransactions;
|
||||
use App\Services\Concerns\RegistersMedia;
|
||||
use App\Services\NotificationService;
|
||||
use App\Services\S3PresignedService;
|
||||
@ -23,7 +25,7 @@
|
||||
|
||||
class TransactionService
|
||||
{
|
||||
use HasStockAdjustment, RegistersMedia;
|
||||
use HasStockAdjustment, HandlesCashTransactions, RegistersMedia;
|
||||
|
||||
private const SELLING_PRICE_MAP = [
|
||||
PriceType::DISTRIBUTOR->value => PriceType::DISTRIBUTOR,
|
||||
@ -233,7 +235,14 @@ public function store(array $data): Order
|
||||
|
||||
$this->applyStock($data['items'], $stockType, -1);
|
||||
|
||||
if ($paymentType !== PaymentType::CASH->value) {
|
||||
if ($paymentType === PaymentType::CASH->value) {
|
||||
$cashTransaction = $this->creditCash(
|
||||
amount: $totalAmount,
|
||||
description: 'Pembayaran tunai: '.$order->order_number,
|
||||
type: CashTransactionType::TRANSACTION,
|
||||
);
|
||||
$order->update(['cash_transaction_id' => $cashTransaction->id]);
|
||||
} else {
|
||||
$this->syncPhoto($order, $data);
|
||||
}
|
||||
|
||||
@ -253,6 +262,7 @@ public function update(Order $order, array $data): Order
|
||||
$order = DB::transaction(function () use ($order, $data) {
|
||||
$order->load('orderItems');
|
||||
|
||||
$oldPaymentType = $order->payment_type;
|
||||
$oldStockType = $order->orderItems->first()?->stock_quality?->value ?? ProductStockQuality::GOOD->value;
|
||||
|
||||
$order->orderItems->each(function (OrderItem $item) use ($oldStockType) {
|
||||
@ -284,13 +294,15 @@ public function update(Order $order, array $data): Order
|
||||
}
|
||||
DB::table('order_items')->insert($itemRows);
|
||||
|
||||
$newPaymentType = $data['payment_type'] ?? $order->payment_type->value;
|
||||
|
||||
$order->update([
|
||||
'customer_id' => $data['customer_id'] ?? null,
|
||||
'marketing_id' => $data['marketing_id'] ?? null,
|
||||
'channel' => $data['channel'] ?? $order->channel->value,
|
||||
'price_type' => $priceType,
|
||||
'status' => ($data['is_completed'] ?? false) ? OrderStatus::COMPLETED : OrderStatus::PENDING,
|
||||
'payment_type' => $data['payment_type'] ?? $order->payment_type->value,
|
||||
'payment_type' => $newPaymentType,
|
||||
'tiktok_order_id' => $data['tiktok_order_id'] ?? null,
|
||||
'shopee_order_id' => $data['shopee_order_id'] ?? null,
|
||||
'subtotal' => $subtotal,
|
||||
@ -303,11 +315,39 @@ public function update(Order $order, array $data): Order
|
||||
|
||||
$this->applyStock($data['items'], $stockType, -1);
|
||||
|
||||
$paymentType = $data['payment_type'] ?? $order->payment_type->value;
|
||||
if ($paymentType !== PaymentType::CASH->value) {
|
||||
$this->syncPhoto($order, $data);
|
||||
} else {
|
||||
if ($oldPaymentType === PaymentType::CASH && $newPaymentType !== PaymentType::CASH->value) {
|
||||
if ($order->cash_transaction_id) {
|
||||
$order->cashTransaction()->delete();
|
||||
$order->update(['cash_transaction_id' => null]);
|
||||
}
|
||||
} elseif ($oldPaymentType !== PaymentType::CASH && $newPaymentType === PaymentType::CASH->value) {
|
||||
$cashTransaction = $this->creditCash(
|
||||
amount: $totalAmount,
|
||||
description: 'Pembayaran tunai: '.$order->order_number,
|
||||
type: CashTransactionType::TRANSACTION,
|
||||
);
|
||||
$order->update(['cash_transaction_id' => $cashTransaction->id]);
|
||||
} elseif ($oldPaymentType === PaymentType::CASH && $newPaymentType === PaymentType::CASH->value && $order->cash_transaction_id) {
|
||||
$cashTransaction = $order->cashTransaction;
|
||||
$oldAmount = $cashTransaction->amount;
|
||||
$difference = $totalAmount - $oldAmount;
|
||||
|
||||
if ($difference !== 0) {
|
||||
$cashAccount = \App\Models\CashAccount::firstOrFail();
|
||||
$newBalance = $cashAccount->balance + $difference;
|
||||
$cashAccount->update(['balance' => $newBalance]);
|
||||
|
||||
$cashTransaction->update([
|
||||
'amount' => $totalAmount,
|
||||
'balance_after' => $newBalance,
|
||||
]);
|
||||
}
|
||||
}
|
||||
|
||||
if ($newPaymentType === PaymentType::CASH->value) {
|
||||
$order->clearMediaCollection('photos');
|
||||
} else {
|
||||
$this->syncPhoto($order, $data);
|
||||
}
|
||||
|
||||
return $order;
|
||||
@ -336,6 +376,14 @@ public function destroy(Order $order): bool
|
||||
});
|
||||
}
|
||||
|
||||
if ($order->payment_type === PaymentType::CASH && $order->cash_transaction_id) {
|
||||
$this->debitCash(
|
||||
amount: $order->total_amount,
|
||||
description: 'Pembatalan transaksi: '.$order->order_number,
|
||||
type: CashTransactionType::EXPENSE,
|
||||
);
|
||||
}
|
||||
|
||||
$order->orderItems()->delete();
|
||||
$order->delete();
|
||||
|
||||
@ -365,6 +413,14 @@ public function updateStatus(Order $order, string $status): Order
|
||||
$order->orderItems->each(function (OrderItem $item) use ($stockType) {
|
||||
$this->adjustVariantStock($item->product_variant_id, $item->quantity, 1, $stockType);
|
||||
});
|
||||
|
||||
if ($order->payment_type === PaymentType::CASH && $order->cash_transaction_id) {
|
||||
$this->debitCash(
|
||||
amount: $order->total_amount,
|
||||
description: 'Pembatalan transaksi: '.$order->order_number,
|
||||
type: CashTransactionType::EXPENSE,
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
return $order;
|
||||
|
||||
@ -1,7 +1,7 @@
|
||||
import { RowActions } from '@/components/data-display';
|
||||
import { ImagePreviewButton } from '@/components/dialogs';
|
||||
import type { ColumnDef } from '@tanstack/react-table';
|
||||
import { Pencil, Trash2 } from 'lucide-react';
|
||||
import { ImagePreviewButton } from '@/components/dialogs';
|
||||
import { RowActions } from '@/components/data-display';
|
||||
|
||||
export type CashTransaction = {
|
||||
id: number;
|
||||
@ -32,7 +32,8 @@ function getTypeLabel(type: string): string {
|
||||
withdrawal: 'Withdrawal',
|
||||
expense: 'Pengeluaran',
|
||||
employee_advance: 'Kasbon',
|
||||
salary : 'Gaji'
|
||||
salary: 'Gaji',
|
||||
transaction: 'Transaksi'
|
||||
};
|
||||
|
||||
return labels[type] ?? type;
|
||||
@ -77,13 +78,13 @@ export function createTransactionColumns(
|
||||
header: () => <span>Jumlah</span>,
|
||||
cell: ({ row }) => {
|
||||
const transaction = row.original;
|
||||
const isDeposit = transaction.type === 'deposit';
|
||||
const isDeposit = transaction.type === 'deposit' || transaction.type === 'transaction';
|
||||
|
||||
return (
|
||||
<span
|
||||
className={
|
||||
isDeposit
|
||||
? 'font-medium text-green-600'
|
||||
? 'foknt-medium text-green-600'
|
||||
: 'font-medium text-red-600'
|
||||
}
|
||||
>
|
||||
|
||||
Loading…
Reference in New Issue
Block a user