Compare commits
5 Commits
2e578cd976
...
a29e6af430
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
a29e6af430 | ||
|
|
ba01039b41 | ||
|
|
ef90f8361f | ||
|
|
c16cfac861 | ||
|
|
bb17bf6ad4 |
@ -95,6 +95,8 @@ function () use ($cashAccount, $validated, $user): CashTransaction {
|
||||
'Gagal melakukan setoran kas',
|
||||
);
|
||||
|
||||
$this->cacheForget('finance:default_account');
|
||||
|
||||
$this->pushNotificationService->sendToRoles(
|
||||
'💰 Setoran Kas',
|
||||
"Setoran kas baru {$transaction->amount_formatted} dengan keterangan: {$transaction->description} oleh {$user->profile?->full_name}.",
|
||||
@ -138,6 +140,8 @@ function () use ($cashAccount, $validated, $user): CashTransaction {
|
||||
'Gagal melakukan tarik kas',
|
||||
);
|
||||
|
||||
$this->cacheForget('finance:default_account');
|
||||
|
||||
$this->pushNotificationService->sendToRoles(
|
||||
'🏦 Tarik Kas',
|
||||
"Tarik kas {$transaction->amount_formatted} dengan keterangan: {$transaction->description} oleh {$user->profile?->full_name}.",
|
||||
@ -155,7 +159,7 @@ public function recordOutgoing(
|
||||
User $user,
|
||||
?CashAccount $cashAccount = null,
|
||||
): CashTransaction {
|
||||
return $this->runInTransaction(
|
||||
$transaction = $this->runInTransaction(
|
||||
function () use ($reference, $amount, $description, $user, $cashAccount): CashTransaction {
|
||||
$account = CashAccount::query()->lockForUpdate()->findOrFail(
|
||||
($cashAccount ?? $this->getDefaultAccount())->id,
|
||||
@ -187,6 +191,10 @@ function () use ($reference, $amount, $description, $user, $cashAccount): CashTr
|
||||
},
|
||||
'Gagal mencatat transaksi keluar kas',
|
||||
);
|
||||
|
||||
$this->cacheForget('finance:default_account');
|
||||
|
||||
return $transaction;
|
||||
}
|
||||
|
||||
public function recordIncoming(
|
||||
@ -196,7 +204,7 @@ public function recordIncoming(
|
||||
User $user,
|
||||
?CashAccount $cashAccount = null,
|
||||
): CashTransaction {
|
||||
return $this->runInTransaction(
|
||||
$transaction = $this->runInTransaction(
|
||||
function () use ($reference, $amount, $description, $user, $cashAccount): CashTransaction {
|
||||
$account = CashAccount::query()->lockForUpdate()->findOrFail(
|
||||
($cashAccount ?? $this->getDefaultAccount())->id,
|
||||
@ -222,6 +230,10 @@ function () use ($reference, $amount, $description, $user, $cashAccount): CashTr
|
||||
},
|
||||
'Gagal mencatat transaksi masuk kas',
|
||||
);
|
||||
|
||||
$this->cacheForget('finance:default_account');
|
||||
|
||||
return $transaction;
|
||||
}
|
||||
|
||||
public function updateDeposit(CashTransaction $transaction, array $validated, User $user): void
|
||||
@ -250,6 +262,8 @@ function () use ($transaction, $validated): void {
|
||||
'Gagal memperbarui setoran kas',
|
||||
);
|
||||
|
||||
$this->cacheForget('finance:default_account');
|
||||
|
||||
$this->pushNotificationService->sendToRoles(
|
||||
'✏️ Transaksi Kas Diperbarui',
|
||||
"Transaksi kas dengan keterangan {$transaction->description} diperbarui menjadi senilai {$transaction->amount_formatted} oleh {$user->profile?->full_name}.",
|
||||
@ -269,7 +283,6 @@ function () use ($transaction): void {
|
||||
|
||||
$account = $transaction->cashAccount;
|
||||
|
||||
$transaction->clearMediaCollection('photos');
|
||||
$transaction->delete();
|
||||
|
||||
$this->recalculateBalances($account);
|
||||
@ -283,6 +296,8 @@ function () use ($transaction): void {
|
||||
'Gagal menghapus transaksi kas',
|
||||
);
|
||||
|
||||
$this->cacheForget('finance:default_account');
|
||||
|
||||
$this->pushNotificationService->sendToRoles(
|
||||
'🗑️ Transaksi Kas Dihapus',
|
||||
"Transaksi kas senilai {$amountFormatted} dengan keterangan {$description} telah dihapus oleh {$user->profile?->full_name}.",
|
||||
@ -317,6 +332,8 @@ function () use ($transaction, $amount, $description): void {
|
||||
},
|
||||
'Gagal memperbarui transaksi kas referensi',
|
||||
);
|
||||
|
||||
$this->cacheForget('finance:default_account');
|
||||
}
|
||||
|
||||
public function deleteReferencedTransaction(CashTransaction $transaction): void
|
||||
@ -338,6 +355,8 @@ function () use ($transaction): void {
|
||||
},
|
||||
'Gagal menghapus transaksi kas referensi',
|
||||
);
|
||||
|
||||
$this->cacheForget('finance:default_account');
|
||||
}
|
||||
|
||||
private function recalculateBalances(CashAccount $cashAccount): void
|
||||
|
||||
@ -133,7 +133,6 @@ function () use ($expense): void {
|
||||
$this->cashService->deleteReferencedTransaction($expense->cashTransaction);
|
||||
}
|
||||
|
||||
$expense->clearMediaCollection('photos');
|
||||
$expense->delete();
|
||||
},
|
||||
'Gagal menghapus pengeluaran',
|
||||
|
||||
@ -172,8 +172,6 @@ public function delete(Attendance $attendance, User $user): void
|
||||
|
||||
$this->runInTransaction(
|
||||
function () use ($attendance): void {
|
||||
$attendance->clearMediaCollection('checkin');
|
||||
$attendance->clearMediaCollection('checkout');
|
||||
$attendance->delete();
|
||||
},
|
||||
'Gagal menghapus presensi',
|
||||
|
||||
@ -128,6 +128,7 @@ function () use ($validated): User {
|
||||
'Gagal membuat karyawan',
|
||||
);
|
||||
|
||||
$this->cacheForget('system:assignable_roles');
|
||||
$this->cacheForgetByPattern('hr:employees:*');
|
||||
|
||||
$this->notifyOwner(
|
||||
@ -189,6 +190,7 @@ function () use ($validated, $user, $employee): void {
|
||||
'Gagal memperbarui karyawan',
|
||||
);
|
||||
|
||||
$this->cacheForget('system:assignable_roles');
|
||||
$this->cacheForgetByPattern('hr:employees:*');
|
||||
|
||||
$this->notifyOwner(
|
||||
@ -213,6 +215,7 @@ function () use ($user, $validated): void {
|
||||
'Gagal memperbarui status karyawan',
|
||||
);
|
||||
|
||||
$this->cacheForget('system:assignable_roles');
|
||||
$this->cacheForgetByPattern('hr:employees:*');
|
||||
|
||||
$statusLabel = $validated['is_active'] ? 'aktif' : 'nonaktif';
|
||||
@ -237,6 +240,7 @@ function () use ($user): void {
|
||||
'Gagal mereset kata sandi karyawan',
|
||||
);
|
||||
|
||||
$this->cacheForget('system:assignable_roles');
|
||||
$this->cacheForgetByPattern('hr:employees:*');
|
||||
|
||||
$this->notifyOwner(
|
||||
@ -259,6 +263,7 @@ function () use ($user): void {
|
||||
'Gagal menghapus karyawan',
|
||||
);
|
||||
|
||||
$this->cacheForget('system:assignable_roles');
|
||||
$this->cacheForgetByPattern('hr:employees:*');
|
||||
|
||||
$this->notifyOwner(
|
||||
|
||||
@ -680,7 +680,6 @@ function () use ($cutting): void {
|
||||
|
||||
$cutting->materials()->delete();
|
||||
$cutting->results()->delete();
|
||||
$cutting->clearMediaCollection('images');
|
||||
$cutting->delete();
|
||||
},
|
||||
'Gagal menghapus proses cutting',
|
||||
|
||||
@ -716,7 +716,6 @@ private function rejectCreate(OwnerVerificationRequest $verificationRequest): vo
|
||||
|
||||
$this->runInTransaction(
|
||||
function () use ($purchase): void {
|
||||
$purchase->clearMediaCollection('photos');
|
||||
$purchase->items()->delete();
|
||||
$purchase->delete();
|
||||
},
|
||||
@ -734,7 +733,6 @@ function () use ($purchase): void {
|
||||
$this->decrementStock($item);
|
||||
}
|
||||
|
||||
$purchase->clearMediaCollection('photos');
|
||||
$purchase->items()->delete();
|
||||
$purchase->delete();
|
||||
},
|
||||
|
||||
@ -573,7 +573,6 @@ private function rejectCreate(OwnerVerificationRequest $verificationRequest): vo
|
||||
|
||||
$this->runInTransaction(
|
||||
function () use ($restock): void {
|
||||
$restock->clearMediaCollection('photos');
|
||||
$restock->items()->delete();
|
||||
$restock->delete();
|
||||
},
|
||||
@ -593,7 +592,6 @@ function () use ($restock): void {
|
||||
$this->decrementStock($item, $stockType);
|
||||
}
|
||||
|
||||
$restock->clearMediaCollection('photos');
|
||||
$restock->items()->delete();
|
||||
$restock->delete();
|
||||
},
|
||||
|
||||
@ -156,9 +156,7 @@ public function submitVerification(
|
||||
}
|
||||
|
||||
$this->cacheForgetByPattern('manage:stocks:*');
|
||||
if ($isOwner) {
|
||||
$this->cacheForgetByPattern('prices:*');
|
||||
}
|
||||
$this->cacheForgetByPattern('prices:*');
|
||||
}
|
||||
|
||||
public function approveVerification(
|
||||
|
||||
@ -254,6 +254,7 @@ function () use ($validated, $product, $user, $isOwner): void {
|
||||
);
|
||||
|
||||
$this->cacheForgetByPattern('master:products:*');
|
||||
$this->cacheForgetByPattern('prices:*');
|
||||
$this->cacheForget('homepage:page_data');
|
||||
|
||||
if ($isOwner) {
|
||||
@ -328,6 +329,7 @@ public function delete(Product $product, User $user): void
|
||||
$name = $product->name;
|
||||
$this->applyDeleteSubject($product);
|
||||
$this->cacheForgetByPattern('master:products:*');
|
||||
$this->cacheForgetByPattern('prices:*');
|
||||
$this->cacheForget('homepage:page_data');
|
||||
|
||||
$this->notifyOwner(
|
||||
@ -435,6 +437,7 @@ public function applyVerificationRequest(OwnerVerificationRequest $verificationR
|
||||
};
|
||||
|
||||
$this->cacheForgetByPattern('master:products:*');
|
||||
$this->cacheForgetByPattern('prices:*');
|
||||
}
|
||||
|
||||
public function rejectVerificationRequest(OwnerVerificationRequest $verificationRequest): void
|
||||
@ -449,6 +452,7 @@ public function rejectVerificationRequest(OwnerVerificationRequest $verification
|
||||
};
|
||||
|
||||
$this->cacheForgetByPattern('master:products:*');
|
||||
$this->cacheForgetByPattern('prices:*');
|
||||
$this->cacheForget('homepage:page_data');
|
||||
}
|
||||
|
||||
@ -519,7 +523,6 @@ private function applyPayloadToProduct(
|
||||
->whereNotIn('id', $submittedVariantIds)
|
||||
->get()
|
||||
->each(function (ProductVariant $variant): void {
|
||||
$variant->clearMediaCollection('images');
|
||||
$variant->delete();
|
||||
});
|
||||
|
||||
@ -586,9 +589,6 @@ private function applyDeleteSubject(Product $product): void
|
||||
{
|
||||
$this->runInTransaction(
|
||||
function () use ($product): void {
|
||||
$product->variants()->each(function (ProductVariant $variant): void {
|
||||
$variant->clearMediaCollection('images');
|
||||
});
|
||||
$product->variants()->delete();
|
||||
$product->categories()->detach();
|
||||
$product->delete();
|
||||
@ -656,9 +656,6 @@ private function rejectCreate(OwnerVerificationRequest $verificationRequest): vo
|
||||
|
||||
$this->runInTransaction(
|
||||
function () use ($product): void {
|
||||
$product->variants()->each(function (ProductVariant $variant): void {
|
||||
$variant->clearMediaCollection('images');
|
||||
});
|
||||
$product->variants()->delete();
|
||||
$product->categories()->detach();
|
||||
$product->delete();
|
||||
|
||||
@ -37,6 +37,24 @@ public function paginateForIndex(array $tableQuery, string $isActive, string $st
|
||||
->with('media')
|
||||
->when($tableQuery['search'] !== '', function ($query) use ($tableQuery): void {
|
||||
$query->where('variant', 'like', "%{$tableQuery['search']}%");
|
||||
})
|
||||
->when($stockStatus === 'out_of_stock', fn ($q) => $q->where('stock', '<=', 0))
|
||||
->when($stockStatus === 'low_stock', function ($q): void {
|
||||
$q->where('stock', '>', 0)
|
||||
->where(function ($q): void {
|
||||
$q->orWhere(function ($q): void {
|
||||
$q->whereHas('rawMaterial', fn ($q) => $q->where('unit', RawMaterialUnit::YARD->value))
|
||||
->where('stock', '<', 20);
|
||||
})
|
||||
->orWhere(function ($q): void {
|
||||
$q->whereHas('rawMaterial', fn ($q) => $q->where('unit', RawMaterialUnit::METER->value))
|
||||
->where('stock', '<', 10);
|
||||
})
|
||||
->orWhere(function ($q): void {
|
||||
$q->whereHas('rawMaterial', fn ($q) => $q->where('unit', RawMaterialUnit::KILOGRAM->value))
|
||||
->where('stock', '<', 5);
|
||||
});
|
||||
});
|
||||
}),
|
||||
])
|
||||
->when(($tableQuery['search_id'] ?? '') !== '', function (Builder $query) use ($tableQuery): void {
|
||||
@ -52,21 +70,15 @@ public function paginateForIndex(array $tableQuery, string $isActive, string $st
|
||||
$query->whereHas('prices', fn (Builder $priceQuery) => $priceQuery->where('stock', '<=', 0));
|
||||
})
|
||||
->when($stockStatus === 'low_stock', function (Builder $query): void {
|
||||
$minStock = [
|
||||
RawMaterialUnit::YARD->value => 20,
|
||||
RawMaterialUnit::METER->value => 10,
|
||||
RawMaterialUnit::KILOGRAM->value => 5,
|
||||
];
|
||||
|
||||
$query->whereHas('prices', function (Builder $priceQuery) use ($minStock): void {
|
||||
$priceQuery->where('stock', '>', 0)->where(function (Builder $priceQuery) use ($minStock): void {
|
||||
foreach (RawMaterialUnit::cases() as $unit) {
|
||||
$priceQuery->orWhere(function (Builder $priceQuery) use ($unit, $minStock): void {
|
||||
$priceQuery->whereHas('rawMaterial', fn (Builder $rawMaterialQuery) => $rawMaterialQuery->where('unit', $unit->value))
|
||||
->where('stock', '<', $minStock[$unit->value]);
|
||||
});
|
||||
}
|
||||
});
|
||||
$query->where(function (Builder $query): void {
|
||||
$query->where('unit', RawMaterialUnit::YARD->value)
|
||||
->whereHas('prices', fn (Builder $q) => $q->where('stock', '>', 0)->where('stock', '<', 20));
|
||||
})->orWhere(function (Builder $query): void {
|
||||
$query->where('unit', RawMaterialUnit::METER->value)
|
||||
->whereHas('prices', fn (Builder $q) => $q->where('stock', '>', 0)->where('stock', '<', 10));
|
||||
})->orWhere(function (Builder $query): void {
|
||||
$query->where('unit', RawMaterialUnit::KILOGRAM->value)
|
||||
->whereHas('prices', fn (Builder $q) => $q->where('stock', '>', 0)->where('stock', '<', 5));
|
||||
});
|
||||
});
|
||||
|
||||
@ -274,9 +286,6 @@ private function applyDeleteSubject(RawMaterial $rawMaterial): void
|
||||
{
|
||||
$this->runInTransaction(
|
||||
function () use ($rawMaterial): void {
|
||||
$rawMaterial->prices()->each(function (RawMaterialPrice $price): void {
|
||||
$price->clearMediaCollection('images');
|
||||
});
|
||||
$rawMaterial->prices()->delete();
|
||||
$rawMaterial->delete();
|
||||
},
|
||||
@ -328,7 +337,6 @@ private function applyPayloadToRawMaterial(
|
||||
->whereNotIn('id', $submittedPriceIds)
|
||||
->get()
|
||||
->each(function (RawMaterialPrice $price): void {
|
||||
$price->clearMediaCollection('images');
|
||||
$price->delete();
|
||||
});
|
||||
|
||||
@ -374,9 +382,6 @@ private function rejectCreate(OwnerVerificationRequest $verificationRequest): vo
|
||||
|
||||
$this->runInTransaction(
|
||||
function () use ($rawMaterial): void {
|
||||
$rawMaterial->prices()->each(function (RawMaterialPrice $price): void {
|
||||
$price->clearMediaCollection('images');
|
||||
});
|
||||
$rawMaterial->prices()->delete();
|
||||
$rawMaterial->delete();
|
||||
},
|
||||
|
||||
File diff suppressed because it is too large
Load Diff
@ -6,7 +6,6 @@
|
||||
use App\Models\Category;
|
||||
use App\Models\Product;
|
||||
use App\Models\SystemConfiguration;
|
||||
use App\Services\Concerns\CachesQuery;
|
||||
use App\Services\Manage\CuttingResultPriceResolver;
|
||||
use App\Services\System\Setting\HomepageSettingService;
|
||||
use App\Settings\SocialMediaSettings;
|
||||
@ -15,8 +14,6 @@
|
||||
|
||||
class HomepageService
|
||||
{
|
||||
use CachesQuery;
|
||||
|
||||
public function __construct(
|
||||
private readonly CuttingResultPriceResolver $cuttingResultPriceResolver,
|
||||
private readonly HomepageSettingService $homepageSettingService,
|
||||
@ -24,32 +21,30 @@ public function __construct(
|
||||
|
||||
public function pageData(): array
|
||||
{
|
||||
return $this->cacheRemember('homepage:page_data', 900, function () {
|
||||
$categories = Category::getActiveWithProducts();
|
||||
$products = $this->getProducts();
|
||||
$categories = Category::getActiveWithProducts();
|
||||
$products = $this->getProducts();
|
||||
|
||||
$configuration = SystemConfiguration::instance();
|
||||
$logo = MediaPresenter::first($configuration, 'logo');
|
||||
$logoUrl = $logo['url'] ?? null;
|
||||
$configuration = SystemConfiguration::instance();
|
||||
$logo = MediaPresenter::first($configuration, 'logo');
|
||||
$logoUrl = $logo['url'] ?? null;
|
||||
|
||||
$settings = app(SystemSettings::class);
|
||||
$socialSettings = app(SocialMediaSettings::class);
|
||||
$settings = app(SystemSettings::class);
|
||||
$socialSettings = app(SocialMediaSettings::class);
|
||||
|
||||
return [
|
||||
'categories' => $categories,
|
||||
'products' => $products,
|
||||
'appName' => $settings->app_name ?? 'DST Collection',
|
||||
'aboutApp' => $settings->about_app ?? '',
|
||||
'contactEmail' => $settings->email ?? '',
|
||||
'contactPhone' => $settings->phone ?? '',
|
||||
'contactAddress' => $settings->address ?? '',
|
||||
'logoUrl' => $logoUrl,
|
||||
'instagramUrl' => $socialSettings->instagram_url ?? null,
|
||||
'facebookUrl' => $socialSettings->facebook_url ?? null,
|
||||
'tiktokUrl' => $socialSettings->tiktok_url ?? null,
|
||||
'homepage' => $this->homepageSettingService->homepageData(),
|
||||
];
|
||||
});
|
||||
return [
|
||||
'categories' => $categories,
|
||||
'products' => $products,
|
||||
'appName' => $settings->app_name ?? 'DST Collection',
|
||||
'aboutApp' => $settings->about_app ?? '',
|
||||
'contactEmail' => $settings->email ?? '',
|
||||
'contactPhone' => $settings->phone ?? '',
|
||||
'contactAddress' => $settings->address ?? '',
|
||||
'logoUrl' => $logoUrl,
|
||||
'instagramUrl' => $socialSettings->instagram_url ?? null,
|
||||
'facebookUrl' => $socialSettings->facebook_url ?? null,
|
||||
'tiktokUrl' => $socialSettings->tiktok_url ?? null,
|
||||
'homepage' => $this->homepageSettingService->homepageData(),
|
||||
];
|
||||
}
|
||||
|
||||
private function getProducts(): array
|
||||
|
||||
@ -87,6 +87,8 @@ public function create(array $validated): void
|
||||
]);
|
||||
}
|
||||
|
||||
$this->cacheForget('system:permissions');
|
||||
$this->cacheForget('system:assignable_roles');
|
||||
$this->cacheForgetByPattern('system:roles:*');
|
||||
}
|
||||
|
||||
@ -114,6 +116,8 @@ public function update(Role $role, array $validated): void
|
||||
]);
|
||||
}
|
||||
|
||||
$this->cacheForget('system:permissions');
|
||||
$this->cacheForget('system:assignable_roles');
|
||||
$this->cacheForgetByPattern('system:roles:*');
|
||||
}
|
||||
|
||||
@ -121,6 +125,8 @@ public function delete(Role $role): void
|
||||
{
|
||||
$role->delete();
|
||||
|
||||
$this->cacheForget('system:permissions');
|
||||
$this->cacheForget('system:assignable_roles');
|
||||
$this->cacheForgetByPattern('system:roles:*');
|
||||
}
|
||||
|
||||
|
||||
@ -16,7 +16,7 @@
|
||||
*/
|
||||
|
||||
'ssr' => [
|
||||
'enabled' => true,
|
||||
'enabled' => false,
|
||||
'url' => 'http://127.0.0.1:13714',
|
||||
// 'bundle' => base_path('bootstrap/ssr/ssr.mjs'),
|
||||
|
||||
|
||||
@ -5,24 +5,26 @@ import { Toaster } from '@/components/ui/sonner';
|
||||
import { useFlashToast } from '@/composables/useFlashToast';
|
||||
import { restoreConnection } from '@/lib/thermal-printer/stable-transport';
|
||||
|
||||
if ('serviceWorker' in navigator) {
|
||||
navigator.serviceWorker
|
||||
.register('/sw.js', { scope: '/' })
|
||||
.then((reg) => {
|
||||
console.log('[SW] Registered:', reg.scope);
|
||||
})
|
||||
.catch((err) => {
|
||||
console.error('[SW] Registration failed:', err);
|
||||
});
|
||||
if (typeof window !== 'undefined') {
|
||||
if ('serviceWorker' in navigator) {
|
||||
navigator.serviceWorker
|
||||
.register('/sw.js', { scope: '/' })
|
||||
.then((reg) => {
|
||||
console.log('[SW] Registered:', reg.scope);
|
||||
})
|
||||
.catch((err) => {
|
||||
console.error('[SW] Registration failed:', err);
|
||||
});
|
||||
}
|
||||
|
||||
window.addEventListener('beforeinstallprompt', (e) => {
|
||||
e.preventDefault();
|
||||
(window as any).deferredPwaPrompt = e;
|
||||
});
|
||||
|
||||
void restoreConnection();
|
||||
}
|
||||
|
||||
window.addEventListener('beforeinstallprompt', (e) => {
|
||||
e.preventDefault();
|
||||
(window as any).deferredPwaPrompt = e;
|
||||
});
|
||||
|
||||
void restoreConnection();
|
||||
|
||||
const appName = import.meta.env.VITE_APP_NAME || 'Laravel';
|
||||
|
||||
createInertiaApp({
|
||||
|
||||
@ -529,11 +529,11 @@ const productBarData = computed<ProductData[]>(() => {
|
||||
|
||||
function applyFilters() {
|
||||
router.get(
|
||||
admin.analysis.url({
|
||||
admin.analysis.url(),
|
||||
{
|
||||
start_date: startDate.value,
|
||||
end_date: endDate.value,
|
||||
}),
|
||||
{},
|
||||
},
|
||||
{
|
||||
preserveState: true,
|
||||
preserveScroll: true,
|
||||
|
||||
Loading…
Reference in New Issue
Block a user