84 Commits

Author SHA1 Message Date
dd6cbd92a2 Merge pull request 'Added pdf generate method for sticker validation' (#85) from ranjith-dev into master
All checks were successful
Scan for leaked secrets using Kingfisher / kingfisher-secrets-scan (push) Successful in 11s
Reviewed-on: #85
2025-12-30 09:19:24 +00:00
b54a9af78b Merge pull request 'Added sticker validation livewire pages' (#84) from ranjith-dev into master
All checks were successful
Scan for leaked secrets using Kingfisher / kingfisher-secrets-scan (push) Successful in 11s
Reviewed-on: #84
2025-12-30 08:59:00 +00:00
57f059aca8 Merge pull request 'Added sticker validation blade file' (#83) from ranjith-dev into master
Some checks failed
Scan for leaked secrets using Kingfisher / kingfisher-secrets-scan (push) Has been cancelled
Reviewed-on: #83
2025-12-30 08:57:51 +00:00
5688e93862 Merge pull request 'Added Sticker Validation resource pages' (#82) from ranjith-dev into master
Some checks failed
Scan for leaked secrets using Kingfisher / kingfisher-secrets-scan (push) Has been cancelled
Reviewed-on: #82
2025-12-30 08:56:26 +00:00
8b556d3c9c Merge pull request 'Added Sticker Validation model file' (#81) from ranjith-dev into master
Some checks failed
Scan for leaked secrets using Kingfisher / kingfisher-secrets-scan (push) Has been cancelled
Reviewed-on: #81
2025-12-30 08:55:06 +00:00
091aaaa0d7 Merge pull request 'Added sticker validation migration file' (#80) from ranjith-dev into master
Some checks failed
Scan for leaked secrets using Kingfisher / kingfisher-secrets-scan (push) Has been cancelled
Reviewed-on: #80
2025-12-30 08:53:55 +00:00
9dd5d04b3c Merge pull request 'Added sticker mapping master importer and exporter' (#79) from ranjith-dev into master
All checks were successful
Scan for leaked secrets using Kingfisher / kingfisher-secrets-scan (push) Successful in 11s
Reviewed-on: #79
2025-12-30 08:46:59 +00:00
4ac3eb4f2f Merge pull request 'Added sticker mapping master resource pages' (#78) from ranjith-dev into master
Some checks failed
Scan for leaked secrets using Kingfisher / kingfisher-secrets-scan (push) Has been cancelled
Reviewed-on: #78
2025-12-30 08:40:35 +00:00
bcd493901c Merge pull request 'Added sticker mapping master model file' (#77) from ranjith-dev into master
Some checks failed
Scan for leaked secrets using Kingfisher / kingfisher-secrets-scan (push) Has been cancelled
Reviewed-on: #77
2025-12-30 08:39:11 +00:00
af3259a842 Merge pull request 'Added sticker mapping master migration file' (#76) from ranjith-dev into master
Some checks failed
Scan for leaked secrets using Kingfisher / kingfisher-secrets-scan (push) Has been cancelled
Reviewed-on: #76
2025-12-30 08:38:43 +00:00
6f41238b1e Merge pull request 'Added validation in importer and exporter of sticker structure details' (#75) from ranjith-dev into master
All checks were successful
Scan for leaked secrets using Kingfisher / kingfisher-secrets-scan (push) Successful in 10s
Reviewed-on: #75
2025-12-25 12:03:45 +00:00
8779e66a18 Merge pull request 'Added validation logic in sticker detail for importer and exporter' (#74) from ranjith-dev into master
All checks were successful
Scan for leaked secrets using Kingfisher / kingfisher-secrets-scan (push) Successful in 10s
Reviewed-on: #74
2025-12-25 12:01:11 +00:00
e0384780dc Merge pull request 'Remove dimage path and image type in sticker detail model file' (#73) from ranjith-dev into master
All checks were successful
Scan for leaked secrets using Kingfisher / kingfisher-secrets-scan (push) Successful in 10s
Reviewed-on: #73
2025-12-25 07:43:39 +00:00
afbbfe2aca Merge pull request 'Removed image path and image type in sticker detail resource' (#72) from ranjith-dev into master
Some checks failed
Scan for leaked secrets using Kingfisher / kingfisher-secrets-scan (push) Has been cancelled
Reviewed-on: #72
2025-12-25 07:42:34 +00:00
4fb04c9fa8 Merge pull request 'removed image type column from sticker details migration' (#71) from ranjith-dev into master
Some checks failed
Scan for leaked secrets using Kingfisher / kingfisher-secrets-scan (push) Has been cancelled
Reviewed-on: #71
2025-12-25 07:40:24 +00:00
656c58999c Merge pull request 'removed image path column in sticker details' (#70) from ranjith-dev into master
All checks were successful
Scan for leaked secrets using Kingfisher / kingfisher-secrets-scan (push) Successful in 11s
Reviewed-on: #70
2025-12-25 07:36:56 +00:00
102bc62805 Merge pull request 'Commented heading tag on preview' (#69) from ranjith-dev into master
All checks were successful
Scan for leaked secrets using Kingfisher / kingfisher-secrets-scan (push) Successful in 11s
Reviewed-on: #69
2025-12-23 12:23:14 +00:00
ef1ad62749 Merge pull request 'removed unwanted file in fields' (#68) from ranjith-dev into master
Some checks failed
Scan for leaked secrets using Kingfisher / kingfisher-secrets-scan (push) Has been cancelled
Reviewed-on: #68
2025-12-23 12:22:21 +00:00
1e0193e6c9 Merge pull request 'Added item and plant models' (#67) from ranjith-dev into master
Some checks failed
Scan for leaked secrets using Kingfisher / kingfisher-secrets-scan (push) Has been cancelled
Reviewed-on: #67
2025-12-23 12:19:20 +00:00
18c203552c Merge pull request 'Commented Blade File' (#66) from ranjith-dev into master
Some checks failed
Scan for leaked secrets using Kingfisher / kingfisher-secrets-scan (push) Has been cancelled
Reviewed-on: #66
2025-12-23 12:18:05 +00:00
61190edcce Merge pull request 'changed logic in sticker preview' (#65) from ranjith-dev into master
Some checks failed
Scan for leaked secrets using Kingfisher / kingfisher-secrets-scan (push) Has been cancelled
Reviewed-on: #65
2025-12-23 12:17:23 +00:00
62774aec0f Merge pull request 'changed logic in sticker pdf service' (#64) from ranjith-dev into master
Some checks failed
Scan for leaked secrets using Kingfisher / kingfisher-secrets-scan (push) Has been cancelled
Reviewed-on: #64
2025-12-23 12:16:15 +00:00
44e58d2d78 Merge pull request 'Added show preview method in sticker pdf service' (#63) from ranjith-dev into master
All checks were successful
Scan for leaked secrets using Kingfisher / kingfisher-secrets-scan (push) Successful in 14s
Reviewed-on: #63
2025-12-23 12:04:02 +00:00
3ac4f88155 Merge pull request 'Added sticker structure preview page blade file' (#62) from ranjith-dev into master
Some checks failed
Scan for leaked secrets using Kingfisher / kingfisher-secrets-scan (push) Has been cancelled
Reviewed-on: #62
2025-12-23 12:00:01 +00:00
818f8a3e08 Merge pull request 'Added Sticker Preview page custom filament page' (#61) from ranjith-dev into master
Some checks failed
Scan for leaked secrets using Kingfisher / kingfisher-secrets-scan (push) Has been cancelled
Reviewed-on: #61
2025-12-23 11:58:45 +00:00
86798212d0 Merge pull request 'Removed sticker mapping master resource files' (#60) from ranjith-dev into master
All checks were successful
Scan for leaked secrets using Kingfisher / kingfisher-secrets-scan (push) Successful in 12s
Reviewed-on: #60
2025-12-23 11:25:53 +00:00
837bd58177 Merge pull request 'Removed model file of sticker mapping master' (#59) from ranjith-dev into master
Some checks failed
Scan for leaked secrets using Kingfisher / kingfisher-secrets-scan (push) Has been cancelled
Reviewed-on: #59
2025-12-23 11:23:13 +00:00
d8b29ba000 Merge pull request 'removed sticker mapping migration file' (#58) from ranjith-dev into master
Some checks failed
Scan for leaked secrets using Kingfisher / kingfisher-secrets-scan (push) Has been cancelled
Reviewed-on: #58
2025-12-23 11:21:54 +00:00
d1db3e0dad Merge pull request 'added null for design element type in resource page' (#57) from ranjith-dev into master
All checks were successful
Scan for leaked secrets using Kingfisher / kingfisher-secrets-scan (push) Successful in 11s
Reviewed-on: #57
2025-12-23 10:57:01 +00:00
f274de00e1 Merge pull request 'added visible to all text boxes based on design element type' (#56) from ranjith-dev into master
All checks were successful
Scan for leaked secrets using Kingfisher / kingfisher-secrets-scan (push) Successful in 10s
Reviewed-on: #56
2025-12-23 10:51:15 +00:00
f9c6405b61 Merge pull request 'Added curved rectangle in sticker pdf service' (#55) from ranjith-dev into master
All checks were successful
Scan for leaked secrets using Kingfisher / kingfisher-secrets-scan (push) Successful in 13s
Reviewed-on: #55
2025-12-23 09:54:48 +00:00
7ec34a04fc Merge pull request 'Added curve radius in sticker details resource pages' (#54) from ranjith-dev into master
Some checks failed
Scan for leaked secrets using Kingfisher / kingfisher-secrets-scan (push) Has been cancelled
Reviewed-on: #54
2025-12-23 09:53:19 +00:00
9256e1ed12 Merge pull request 'added curve radius in model file of sticker details' (#53) from ranjith-dev into master
Some checks failed
Scan for leaked secrets using Kingfisher / kingfisher-secrets-scan (push) Has been cancelled
Reviewed-on: #53
2025-12-23 09:52:27 +00:00
b334ba60fa Merge pull request 'Added curve radius column in sticker details' (#52) from ranjith-dev into master
All checks were successful
Scan for leaked secrets using Kingfisher / kingfisher-secrets-scan (push) Successful in 11s
Reviewed-on: #52
2025-12-23 09:48:11 +00:00
8c81c140d1 Merge pull request 'Added logic in pdf controller' (#51) from ranjith-dev into master
All checks were successful
Scan for leaked secrets using Kingfisher / kingfisher-secrets-scan (push) Successful in 11s
Reviewed-on: #51
2025-12-23 06:19:16 +00:00
5ff8acac74 Merge pull request 'Modified logic in generate template' (#50) from ranjith-dev into master
All checks were successful
Scan for leaked secrets using Kingfisher / kingfisher-secrets-scan (push) Successful in 11s
Reviewed-on: #50
2025-12-23 05:56:29 +00:00
2f2bab37d4 Merge pull request 'Added plant and item characteritivcs id in resource page' (#49) from ranjith-dev into master
Some checks failed
Scan for leaked secrets using Kingfisher / kingfisher-secrets-scan (push) Has been cancelled
Reviewed-on: #49
2025-12-23 05:51:19 +00:00
a8d72923ae Merge pull request 'ranjith-dev' (#48) from ranjith-dev into master
Some checks failed
Scan for leaked secrets using Kingfisher / kingfisher-secrets-scan (push) Has been cancelled
Reviewed-on: #48
2025-12-23 05:50:34 +00:00
e39ab23142 Merge pull request 'Added dynamic logic in pdf controller' (#47) from ranjith-dev into master
Some checks failed
Scan for leaked secrets using Kingfisher / kingfisher-secrets-scan (push) Has been cancelled
Reviewed-on: #47
2025-12-23 05:44:55 +00:00
2373e1d427 Merge pull request 'Added Sticker pdf service logic for dynamic values' (#46) from ranjith-dev into master
Some checks failed
Scan for leaked secrets using Kingfisher / kingfisher-secrets-scan (push) Has been cancelled
Reviewed-on: #46
2025-12-23 05:44:01 +00:00
baa165e285 Merge pull request 'Added route file in web.php' (#45) from ranjith-dev into master
Some checks failed
Scan for leaked secrets using Kingfisher / kingfisher-secrets-scan (push) Has been cancelled
Reviewed-on: #45
2025-12-23 05:42:43 +00:00
53e671d612 Merge pull request 'Added characteritics type in resource page' (#44) from ranjith-dev into master
Some checks failed
Scan for leaked secrets using Kingfisher / kingfisher-secrets-scan (push) Has been cancelled
Reviewed-on: #44
2025-12-23 05:41:34 +00:00
58be303cfe Merge pull request 'Added characteristics type in model file' (#43) from ranjith-dev into master
Some checks failed
Scan for leaked secrets using Kingfisher / kingfisher-secrets-scan (push) Has been cancelled
Reviewed-on: #43
2025-12-23 05:40:18 +00:00
a1c39c5f0e Merge pull request 'Added characteritics type column in sticker detail' (#42) from ranjith-dev into master
Some checks failed
Scan for leaked secrets using Kingfisher / kingfisher-secrets-scan (push) Has been cancelled
Reviewed-on: #42
2025-12-23 05:39:12 +00:00
41e8c04b9d Merge pull request 'hidden the sticker_id_live form in resource' (#41) from ranjith-dev into master
All checks were successful
Scan for leaked secrets using Kingfisher / kingfisher-secrets-scan (push) Successful in 12s
Reviewed-on: #41
2025-12-22 12:28:02 +00:00
6a30fbc8f2 Merge pull request 'Added logic for validation in generate temp' (#40) from ranjith-dev into master
Some checks failed
Scan for leaked secrets using Kingfisher / kingfisher-secrets-scan (push) Has been cancelled
Reviewed-on: #40
2025-12-22 12:26:51 +00:00
9e57461d3a Merge pull request 'Added validation part for generate pdf' (#39) from ranjith-dev into master
Some checks failed
Scan for leaked secrets using Kingfisher / kingfisher-secrets-scan (push) Has been cancelled
Reviewed-on: #39
2025-12-22 12:19:39 +00:00
ab5a6b94c9 Merge pull request 'Added string value in forms and tables' (#38) from ranjith-dev into master
Some checks failed
Scan for leaked secrets using Kingfisher / kingfisher-secrets-scan (push) Has been cancelled
Reviewed-on: #38
2025-12-22 12:09:51 +00:00
84b78ea0c1 Merge pull request 'changed logic in sticker pdf service' (#37) from ranjith-dev into master
Some checks failed
Scan for leaked secrets using Kingfisher / kingfisher-secrets-scan (push) Has been cancelled
Reviewed-on: #37
2025-12-22 12:08:43 +00:00
5e46b080c5 Merge pull request 'Added sticker pdf service file' (#36) from ranjith-dev into master
Some checks failed
Scan for leaked secrets using Kingfisher / kingfisher-secrets-scan (push) Has been cancelled
Reviewed-on: #36
2025-12-22 11:57:49 +00:00
17f337e8db Merge pull request 'Added sticker generate route in web file' (#35) from ranjith-dev into master
Some checks failed
Scan for leaked secrets using Kingfisher / kingfisher-secrets-scan (push) Has been cancelled
Reviewed-on: #35
2025-12-22 11:53:40 +00:00
2781d57e3f Merge pull request 'Added generate method in pdf controller' (#34) from ranjith-dev into master
Some checks failed
Scan for leaked secrets using Kingfisher / kingfisher-secrets-scan (push) Has been cancelled
Reviewed-on: #34
2025-12-22 11:52:32 +00:00
5628e8abd4 Merge pull request 'Added generate pdf blade file' (#33) from ranjith-dev into master
Some checks failed
Scan for leaked secrets using Kingfisher / kingfisher-secrets-scan (push) Has been cancelled
Reviewed-on: #33
2025-12-22 11:51:41 +00:00
e56733ce44 Merge pull request 'Added item characteristics policy file' (#32) from ranjith-dev into master
Some checks failed
Scan for leaked secrets using Kingfisher / kingfisher-secrets-scan (push) Has been cancelled
Reviewed-on: #32
2025-12-22 11:49:18 +00:00
b3f32f6813 Merge pull request 'Added item characteristics resource files' (#31) from ranjith-dev into master
Some checks failed
Scan for leaked secrets using Kingfisher / kingfisher-secrets-scan (push) Has been cancelled
Reviewed-on: #31
2025-12-22 11:47:17 +00:00
b2937ccfa8 Merge pull request 'Added item characteristics model file' (#30) from ranjith-dev into master
Some checks failed
Scan for leaked secrets using Kingfisher / kingfisher-secrets-scan (push) Has been cancelled
Reviewed-on: #30
2025-12-22 11:46:06 +00:00
026e4982b8 Merge pull request 'Added item characteristics migration file' (#29) from ranjith-dev into master
Some checks failed
Scan for leaked secrets using Kingfisher / kingfisher-secrets-scan (push) Has been cancelled
Reviewed-on: #29
2025-12-22 11:45:27 +00:00
6478bc3722 Merge pull request 'Added sticker detail policy file' (#28) from ranjith-dev into master
Some checks failed
Scan for leaked secrets using Kingfisher / kingfisher-secrets-scan (push) Has been cancelled
Reviewed-on: #28
2025-12-22 11:43:41 +00:00
1ab7ed2da9 Merge pull request 'Added sticker deatil importer and exporter' (#27) from ranjith-dev into master
Some checks failed
Scan for leaked secrets using Kingfisher / kingfisher-secrets-scan (push) Has been cancelled
Reviewed-on: #27
2025-12-22 11:41:57 +00:00
9ecd04f0e3 Merge pull request 'Added sticker detail resource page' (#26) from ranjith-dev into master
Some checks failed
Scan for leaked secrets using Kingfisher / kingfisher-secrets-scan (push) Has been cancelled
Reviewed-on: #26
2025-12-22 11:41:04 +00:00
53179ea538 Merge pull request 'Added sticker detail model file' (#25) from ranjith-dev into master
Some checks failed
Scan for leaked secrets using Kingfisher / kingfisher-secrets-scan (push) Has been cancelled
Reviewed-on: #25
2025-12-22 11:39:46 +00:00
b4e24c581e Merge pull request 'Added sticker details migration file' (#24) from ranjith-dev into master
Some checks failed
Scan for leaked secrets using Kingfisher / kingfisher-secrets-scan (push) Has been cancelled
Reviewed-on: #24
2025-12-22 11:38:28 +00:00
4938fa62a7 Merge pull request 'Added sticker structure policy file' (#23) from ranjith-dev into master
Some checks failed
Scan for leaked secrets using Kingfisher / kingfisher-secrets-scan (push) Has been cancelled
Reviewed-on: #23
2025-12-22 11:34:44 +00:00
01f6288c63 Merge pull request 'Added importer and exporter of sticker structure detail' (#22) from ranjith-dev into master
Some checks failed
Scan for leaked secrets using Kingfisher / kingfisher-secrets-scan (push) Has been cancelled
Reviewed-on: #22
2025-12-22 11:33:09 +00:00
c9c7c38088 Merge pull request 'Added sticker structure detail resource pages' (#21) from ranjith-dev into master
Some checks failed
Scan for leaked secrets using Kingfisher / kingfisher-secrets-scan (push) Has been cancelled
Reviewed-on: #21
2025-12-22 11:32:08 +00:00
90cfe9ef0d Merge pull request 'Added sticker structure detail model file' (#20) from ranjith-dev into master
Some checks failed
Scan for leaked secrets using Kingfisher / kingfisher-secrets-scan (push) Has been cancelled
Reviewed-on: #20
2025-12-22 11:30:56 +00:00
aa806f2fe3 Merge pull request 'Added sticker structure detail migration file' (#19) from ranjith-dev into master
Some checks failed
Scan for leaked secrets using Kingfisher / kingfisher-secrets-scan (push) Has been cancelled
Reviewed-on: #19
2025-12-22 11:30:11 +00:00
0eb6f76ca6 Merge pull request 'Enhance Gemini review step to handle errors and provide feedback on review status' (#18) from ranjith-dev into master
All checks were successful
Scan for leaked secrets using Kingfisher / kingfisher-secrets-scan (push) Successful in 10s
Reviewed-on: #18
2025-12-18 06:34:16 +00:00
73366ccd70 Merge pull request 'Update Gemini review step to use gemini-pro model for code analysis' (#17) from ranjith-dev into master
Some checks failed
Scan for leaked secrets using Kingfisher / kingfisher-secrets-scan (push) Has been cancelled
Reviewed-on: #17
2025-12-18 06:31:07 +00:00
acbecedce9 Merge pull request 'Update Gemini review step to use gemini-1.5-flash model for code analysis' (#16) from ranjith-dev into master
Some checks failed
Scan for leaked secrets using Kingfisher / kingfisher-secrets-scan (push) Has been cancelled
Reviewed-on: #16
2025-12-18 06:28:15 +00:00
614d89932b Merge pull request 'Update Gemini review step to use GPT-5-mini model for code analysis' (#15) from ranjith-dev into master
Some checks failed
Scan for leaked secrets using Kingfisher / kingfisher-secrets-scan (push) Has been cancelled
Reviewed-on: #15
2025-12-18 06:26:56 +00:00
c839c6fdbc Merge pull request 'Remove unnecessary blank line in Gemini PR Review workflow' (#14) from ranjith-dev into master
All checks were successful
Scan for leaked secrets using Kingfisher / kingfisher-secrets-scan (push) Successful in 11s
Reviewed-on: #14
2025-12-18 05:16:54 +00:00
d9445a9d4b Merge pull request 'Refactor Gemini PR Review workflow' (#13) from ranjith-dev into master
All checks were successful
Scan for leaked secrets using Kingfisher / kingfisher-secrets-scan (push) Successful in 10s
Reviewed-on: #13
2025-12-18 04:48:44 +00:00
50476c8a2c Merge pull request 'Added nav group name in ocr validation resource page' (#12) from ranjith-dev into master
All checks were successful
Scan for leaked secrets using Kingfisher / kingfisher-secrets-scan (push) Successful in 10s
Reviewed-on: #12
2025-12-17 06:22:14 +00:00
c57cfe71ca Merge pull request 'Added nav group for web capture page' (#11) from ranjith-dev into master
Some checks failed
Scan for leaked secrets using Kingfisher / kingfisher-secrets-scan (push) Has been cancelled
Reviewed-on: #11
2025-12-17 06:21:40 +00:00
96c08c34c1 Merge pull request 'Added nav group in reject reason resource page' (#10) from ranjith-dev into master
Some checks failed
Scan for leaked secrets using Kingfisher / kingfisher-secrets-scan (push) Has been cancelled
Reviewed-on: #10
2025-12-17 06:20:01 +00:00
19cf7c8edd Merge pull request 'Added nav group for production reject reason resource page' (#9) from ranjith-dev into master
Some checks failed
Scan for leaked secrets using Kingfisher / kingfisher-secrets-scan (push) Has been cancelled
Reviewed-on: #9
2025-12-17 06:19:03 +00:00
66086dd2d7 Merge pull request 'Added nav group in product characteristics resource page' (#8) from ranjith-dev into master
Some checks failed
Scan for leaked secrets using Kingfisher / kingfisher-secrets-scan (push) Has been cancelled
Reviewed-on: #8
2025-12-17 06:16:38 +00:00
5da724c9a4 Merge pull request 'Added nav group in gr master resource page' (#7) from ranjith-dev into master
Some checks failed
Scan for leaked secrets using Kingfisher / kingfisher-secrets-scan (push) Has been cancelled
Reviewed-on: #7
2025-12-17 06:15:52 +00:00
6b723c0929 Merge pull request 'Added navigation sort for sticker mapping resource page' (#6) from ranjith-dev into master
Some checks failed
Scan for leaked secrets using Kingfisher / kingfisher-secrets-scan (push) Has been cancelled
Reviewed-on: #6
2025-12-17 06:13:44 +00:00
8e20d0732d Merge pull request 'Added nav group for sticker printing resource page' (#5) from ranjith-dev into master
Some checks failed
Scan for leaked secrets using Kingfisher / kingfisher-secrets-scan (push) Has been cancelled
Reviewed-on: #5
2025-12-17 06:11:56 +00:00
1d8fb1c9aa Merge pull request 'Added nav group for sticker master mapping resource' (#4) from ranjith-dev into master
Some checks failed
Scan for leaked secrets using Kingfisher / kingfisher-secrets-scan (push) Has been cancelled
Reviewed-on: #4
2025-12-17 06:11:07 +00:00
33bbce47ba Merge pull request 'Added navigation group for class characteristics' (#3) from ranjith-dev into master
Some checks failed
Scan for leaked secrets using Kingfisher / kingfisher-secrets-scan (push) Has been cancelled
Reviewed-on: #3
2025-12-17 06:08:01 +00:00
860ff96134 Merge pull request 'Added driver master migration file' (#2) from fix-migration into master
All checks were successful
Scan for leaked secrets using Kingfisher / kingfisher-secrets-scan (push) Successful in 10s
Reviewed-on: #2
2025-12-17 03:52:20 +00:00
76 changed files with 2035 additions and 6839 deletions

View File

@@ -1,62 +0,0 @@
<?php
namespace App\Exports;
use Maatwebsite\Excel\Concerns\FromCollection;
use Maatwebsite\Excel\Concerns\FromArray;
use Maatwebsite\Excel\Concerns\WithHeadings;
use Maatwebsite\Excel\Concerns\WithMapping;
class ProductionPlanExport implements FromArray, WithHeadings, WithMapping
{
protected array $data;
protected array $dates;
public function __construct(array $data, array $dates)
{
$this->data = $data;
$this->dates = $dates;
}
public function array(): array
{
return $this->data;
}
public function headings(): array
{
$headings = [
'Plant Name',
'Line Name',
'Item Code',
];
// Add dynamic headings for each date: Target / Produced
foreach ($this->dates as $date) {
$headings[] = $date . ' - Target Plan';
$headings[] = $date . ' - Produced Quantity';
}
return $headings;
}
public function map($row): array
{
$mapped = [
$row['plant_name'] ?? '',
$row['line_name'] ?? '',
$row['item_code'] ?? '',
];
// Add daily target and produced quantity for each date
foreach ($this->dates as $date) {
// $mapped[] = $row['daily_target_dynamic'] ?? 0;
$mapped[] = $row['daily_target_dynamic'][$date] ?? '-';
$mapped[] = $row['produced_quantity'][$date] ?? 0;
}
return $mapped;
}
}

View File

@@ -3,7 +3,6 @@
namespace App\Filament\Imports;
use App\Models\Block;
use App\Models\Item;
use App\Models\Line;
use App\Models\Plant;
use App\Models\ProductionPlan;
@@ -24,33 +23,11 @@ class ProductionPlanImporter extends Importer
public static function getColumns(): array
{
return [
// ImportColumn::make('created_at')
// ->requiredMapping()
// ->exampleHeader('Created DateTime')
// ->example(['01-01-2025 08:00:00', '01-01-2025 19:30:00'])
// ->label('Created DateTime')
// ->rules(['required']),
ImportColumn::make('plant')
ImportColumn::make('created_at')
->requiredMapping()
->exampleHeader('Plant Code')
->example(['1000', '1000'])
->label('Plant Code')
->relationship(resolveUsing: 'code')
->rules(['required']),
ImportColumn::make('line')
->requiredMapping()
->exampleHeader('Line Name')
->example(['4 inch pump line', '4 inch pump line'])
->label('Line Name')
->relationship(resolveUsing: 'name')
->rules(['required']),
ImportColumn::make('item')
->requiredMapping()
->exampleHeader('Item Code')
->example(['123456', '210987'])
->label('Item Code')
->relationship(resolveUsing: 'code')
->exampleHeader('Created DateTime')
->example(['01-01-2025 08:00:00', '01-01-2025 19:30:00'])
->label('Created DateTime')
->rules(['required']),
ImportColumn::make('plan_quantity')
->requiredMapping()
@@ -59,111 +36,175 @@ class ProductionPlanImporter extends Importer
->label('Plan Quantity')
->numeric()
->rules(['required', 'integer']),
// ImportColumn::make('production_quantity')
// ->requiredMapping()
// ->exampleHeader('Production Quantity')
// ->example(['0', '0'])
// ->label('Production Quantity')
// ->numeric()
// ->rules(['required', 'integer']),
// ImportColumn::make('block_reference')
// ->requiredMapping() // Or optionalMapping() if not always present
// ->exampleHeader('Block Name')
// ->example(['Block A', 'Block A'])
// ->label('Block Name')
// ->rules(['required']), // Or remove if not required
// ImportColumn::make('shift')
// ->requiredMapping()
// ->exampleHeader('Shift Name') // ID
// ->example(['Day', 'Night']) // '2', '7'
// ->label('Shift Name') // ID
// ->relationship(resolveUsing: 'name')
// ->rules(['required']),
// ImportColumn::make('updated_at')
// ->requiredMapping()
// ->exampleHeader('Updated DateTime')
// ->example(['01-01-2025 08:00:00', '01-01-2025 19:30:00'])
// ->label('Updated DateTime')
// ->rules(['required']),
// ImportColumn::make('operator_id')
// ->requiredMapping()
// ->exampleHeader('Operator ID')
// ->example([Filament::auth()->user()->name, Filament::auth()->user()->name])
// ->label('Operator ID')
// ->rules(['required']),
ImportColumn::make('production_quantity')
->requiredMapping()
->exampleHeader('Production Quantity')
->example(['0', '0'])
->label('Production Quantity')
->numeric()
->rules(['required', 'integer']),
ImportColumn::make('line')
->requiredMapping()
->exampleHeader('Line Name')
->example(['4 inch pump line', '4 inch pump line'])
->label('Line Name')
->relationship(resolveUsing:'name')
->rules(['required']),
ImportColumn::make('block_reference')
->requiredMapping() // Or optionalMapping() if not always present
->exampleHeader('Block Name')
->example(['Block A', 'Block A'])
->label('Block Name')
->rules(['required']), // Or remove if not required
ImportColumn::make('shift')
->requiredMapping()
->exampleHeader('Shift Name') //ID
->example(['Day', 'Night']) //'2', '7'
->label('Shift Name') // ID
->relationship(resolveUsing: 'name')
->rules(['required']),
ImportColumn::make('plant')
->requiredMapping()
->exampleHeader('Plant Name')
->example(['Ransar Industries-I', 'Ransar Industries-I'])
->label('Plant Name')
->relationship(resolveUsing:'name')
->rules(['required']),
ImportColumn::make('updated_at')
->requiredMapping()
->exampleHeader('Updated DateTime')
->example(['01-01-2025 08:00:00', '01-01-2025 19:30:00'])
->label('Updated DateTime')
->rules(['required']),
ImportColumn::make('operator_id')
->requiredMapping()
->exampleHeader('Operator ID')
->example([Filament::auth()->user()->name, Filament::auth()->user()->name])
->label('Operator ID')
->rules(['required']),
];
}
public function resolveRecord(): ?ProductionPlan
{
$warnMsg = [];
$plantCod = $this->data['plant'];
$itemCod = $this->data['item'];
$plant = null;
$plant = Plant::where('name', $this->data['plant'])->first();
$line = null;
$block = null;
if (Str::length($plantCod) < 4 || ! is_numeric($plantCod) || ! preg_match('/^[1-9]\d{3,}$/', $plantCod)) {
$warnMsg[] = 'Invalid plant code found';
} else {
$plant = Plant::where('code', $plantCod)->first();
if (!$plant) {
$warnMsg[] = "Plant not found";
}
if (! $plant) {
$warnMsg[] = 'Plant not found';
} else {
else {
$line = Line::where('name', $this->data['line'])->where('plant_id', $plant->id)->first();
//block_reference
$block = Block::where('name', $this->data['block_reference'])->where('plant_id', $plant->id)->first();
}
if (!$line) {
$warnMsg[] = "Line not found";
}
$shift = null;
if (!$block) {
$warnMsg[] = "Block not found";
}
else {
$shift = Shift::where('name', $this->data['shift'])->where('plant_id', $plant->id)->where('block_id', $block->id)->first();
}
//$shift = Shift::where('id', $this->data['shift'])->where('plant_id', $plant->id)->first();
if (!$shift) {
$warnMsg[] = "Shift not found";
}
if (Str::length($this->data['plan_quantity']) < 0 || !is_numeric($this->data['plan_quantity']) || $this->data['plan_quantity'] <= 0) {
$warnMsg[] = "Invalid plan quantity found";
}
if (Str::length($this->data['production_quantity']) < 0 || !is_numeric($this->data['production_quantity']) || $this->data['production_quantity'] < 0) {
$warnMsg[] = "Invalid production quantity found";
}
if (! $line) {
$warnMsg[] = 'Line not found';
$fromDate = $this->data['created_at'];
$toDate = $this->data['updated_at'];
$formats = ['d-m-Y H:i', 'd-m-Y H:i:s']; //'07-05-2025 08:00' or '07-05-2025 08:00:00'
$fdateTime = null;
$tdateTime = null;
// Try parsing with multiple formats
foreach ($formats as $format) {
try {
$fdateTime = Carbon::createFromFormat($format, $fromDate);
break;
} catch (\Exception $e) {
// Optionally collect warning messages
// $warnMsg[] = "Date format mismatch with format: $format";
}
}
if (Str::length($itemCod) < 6 || ! is_numeric($itemCod)) {
$warnMsg[] = 'Invalid item code found';
} else {
$item = Item::where('code', $itemCod)->first();
foreach ($formats as $format) {
try {
$tdateTime = Carbon::createFromFormat($format, $toDate);
break;
} catch (\Exception $e) {
// Optionally collect warning messages
// $warnMsg[] = "Date format mismatch with format: $format";
}
}
if (! $item) {
$warnMsg[] = 'Item not found';
$fDateOnly = '';
if (!isset($fdateTime)) {
// throw new \Exception('Invalid date time format');
$warnMsg[] = "Invalid 'Created DateTime' format. Expected DD-MM-YYYY HH:MM:SS";
}
else {
$fDateOnly = $fdateTime->toDateString();
}
if (!isset($tdateTime)) {
$warnMsg[] = "Invalid 'Updated DateTime' format. Expected DD-MM-YYYY HH:MM:SS";
}
$plantId = $plant->id;
$itemAgaPlant = Item::where('plant_id', $plantId)->where('code', $itemCod)->first();
if(!$itemAgaPlant){
$warnMsg[] = 'Item not found against plant code';
if (isset($fdateTime) && isset($tdateTime)) {
if ($fdateTime->greaterThan($tdateTime)) {
$warnMsg[] = "'Created DataTime' is greater than 'Updated DateTime'.";
}
}
$user = Filament::auth()->user();
// if (!$fromDate) {
// $warnMsg[] = "Invalid 'Created DateTime' format. Expected DD-MM-YYYY HH:MM:SS";
// }
// else if (!$toDate) {
// $warnMsg[] = "Invalid 'Updated DateTime' format. Expected DD-MM-YYYY HH:MM:SS";
// }
$operatorName = $user->name;
if (Str::length($this->data['plan_quantity']) < 0 || ! is_numeric($this->data['plan_quantity']) || $this->data['plan_quantity'] <= 0) {
$warnMsg[] = 'Invalid plan quantity found';
$user = User::where('name', $this->data['operator_id'])->first();
if (!$user) {
$warnMsg[] = "Operator ID not found";
}
if (! empty($warnMsg)) {
if (!empty($warnMsg)) {
throw new RowImportFailedException(implode(', ', $warnMsg));
} else {
}
else { //if (empty($warnMsg))
$productionPlan = ProductionPlan::where('plant_id', $plant->id)
->where('line_id', $line->id)
->where('item_id', $itemAgaPlant->id)
->latest()
->first();
->where('shift_id', $shift->id)
->where('line_id', $line->id)
->whereDate('created_at', $fDateOnly)
// ->where('plan_quantity', $productionQuantity->plan_quantity)
->latest()
->first();
if ($productionPlan) {
// if($productionPlan->production_quantity)
// {
// throw new RowImportFailedException("{$productionPlan->created_at}, {$productionPlan->production_quantity}");
// }
// $warnMsg[] = "Production plan already exist on '{$fDateOnly}'!";
$productionPlan->update([
'plan_quantity' => $this->data['plan_quantity'],
'operator_id' => $operatorName,
// 'production_quantity' => $productionPlan->production_quantity,
// 'created_at' => $productionPlan->created_at,//$fdateTime->format('Y-m-d H:i:s'),
// 'updated_at' => $tdateTime->format('Y-m-d H:i:s'),
'operator_id' => $this->data['operator_id'],
]);
$productionPlan->save();
return null;
}
}
@@ -171,23 +212,28 @@ class ProductionPlanImporter extends Importer
ProductionPlan::updateOrCreate([
'plant_id' => $plant->id,
'line_id' => $line->id,
'item_id' => $itemAgaPlant->id,
// 'shift_id' => $shift->id,
'shift_id' => $shift->id,
'plan_quantity' => $this->data['plan_quantity'],
'created_at' =>now(),
'updated_at' => now(),
'operator_id' => $operatorName,
'production_quantity' => $this->data['production_quantity'],
'created_at' => $fdateTime->format('Y-m-d H:i:s'),//$this->data['created_at'],
'updated_at' => $tdateTime->format('Y-m-d H:i:s'),//$this->data['updated_at'],
'operator_id' => $this->data['operator_id'],
]);
return null;
// return ProductionPlan::firstOrNew([
// // Update existing records, matching them by `$this->data['column_name']`
// 'email' => $this->data['email'],
// ]);
// return new ProductionPlan();
}
public static function getCompletedNotificationBody(Import $import): string
{
$body = 'Your production plan import has completed and '.number_format($import->successful_rows).' '.str('row')->plural($import->successful_rows).' imported.';
$body = 'Your production plan import has completed and ' . number_format($import->successful_rows) . ' ' . str('row')->plural($import->successful_rows) . ' imported.';
if ($failedRowsCount = $import->getFailedRowsCount()) {
$body .= ' '.number_format($failedRowsCount).' '.str('row')->plural($failedRowsCount).' failed to import.';
$body .= ' ' . number_format($failedRowsCount) . ' ' . str('row')->plural($failedRowsCount) . ' failed to import.';
}
return $body;

View File

@@ -1,20 +0,0 @@
<?php
namespace App\Filament\Pages;
use Filament\Pages\Page;
class NotificationSettings extends Page
{
protected static ?string $navigationIcon = 'heroicon-o-document-text';
protected static string $view = 'filament.pages.notification-settings';
public static function getScripts(): array
{
return [
asset('js/push.js')
];
}
}

View File

@@ -1,163 +0,0 @@
<?php
namespace App\Filament\Pages;
use App\Models\CustomerPoMaster;
use App\Models\Plant;
use App\Models\ProductionPlan;
use App\Models\WireMasterPacking;
use Filament\Facades\Filament;
use Filament\Pages\Page;
use Filament\Forms\Concerns\InteractsWithForms;
use Filament\Forms\Form;
use Filament\Forms\Components\Section;
use Filament\Forms\Components\Select;
use Filament\Forms\Components\DatePicker;
use Filament\Forms\Components\Grid;
use Filament\Forms\Components\TextInput;
use Filament\Forms\Components\ViewField;
use Filament\Notifications\Notification;
use Filament\Forms\Components\Actions\Action;
use Filament\Forms\Components\Hidden;
class ProductionCalender extends Page
{
protected static ?string $navigationIcon = 'heroicon-o-document-text';
protected static string $view = 'filament.pages.production-calender';
use InteractsWithForms;
protected $listeners = ['setWorkingDays'];
public $pId;
public array $filters = [];
public function setWorkingDays($days = null)
{
$this->form->fill([
'working_days' => $days ?? 0,
]);
}
public function form(Form $form): Form
{
return $form
->statePath('filters')
->schema([
Section::make('')
->schema([
Select::make('plant_id')
->label('Plant')
->reactive()
//->options(Plant::pluck('name', 'id'))
->options(function (callable $get) {
$userHas = Filament::auth()->user()->plant_id;
return ($userHas && strlen($userHas) > 0) ? Plant::where('id', $userHas)->pluck('name', 'id')->toArray() : Plant::pluck('name', 'id')->toArray();
})
->columnSpan(['default' => 10, 'sm' => 7])
->required()
->afterStateUpdated(function ($state, callable $set, callable $get) {
$set('working_days', null);
}),
TextInput::make('working_days')
->label('No. of Working Days')
->numeric()
->readOnly()
->columnSpan(['default' => 10, 'sm' => 2])
->required()
->minValue(0)
->maxValue(31)
->placeholder('Enter working days')
->id('working_days'),
Hidden::make('month')
->label('Month')
->id('month'),
Hidden::make('year')
->label('Year')
->id('year'),
Hidden::make('selected_dates')
->label('Selected Dates')
->id('selected_dates'),
ViewField::make('save')
->view('forms.save')
->columnSpan(['default' => 10, 'sm' => 1]),
ViewField::make('calendar')
->view('forms.calendar')
->columnspan(10),
])
->columns(10)
]);
}
public function saveWorkingDays(){
$plantId = $this->filters['plant_id'] ?? null;
$workingDays = $this->filters['working_days'] ?? null;
$month = $this->filters['month'] ?? null;
$year = $this->filters['year'] ?? null;
$dates = $this->filters['selected_dates'] ?? null;
if (!$plantId) {
Notification::make()
->title('Unknown Plant')
->body("Please select a plant first!")
->danger()
->send();
return;
}
else if (!$workingDays) {
Notification::make()
->title('Unknown Working Days')
->body("Working days can't be empty!")
->danger()
->send();
return;
}
else if (!$month) {
Notification::make()
->title('Unknown Month')
->body("month can't be empty!")
->danger()
->send();
return;
}
else if (!$year) {
Notification::make()
->title('Unknown Year')
->body("Year can't be empty!")
->danger()
->send();
return;
}
$updated = ProductionPlan::where('plant_id', $plantId)
->whereMonth('created_at', $month)
->whereYear('created_at', $year)
->update([
'working_days' => $workingDays,
'leave_dates' => $dates,
'updated_at' => now(),
]);
if ($updated) {
Notification::make()
->title('Success')
->body("Working days updated successfully!")
->success()
->send();
} else {
Notification::make()
->title('No Records Updated')
->body("No production plans found for this plant and month.")
->warning()
->send();
}
}
}

File diff suppressed because it is too large Load Diff

View File

@@ -1,173 +0,0 @@
<?php
namespace App\Filament\Pages;
use App\Models\Plant;
use Filament\Facades\Filament;
use Filament\Forms\Components\DatePicker;
use Filament\Pages\Page;
use Filament\Forms\Form;
use Filament\Forms\Components\Section;
use Filament\Forms\Components\Select;
use Filament\Forms\Components\TextInput;
use Filament\Notifications\Notification;
class ProductionTarget extends Page
{
protected static ?string $navigationIcon = 'heroicon-o-document-text';
protected static string $view = 'filament.pages.production-target';
public array $filters = [];
public function form(Form $form): Form
{
return $form
->statePath('filters')
->schema([
Section::make('')
->schema([
Select::make('plant_id')
->label('Plant')
->reactive()
->options(function (callable $get) {
$userHas = Filament::auth()->user()->plant_id;
return ($userHas && strlen($userHas) > 0) ? Plant::where('id', $userHas)->pluck('name', 'id')->toArray() : Plant::pluck('name', 'id')->toArray();
})
->required()
->afterStateUpdated(function ($state, callable $get, $set) {
$set('line_id', null);
$set('year', null);
$set('month', null);
$this->dispatch('loadData',$state, '', '', '');
}),
Select::make('line_id')
->label('Line')
->required()
->columnSpan(1)
->options(function (callable $get) {
if (!$get('plant_id')) {
return [];
}
return \App\Models\Line::where('plant_id', $get('plant_id'))
->pluck('name', 'id')
->toArray();
})
->reactive()
->afterStateUpdated(function ($state, callable $get, $set) {
$plantId = $get('plant_id');
$set('year', null);
$set('month', null);
$this->dispatch('loadData',$plantId, $state, '', '');
}),
Select::make('year')
->label('Year')
->reactive()
->options([
'2026' => '2026',
'2027' => '2027',
'2028' => '2028',
'2029' => '2029',
'2030' => '2030',
'2031' => '2031',
'2032' => '2032',
'2033' => '2033',
'2034' => '2034',
'2035' => '2035',
'2036' => '2036',
'2037' => '2037',
'2038' => '2038',
'2039' => '2039',
'2040' => '2040',
])
->required()
->afterStateUpdated(function ($state, callable $get, $set) {
$set('month', null);
$plantId = $get('plant_id');
$lineId = $get('line_id');
$this->dispatch('loadData',$plantId, $lineId, $state, '');
}),
Select::make('month')
->label('Month')
->reactive()
->options([
'01' => 'January',
'02' => 'February',
'03' => 'March',
'04' => 'April',
'05' => 'May',
'06' => 'June',
'07' => 'July',
'08' => 'August',
'09' => 'September',
'10' => 'October',
'11' => 'November',
'12' => 'December',
])
->required()
->afterStateUpdated(function ($state, callable $get) {
$plantId = $get('plant_id');
$lineId = $get('line_id');
// $month = $get('month');
$year = $get('year');
$month = (int) $get('month');
if (!$month) {
return;
}
$this->dispatch('loadData', $plantId, $lineId, $month, $year);
}),
])
->columns(4)
]);
}
public function export(){
$plantId = $this->filters['plant_id'] ?? null;
$lineId = $this->filters['line_id'] ?? null;
$year = $this->filters['year'] ?? null;
$month = $this->filters['month'] ?? null;
if (! $plantId) {
Notification::make()
->title('Plant')
->body("please select plant to export data..!")
->danger()
->send();
return;
}
else if (! $lineId) {
Notification::make()
->title('Line')
->body("please select line to export data..!")
->danger()
->send();
return;
}
else if (! $year) {
Notification::make()
->title('Year')
->body("please select year to export data..!")
->danger()
->send();
return;
}
else if (! $month) {
Notification::make()
->title('Month')
->body("please select month to export data..!")
->danger()
->send();
return;
}
$this->dispatch('loadData1' ,$plantId, $lineId, $year, $month);
}
}

View File

@@ -1,163 +0,0 @@
<?php
namespace App\Filament\Pages;
use Filament\Pages\Page;
use Filament\Forms\Components\Select;
use Filament\Forms\Components\TextInput;
use Filament\Forms\Form;
use Filament\Pages\Dashboard\Concerns\HasFiltersForm;
use Filament\Tables\Filters\SelectFilter;
use Illuminate\Support\Facades\DB;
use App\Models\Plant;
use App\Models\RequestQuotation;
use App\Models\RfqTransporterBid;
use Filament\Facades\Filament;
use Filament\Widgets\Widget;
use Illuminate\Support\Facades\Auth;
use Filament\Forms\Components\Section;
use Filament\Forms;
use Filament\Forms\Concerns\InteractsWithForms;
use Filament\Forms\Contracts\HasForms;
class RfqDashboard extends Page
{
protected static ?string $navigationIcon = 'heroicon-o-document-text';
protected static string $view = 'filament.pages.rfq-dashboard';
protected static ?string $navigationGroup = 'RFQ Dashboard';
use HasFiltersForm;
public function mount(): void
{
session()->forget(['transport_name']);
session()->forget(['rfq_number']);
$this->filtersForm->fill([
'transport_name' => null,
'rfq_number' => null
]);
}
public function filtersForm(Form $form): Form
{
return $form
->statePath('filters')
->schema([
Section::make('')
->schema([
// Select::make('plant')
// ->label('Select Plant')
// ->reactive()
// ->options(function (callable $get) {
// $userHas = Filament::auth()->user()->plant_id;
// return ($userHas && strlen($userHas) > 0) ? Plant::where('id', $userHas)->pluck('name', 'id')->toArray() : Plant::pluck('name', 'id')->toArray();
// })
// ->afterStateUpdated(function ($state,callable $set) {
// session(['selected_plant' => $state]);
// // $set('rfq_number', null);
// session()->forget('rfq_number');
// }),
Select::make('rfq_number')
->label('Select RFQ Number')
->reactive()
->options(function (callable $get) {
return RequestQuotation::orderBy('rfq_number')
->pluck('rfq_number', 'id')
->toArray();
})
->afterStateUpdated(function ($state, callable $set) {
session(['rfq_id' => $state]);
$set('transport_name', null);
session()->forget('transport_name');
}),
Select::make('transport_name')
->label('User name')
->reactive()
->options(function (callable $get) {
$rfqId = $get('rfq_number');
if (!$rfqId) {
return [];
}
$user = Filament::auth()->user();
if ($user->hasRole(['Super Admin', 'Rfq Supervisor'])) {
return RfqTransporterBid::query()
->where('request_quotation_id', $rfqId)
->whereNotNull('transporter_name')
->distinct()
->pluck('transporter_name', 'transporter_name')
->toArray();
}
return RfqTransporterBid::query()
->where('request_quotation_id', $rfqId)
->where('transporter_name', $user->name)
->distinct()
->pluck('transporter_name', 'transporter_name')
->toArray();
})
->afterStateUpdated(function ($state, callable $set) {
session(['transport_name' => $state]);
}),
// Select::make('transport_name')
// ->label('User name')
// ->reactive()
// ->options(function () {
// $user = Filament::auth()->user();
// if ($user->hasRole(['Super Admin', 'Rfq Supervisor'])) {
// return RfqTransporterBid::query()
// ->whereNotNull('transporter_name')
// ->distinct()
// ->pluck('transporter_name', 'transporter_name')
// ->toArray();
// }
// return RfqTransporterBid::query()
// ->where('transporter_name', $user->name)
// ->distinct()
// ->pluck('transporter_name', 'transporter_name')
// ->toArray();
// })
// ->afterStateUpdated(function ($state, callable $set) {
// session(['transport_name' => $state]);
// $set('rfq_number', null);
// session()->forget('rfq_number');
// }),
// Select::make('rfq_number')
// ->label('Select RFQ Number')
// ->reactive()
// ->options(function (callable $get) {
// $transportName = $get('transport_name');
// if (!$transportName) {
// return [];
// }
// return RequestQuotation::where('transporter_name', $transportName)
// ->pluck('rfq_number', 'rfq_number')
// ->toArray();
// })
// ->afterStateUpdated(function ($state) {
// session(['rfq_number' => $state]);
// }),
])
->columns(2),
]);
}
public static function canAccess(): bool
{
return Auth::check() && Auth::user()->can('view rfq dashboard');
}
}

View File

@@ -1,58 +0,0 @@
<?php
namespace App\Filament\Pages;
use App\Models\RequestQuotation;
use Filament\Pages\Page;
use Filament\Forms\Components\Section;
use Filament\Forms\Components\Select;
use Filament\Forms\Form;
use Filament\Pages\Dashboard\Concerns\HasFiltersForm;
use Illuminate\Support\Facades\Auth;
class RfqOverview extends Page
{
protected static ?string $navigationIcon = 'heroicon-o-document-text';
protected static string $view = 'filament.pages.rfq-overview';
protected static ?string $navigationGroup = 'RFQ Dashboard';
use HasFiltersForm;
public function mount(): void
{
session()->forget(['rfq_id']);
$this->filtersForm->fill([
'rfq_id' => null
]);
}
public function filtersForm(Form $form): Form
{
return $form
->statePath('filters')
->schema([
Section::make('')
->schema([
Select::make('rfq_number')
->label('Select RFQ Number')
->reactive()
->options(function (callable $get) {
return RequestQuotation::orderBy('rfq_number')
->pluck('rfq_number', 'id')
->toArray();
})
->afterStateUpdated(function ($state, callable $set) {
session(['rfq_id' => $state]);
}),
])
->columns(1),
]);
}
public static function canAccess(): bool
{
return Auth::check() && Auth::user()->can('view rfq overview dashboard');
}
}

View File

@@ -1,17 +0,0 @@
<?php
namespace App\Filament\Pages;
use Filament\Pages\Page;
class Welcome extends Page
{
protected static ?string $navigationIcon = 'heroicon-o-document-text';
protected static string $view = 'filament.pages.welcome';
public function getHeading(): string
{
return '';
}
}

View File

@@ -10,7 +10,6 @@ use App\Models\InvoiceValidation;
use App\Models\Item;
use App\Models\Plant;
use App\Models\StickerMaster;
use App\Notifications\PushAlertNotification;
use Filament\Facades\Filament;
use Filament\Notifications\Notification;
use Filament\Pages\Concerns\ExposesTableToWidgets;
@@ -137,10 +136,6 @@ class CreateInvoiceValidation extends CreateRecord
->send();
$this->dispatch('playNotificationSound');
$user1 = Filament::auth()->user();
$user1->notify(new PushAlertNotification());
$this->form->fill([
'plant_id' => $plantId,
'invoice_number' => $invoiceNumber,
@@ -2290,7 +2285,6 @@ class CreateInvoiceValidation extends CreateRecord
->danger()
->seconds(3)
->send();
$this->dispatch('playWarnSound');
$this->form->fill([

View File

@@ -82,9 +82,6 @@ class ItemResource extends Resource
Forms\Components\TextInput::make('category')
->label('Category')
->placeholder('Scan the Category'),
Forms\Components\TextInput::make('category')
->label('Category')
->placeholder('Scan the Category'),
Forms\Components\TextInput::make('code')
->required()
->placeholder('Scan the valid code')

File diff suppressed because it is too large Load Diff

View File

@@ -6,8 +6,8 @@ use AlperenErsoy\FilamentExport\Actions\FilamentExportBulkAction;
use App\Filament\Exports\ProductionPlanExporter;
use App\Filament\Imports\ProductionPlanImporter;
use App\Filament\Resources\ProductionPlanResource\Pages;
use App\Filament\Resources\ProductionPlanResource\RelationManagers;
use App\Models\Block;
use App\Models\Item;
use App\Models\Line;
use App\Models\Plant;
use App\Models\ProductionPlan;
@@ -16,18 +16,19 @@ use Carbon\Carbon;
use Filament\Facades\Filament;
use Filament\Forms;
use Filament\Forms\Components\DateTimePicker;
use Filament\Forms\Components\Section;
use Filament\Forms\Components\Select;
use Filament\Forms\Form;
use Filament\Forms\Get;
use Filament\Resources\Resource;
use Filament\Tables;
use Filament\Tables\Actions\ExportAction;
use Filament\Tables\Actions\ImportAction;
use Filament\Tables\Filters\Filter;
use Filament\Tables\Table;
use Illuminate\Database\Eloquent\Builder;
use Illuminate\Database\Eloquent\SoftDeletingScope;
use Filament\Forms\Components\Section;
use Filament\Forms\Components\Select;
use Filament\Tables\Actions\ExportAction;
use Filament\Tables\Filters\Filter;
use Illuminate\Support\Facades\Request;
class ProductionPlanResource extends Resource
{
@@ -54,22 +55,22 @@ class ProductionPlanResource extends Resource
->reactive()
->options(function (callable $get) {
$userHas = Filament::auth()->user()->plant_id;
return ($userHas && strlen($userHas) > 0) ? Plant::where('id', $userHas)->pluck('name', 'id')->toArray() : Plant::orderBy('code')->pluck('name', 'id')->toArray();
return ($userHas && strlen($userHas) > 0) ? Plant::where('id', $userHas)->pluck('name', 'id')->toArray() : Plant::pluck('name', 'id')->toArray();
})
->default(function () {
return optional(ProductionPlan::latest()->first())->plant_id;
})
->disabled(fn (Get $get) => ! empty($get('id')))
->disabled(fn (Get $get) => !empty($get('id')))
// ->afterStateUpdated(fn ($set) => $set('block_name', null))
->afterStateUpdated(function ($state, callable $set, callable $get) {
$plantId = $get('plant_id');
$set('block_name', null);
if (! $plantId) {
if (!$plantId) {
$set('ppPlantError', 'Please select a plant first.');
return;
} else {
}
else
{
$set('ppPlantError', null);
}
})
@@ -78,6 +79,102 @@ class ProductionPlanResource extends Resource
])
->hint(fn ($get) => $get('ppPlantError') ? $get('ppPlantError') : null)
->hintColor('danger'),
Forms\Components\Select::make('block_name')
->required()
// ->nullable()
->label('Block')
->options(function (callable $get) {
if (!$get('plant_id')) {
return [];
}
return Block::where('plant_id', $get('plant_id'))
->pluck('name', 'id')
->toArray();
})
->reactive()
->default(function () {
$latestShiftId = optional(ProductionPlan::latest()->first())->shift_id;
return optional(Shift::where('id', $latestShiftId)->first())->block_id;
})
//->afterStateUpdated(fn ($set) => $set('shift_id', null))
->afterStateUpdated(function ($state, callable $set, callable $get) {
if($get('id'))
{
$getShift = ProductionPlan::where('id', $get('id'))->first();
$getBlock = Shift::where('id', $getShift->shift_id)->first();
if($getBlock->block_id)
{
$set('block_name', $getBlock->block_id);
$set('ppBlockError', null);
}
}
$blockId = $get('block_name');
$set('shift_id', null);
if (!$blockId) {
$set('ppBlockError', 'Please select a block first.');
return;
}
else
{
$set('ppBlockError', null);
}
})
->extraAttributes(fn ($get) => [
'class' => $get('ppBlockError') ? 'border-red-500' : '',
])
->hint(fn ($get) => $get('ppBlockError') ? $get('ppBlockError') : null)
->hintColor('danger'),
Forms\Components\Select::make('shift_id')
->relationship('shift', 'name')
->required()
// ->nullable()
->autofocus(true)
->options(function (callable $get) {
if (!$get('plant_id') || !$get('block_name')) {
return [];
}
return Shift::where('plant_id', $get('plant_id'))
->where('block_id', $get('block_name'))
->pluck('name', 'id')
->toArray();
})
->reactive()
->default(function () {
return optional(ProductionPlan::latest()->first())->shift_id;
})
// ->afterStateUpdated(fn ($set) => $set('line_id', null))
->afterStateUpdated(function ($state, callable $set, callable $get) {
if($get('id'))
{
$getShift = ProductionPlan::where('id', $get('id'))->first();
if($getShift->shift_id)
{
$set('shift_id', $getShift->shift_id);
$set('ppShiftError', null);
}
}
$curShiftId = $get('shift_id');
$set('line_id', null);
if (!$curShiftId) {
$set('ppShiftError', 'Please select a shift first.');
return;
}
else
{
$set('ppShiftError', null);
}
})
->extraAttributes(fn ($get) => [
'class' => $get('ppShiftError') ? 'border-red-500' : '',
])
->hint(fn ($get) => $get('ppShiftError') ? $get('ppShiftError') : null)
->hintColor('danger'),
Forms\Components\Select::make('line_id')
->relationship('line', 'name')
->required()
@@ -88,7 +185,7 @@ class ProductionPlanResource extends Resource
// ->toArray() // Convert collection to array
// )
->options(function (callable $get) {
if (! $get('plant_id')) {
if (!$get('plant_id') || !$get('block_name') || !$get('shift_id')) {
return [];
}
@@ -100,257 +197,248 @@ class ProductionPlanResource extends Resource
// ->default(function () {
// return optional(ProductionPlan::latest()->first())->line_id;
// })
// ->afterStateUpdated(function ($state, callable $set, callable $get) {
// if ($get('id')) {
// $getShift = ProductionPlan::where('id', $get('id'))->first();
// if ($getShift->line_id) {
// $set('line_id', $getShift->line_id);
// $set('ppLineError', null);
// }
// } else {
// $currentDT = Carbon::now()->toDateTimeString();
// $set('created_at', $currentDT);
// $set('update_date', null);
// }
// $lineId = $get('line_id');
// // $set('plan_quantity', null);
// if (! $lineId) {
// $set('ppLineError', 'Please select a line first.');
// return;
// } else {
// $isUpdate = ! empty($get('id'));
// if (! $isUpdate) {
// $exists = ProductionPlan::where('plant_id', $get('plant_id'))
// ->where('shift_id', $get('shift_id'))
// ->where('line_id', $get('line_id'))
// ->whereDate('created_at', today())
// ->latest()
// ->exists();
// if ($exists) {
// $set('line_id', null);
// $set('ppLineError', 'Production plan already updated.');
// return;
// } else {
// $existShifts = ProductionPlan::where('plant_id', $get('plant_id'))
// ->where('shift_id', $get('shift_id'))
// ->where('line_id', $get('line_id'))
// ->whereDate('created_at', Carbon::yesterday())
// ->latest()
// ->exists();
// if ($existShifts) { // if ($existShifts->count() > 0)
// // $currentDate = date('Y-m-d');
// $yesterday = date('Y-m-d', strtotime('-1 days'));
// $shiftId = Shift::where('id', $get('shift_id'))
// ->first();
// [$hRs, $miNs] = explode('.', $shiftId->duration) + [0, 0];
// $hRs = (int) $hRs;
// // $miNs = (int) $miNs;-*/
// $totalMinutes = $hRs * 60 + $miNs;
// $from_dt = $yesterday.' '.$shiftId->start_time;
// $to_dt = date('Y-m-d H:i:s', strtotime($from_dt." + $totalMinutes minutes"));
// $currentDateTime = date('Y-m-d H:i:s');
// // Check if current date time is within the range
// if ($currentDateTime >= $from_dt && $currentDateTime < $to_dt) {
// // echo "Choosed a valid shift...";
// $set('line_id', null);
// $set('ppLineError', 'Production plan already updated.');
// // $set('ppLineError', 'Valid (From: '.$from_dt.', To: '.$to_dt.')');
// return;
// } else {
// $currentDate = date('Y-m-d');
// $shiftId = Shift::where('id', $get('shift_id'))
// ->first();
// [$hRs, $miNs] = explode('.', $shiftId->duration) + [0, 0];
// $hRs = (int) $hRs;
// // $miNs = (int) $miNs;-*/
// $totalMinutes = $hRs * 60 + $miNs;
// $from_dt = $currentDate.' '.$shiftId->start_time;
// $to_dt = date('Y-m-d H:i:s', strtotime($from_dt." + $totalMinutes minutes"));
// $currentDateTime = date('Y-m-d H:i:s');
// // Check if current date time is within the range
// if (! ($currentDateTime >= $from_dt && $currentDateTime < $to_dt)) {
// // echo "Choosed a valid shift...";
// $set('line_id', null);
// $set('ppLineError', 'Choosed a invalid shift.');
// // $set('ppLineError', 'Valid (From: '.$from_dt.', To: '.$to_dt.')');
// return;
// }
// }
// $set('ppLineError', null);
// return;
// } else {
// // $currentDate = date('Y-m-d');
// $yesterday = date('Y-m-d', strtotime('-1 days'));
// $shiftId = Shift::where('id', $get('shift_id'))
// ->first();
// [$hRs, $miNs] = explode('.', $shiftId->duration) + [0, 0];
// $hRs = (int) $hRs;
// // $miNs = (int) $miNs;-*/
// $totalMinutes = $hRs * 60 + $miNs;
// $from_dt = $yesterday.' '.$shiftId->start_time;
// $to_dt = date('Y-m-d H:i:s', strtotime($from_dt." + $totalMinutes minutes"));
// $currentDateTime = date('Y-m-d H:i:s');
// // Check if current date time is within the range
// if ($currentDateTime >= $from_dt && $currentDateTime < $to_dt) {
// // echo "Choosed a valid shift...";
// // here i'm updating created as yesterday
// $set('created_at', $from_dt);
// $set('update_date', '1');
// $set('ppLineError', null);
// // $set('ppLineError', 'Valid (From: '.$from_dt.', To: '.$to_dt.')');
// return;
// } else {
// $currentDate = date('Y-m-d');
// $shiftId = Shift::where('id', $get('shift_id'))
// ->first();
// [$hRs, $miNs] = explode('.', $shiftId->duration) + [0, 0];
// $hRs = (int) $hRs;
// // $miNs = (int) $miNs;-*/
// $totalMinutes = $hRs * 60 + $miNs;
// $from_dt = $currentDate.' '.$shiftId->start_time;
// $to_dt = date('Y-m-d H:i:s', strtotime($from_dt." + $totalMinutes minutes"));
// $currentDateTime = date('Y-m-d H:i:s');
// // Check if current date time is within the range
// if (! ($currentDateTime >= $from_dt && $currentDateTime < $to_dt)) {
// // echo "Choosed a valid shift...";
// $set('line_id', null);
// $set('ppLineError', 'Choosed a invalid shift.');
// // $set('ppLineError', 'Valid (From: '.$from_dt.', To: '.$to_dt.')');
// return;
// }
// }
// $set('ppLineError', null);
// return;
// }
// // $exists = ProductionPlan::where('plant_id', $get('plant_id'))
// // //->where('shift_id', $get('shift_id'))
// // ->where('line_id', $get('line_id'))
// // ->whereDate('created_at', today())
// // ->latest() // Orders by created_at DESC
// // ->first();
// // if ($exists)
// // {
// // $existingShifts = ProductionPlan::where('plant_id', $get('plant_id'))
// // //->where('shift_id', $get('shift_id'))
// // ->where('line_id', $get('line_id'))
// // // ->whereDate('created_at', today())
// // ->whereDate('created_at', today())
// // ->get();
// // foreach ($existingShifts as $shift) {
// // $curShiftId = $shift->shift_id;
// // $currentDate = date('Y-m-d');
// // $shiftId = \App\Models\Shift::where('id', $curShiftId)
// // ->first();
// // [$hRs, $miNs] = explode('.', $shiftId->duration) + [0, 0];
// // $hRs = (int) $hRs;
// // // $miNs = (int) $miNs;-*/
// // $totalMinutes = $hRs * 60 + $miNs;
// // $from_dt = $currentDate . ' ' . $shiftId->start_time;
// // $to_dt = date('Y-m-d H:i:s', strtotime($from_dt . " + $totalMinutes minutes"));
// // $currentDateTime = date('Y-m-d H:i:s');
// // // Check if current date time is within the range
// // if ($currentDateTime >= $from_dt && $currentDateTime < $to_dt) {
// // //echo "Choosed a valid shift...";
// // // $set('ppLineError', 'Valid (From: '.$from_dt.', To: '.$to_dt.')');
// // $set('line_id', null);
// // $set('ppLineError', 'Production plan already updated.');
// // return;
// // }
// // // else {
// // // $set('ppLineError', 'Choosed a invalid shift...');
// // // return;
// // // }
// // }
// // $set('ppLineError', null);
// // return;
// // }
// }
// }
// $set('ppLineError', null);
// }
// })
->afterStateUpdated(function ($state, callable $set, callable $get) {
$set('item_id', null);
$set('plan_quantity', null);
if($get('id'))
{
$getShift = ProductionPlan::where('id', $get('id'))->first();
if($getShift->line_id)
{
$set('line_id', $getShift->line_id);
$set('ppLineError', null);
}
}
else
{
$currentDT = Carbon::now()->toDateTimeString();
$set('created_at', $currentDT);
$set('update_date', null);
}
$lineId = $get('line_id');
// $set('plan_quantity', null);
if (!$lineId) {
$set('ppLineError', 'Please select a line first.');
return;
}
else
{
$isUpdate = !empty($get('id'));
if (!$isUpdate)
{
$exists = ProductionPlan::where('plant_id', $get('plant_id'))
->where('shift_id', $get('shift_id'))
->where('line_id', $get('line_id'))
->whereDate('created_at', today())
->latest()
->exists();
if ($exists)
{
$set('line_id', null);
$set('ppLineError', 'Production plan already updated.');
return;
}
else
{
$existShifts = ProductionPlan::where('plant_id', $get('plant_id'))
->where('shift_id', $get('shift_id'))
->where('line_id', $get('line_id'))
->whereDate('created_at', Carbon::yesterday())
->latest()
->exists();
if ($existShifts) //if ($existShifts->count() > 0)
{
//$currentDate = date('Y-m-d');
$yesterday = date('Y-m-d', strtotime('-1 days'));
$shiftId = Shift::where('id', $get('shift_id'))
->first();
[$hRs, $miNs] = explode('.', $shiftId->duration) + [0, 0];
$hRs = (int) $hRs;
// $miNs = (int) $miNs;-*/
$totalMinutes = $hRs * 60 + $miNs;
$from_dt = $yesterday . ' ' . $shiftId->start_time;
$to_dt = date('Y-m-d H:i:s', strtotime($from_dt . " + $totalMinutes minutes"));
$currentDateTime = date('Y-m-d H:i:s');
// Check if current date time is within the range
if ($currentDateTime >= $from_dt && $currentDateTime < $to_dt) {
//echo "Choosed a valid shift...";
$set('line_id', null);
$set('ppLineError', 'Production plan already updated.');
// $set('ppLineError', 'Valid (From: '.$from_dt.', To: '.$to_dt.')');
return;
}
else
{
$currentDate = date('Y-m-d');
$shiftId = Shift::where('id', $get('shift_id'))
->first();
[$hRs, $miNs] = explode('.', $shiftId->duration) + [0, 0];
$hRs = (int) $hRs;
// $miNs = (int) $miNs;-*/
$totalMinutes = $hRs * 60 + $miNs;
$from_dt = $currentDate . ' ' . $shiftId->start_time;
$to_dt = date('Y-m-d H:i:s', strtotime($from_dt . " + $totalMinutes minutes"));
$currentDateTime = date('Y-m-d H:i:s');
// Check if current date time is within the range
if (!($currentDateTime >= $from_dt && $currentDateTime < $to_dt)) {
//echo "Choosed a valid shift...";
$set('line_id', null);
$set('ppLineError', 'Choosed a invalid shift.');
// $set('ppLineError', 'Valid (From: '.$from_dt.', To: '.$to_dt.')');
return;
}
}
$set('ppLineError', null);
return;
}
else
{
//$currentDate = date('Y-m-d');
$yesterday = date('Y-m-d', strtotime('-1 days'));
$shiftId = Shift::where('id', $get('shift_id'))
->first();
[$hRs, $miNs] = explode('.', $shiftId->duration) + [0, 0];
$hRs = (int) $hRs;
// $miNs = (int) $miNs;-*/
$totalMinutes = $hRs * 60 + $miNs;
$from_dt = $yesterday . ' ' . $shiftId->start_time;
$to_dt = date('Y-m-d H:i:s', strtotime($from_dt . " + $totalMinutes minutes"));
$currentDateTime = date('Y-m-d H:i:s');
// Check if current date time is within the range
if ($currentDateTime >= $from_dt && $currentDateTime < $to_dt) {
//echo "Choosed a valid shift...";
// here i'm updating created as yesterday
$set('created_at', $from_dt);
$set('update_date', '1');
$set('ppLineError', null);
// $set('ppLineError', 'Valid (From: '.$from_dt.', To: '.$to_dt.')');
return;
}
else
{
$currentDate = date('Y-m-d');
$shiftId = Shift::where('id', $get('shift_id'))
->first();
[$hRs, $miNs] = explode('.', $shiftId->duration) + [0, 0];
$hRs = (int) $hRs;
// $miNs = (int) $miNs;-*/
$totalMinutes = $hRs * 60 + $miNs;
$from_dt = $currentDate . ' ' . $shiftId->start_time;
$to_dt = date('Y-m-d H:i:s', strtotime($from_dt . " + $totalMinutes minutes"));
$currentDateTime = date('Y-m-d H:i:s');
// Check if current date time is within the range
if (!($currentDateTime >= $from_dt && $currentDateTime < $to_dt)) {
//echo "Choosed a valid shift...";
$set('line_id', null);
$set('ppLineError', 'Choosed a invalid shift.');
// $set('ppLineError', 'Valid (From: '.$from_dt.', To: '.$to_dt.')');
return;
}
}
$set('ppLineError', null);
return;
}
// $exists = ProductionPlan::where('plant_id', $get('plant_id'))
// //->where('shift_id', $get('shift_id'))
// ->where('line_id', $get('line_id'))
// ->whereDate('created_at', today())
// ->latest() // Orders by created_at DESC
// ->first();
// if ($exists)
// {
// $existingShifts = ProductionPlan::where('plant_id', $get('plant_id'))
// //->where('shift_id', $get('shift_id'))
// ->where('line_id', $get('line_id'))
// // ->whereDate('created_at', today())
// ->whereDate('created_at', today())
// ->get();
// foreach ($existingShifts as $shift) {
// $curShiftId = $shift->shift_id;
// $currentDate = date('Y-m-d');
// $shiftId = \App\Models\Shift::where('id', $curShiftId)
// ->first();
// [$hRs, $miNs] = explode('.', $shiftId->duration) + [0, 0];
// $hRs = (int) $hRs;
// // $miNs = (int) $miNs;-*/
// $totalMinutes = $hRs * 60 + $miNs;
// $from_dt = $currentDate . ' ' . $shiftId->start_time;
// $to_dt = date('Y-m-d H:i:s', strtotime($from_dt . " + $totalMinutes minutes"));
// $currentDateTime = date('Y-m-d H:i:s');
// // Check if current date time is within the range
// if ($currentDateTime >= $from_dt && $currentDateTime < $to_dt) {
// //echo "Choosed a valid shift...";
// // $set('ppLineError', 'Valid (From: '.$from_dt.', To: '.$to_dt.')');
// $set('line_id', null);
// $set('ppLineError', 'Production plan already updated.');
// return;
// }
// // else {
// // $set('ppLineError', 'Choosed a invalid shift...');
// // return;
// // }
// }
// $set('ppLineError', null);
// return;
// }
}
}
$set('ppLineError', null);
}
})
->extraAttributes(fn ($get) => [
'class' => $get('ppLineError') ? 'border-red-500' : '',
])
->hint(fn ($get) => $get('ppLineError') ? $get('ppLineError') : null)
->hintColor('danger'),
Forms\Components\Select::make('item_id')
->label('Item')
->reactive()
->searchable()
->required()
->options(function (callable $get) {
if (! $get('plant_id')) {
return [];
}
return Item::where('plant_id', $get('plant_id'))
->pluck('code', 'id')
->toArray();
}),
Forms\Components\TextInput::make('plan_quantity')
->required()
->integer()
@@ -361,18 +449,21 @@ class ProductionPlanResource extends Resource
->afterStateUpdated(function ($state, callable $set, callable $get) {
$planQuan = $get('plan_quantity');
if (! $get('update_date')) {
if (! $get('id')) {
if(!$get('update_date') )
{
if(!$get('id'))
{
$currentDT = Carbon::now()->toDateTimeString();
$set('created_at', $currentDT);
}
}
if (! $planQuan) {
if (!$planQuan) {
$set('ppPlanQuanError', 'Scan the valid plan quantity.');
return;
} else {
}
else
{
$set('ppPlanQuanError', null);
}
})
@@ -381,19 +472,29 @@ class ProductionPlanResource extends Resource
])
->hint(fn ($get) => $get('ppPlanQuanError') ? $get('ppPlanQuanError') : null)
->hintColor('danger'),
// Forms\Components\TextInput::make('production_quantity')
// ->required()
// ->integer()
// ->label('Production Quantity')
// ->readOnly(fn (callable $get) => ! $get('id'))
// ->default(0),
Forms\Components\TextInput::make('production_quantity')
->required()
->integer()
->label('Production Quantity')
->readOnly(fn (callable $get) => !$get('id'))
->default(0),
Forms\Components\TextInput::make('id')
->hidden()
->readOnly(),
Forms\Components\TextInput::make('update_date')
->hidden()
->reactive()
->readOnly(),
Forms\Components\DateTimePicker::make('created_at')
->label('Created DateTime')
->hidden()
->reactive()
->required()
->readOnly(),
Forms\Components\Hidden::make('operator_id')
->default(Filament::auth()->user()->name),
])
->columns(4),
])
->columns(2),
]);
}
@@ -428,55 +529,34 @@ class ProductionPlanResource extends Resource
$paginator = $livewire->getTableRecords();
$perPage = method_exists($paginator, 'perPage') ? $paginator->perPage() : 10;
$currentPage = method_exists($paginator, 'currentPage') ? $paginator->currentPage() : 1;
return ($currentPage - 1) * $perPage + $rowLoop->iteration;
}),
Tables\Columns\TextColumn::make('plant.name')
->label('Plant')
->alignCenter()
->sortable()
->searchable(),
Tables\Columns\TextColumn::make('line.name')
->label('Plant')
->alignCenter()
->sortable()
->searchable(),
Tables\Columns\TextColumn::make('item.code')
->label('Item')
->alignCenter()
->sortable()
->searchable(),
Tables\Columns\TextColumn::make('plan_quantity')
->label('Plan Quantity')
->alignCenter()
->numeric()
->sortable()
->searchable(),
Tables\Columns\TextColumn::make('working_days')
->label('Working Days')
->alignCenter()
->numeric()
->sortable()
->searchable(),
->sortable(),
Tables\Columns\TextColumn::make('production_quantity')
->label('Production Quantity')
->alignCenter()
->numeric()
->sortable()
->searchable(),
// Tables\Columns\TextColumn::make('line.name')
// ->label('Line')
// ->alignCenter()
// ->sortable(), // ->searchable(),
// Tables\Columns\TextColumn::make('shift.block.name')
// ->label('Block')
// ->alignCenter()
// ->sortable(),
// Tables\Columns\TextColumn::make('shift.name')
// ->label('Shift')
// ->alignCenter()
// ->sortable(), // ->searchable(),
->sortable(),
Tables\Columns\TextColumn::make('line.name')
->label('Line')
->alignCenter()
->sortable(),// ->searchable(),
Tables\Columns\TextColumn::make('shift.block.name')
->label('Block')
->alignCenter()
->sortable(),
Tables\Columns\TextColumn::make('shift.name')
->label('Shift')
->alignCenter()
->sortable(),// ->searchable(),
Tables\Columns\TextColumn::make('plant.name')
->label('Plant')
->alignCenter()
->sortable(),// ->searchable(),
Tables\Columns\TextColumn::make('created_at')
->label('Created At')
->dateTime()
@@ -504,7 +584,7 @@ class ProductionPlanResource extends Resource
Filter::make('advanced_filters')
->label('Advanced Filters')
->form([
// plant
//plant
Select::make('Plant')
->label('Select Plant')
->nullable()
@@ -513,8 +593,7 @@ class ProductionPlanResource extends Resource
// })
->options(function (callable $get) {
$userHas = Filament::auth()->user()->plant_id;
return ($userHas && strlen($userHas) > 0) ? Plant::where('id', $userHas)->pluck('name', 'id')->toArray() : Plant::orderBy('code')->pluck('name', 'id')->toArray();
return ($userHas && strlen($userHas) > 0) ? Plant::where('id', $userHas)->pluck('name', 'id')->toArray() : Plant::pluck('name', 'id')->toArray();
})
->reactive()
->afterStateUpdated(function ($state, callable $set, callable $get) {
@@ -523,33 +602,31 @@ class ProductionPlanResource extends Resource
$set('Shift', null);
}),
// line
//line
Select::make('Line')
->label('Select line')
->nullable()
->options(function (callable $get) {
$plantId = $get('Plant');
if (! $plantId) {
if (!$plantId ) {
return [];
}
return Line::where('plant_id', $plantId)
->pluck('name', 'id');
->pluck('name', 'id');
})
->reactive(),
// block
//block
Select::make('Block')
->label('Select Block')
->nullable()
->options(function (callable $get) {
$plantId = $get('Plant');
if (! $plantId) {
if (!$plantId ) {
return [];
}
return Block::where('plant_id', $get('Plant'))->pluck('name', 'id');
})
->reactive()
@@ -557,7 +634,7 @@ class ProductionPlanResource extends Resource
$set('Shift', null);
}),
// shift
//shift
Select::make('Shift')
->label('Select Shift')
->nullable()
@@ -565,7 +642,7 @@ class ProductionPlanResource extends Resource
$plantId = $get('Plant');
$blockId = $get('Block');
if (! $plantId || ! $blockId) {
if (!$plantId || !$blockId) {
return []; // Return empty if plant or block is not selected
}
@@ -592,66 +669,52 @@ class ProductionPlanResource extends Resource
return $query->whereRaw('1 = 0');
}
if (! empty($data['Plant'])) {// if ($plant = $data['Plant'] ?? null) {
$query->where('plant_id', $data['Plant']);
} else {
$userHas = Filament::auth()->user()->plant_id;
if ($userHas && strlen($userHas) > 0) {
return $query->whereRaw('1 = 0');
}
if ($plant = $data['Plant'] ?? null) {
$query->where('plant_id', $plant);
}
if (! empty($data['Shift'])) {// if ($shift = $data['Shift'] ?? null) {
$query->where('shift_id', $data['Shift']);
if ($shift = $data['Shift'] ?? null) {
$query->where('shift_id', $shift);
}
if (! empty($data['Line'])) {// if ($line = $data['Line'] ?? null) {
$query->where('line_id', $data['Line']);
if ($line = $data['Line'] ?? null) {
$query->where('line_id', $line);
}
if (! empty($data['created_from'])) {// if ($from = $data['created_from'] ?? null) {
$query->where('created_at', '>=', $data['created_from']);
if ($from = $data['created_from'] ?? null) {
$query->where('created_at', '>=', $from);
}
if (! empty($data['created_to'])) {// if ($to = $data['created_to'] ?? null) {
$query->where('created_at', '<=', $data['created_to']);
if ($to = $data['created_to'] ?? null) {
$query->where('created_at', '<=', $to);
}
return $query;
})
->indicateUsing(function (array $data) {
$indicators = [];
if (! empty($data['Plant'])) {
$indicators[] = 'Plant: '.Plant::where('id', $data['Plant'])->value('name');
} else {
$userHas = Filament::auth()->user()->plant_id;
if ($userHas && strlen($userHas) > 0) {
return 'Plant: Choose plant to filter records.';
}
if (!empty($data['Plant'])) {
$indicators[] = 'Plant: ' . Plant::where('id', $data['Plant'])->value('name');
}
if (! empty($data['Shift'])) {
$indicators[] = 'Shift: '.Shift::where('id', $data['Shift'])->value('name');
if (!empty($data['Shift'])) {
$indicators[] = 'Shift: ' . Shift::where('id', $data['Shift'])->value('name');
}
if (! empty($data['Line'])) {
$indicators[] = 'Line: '.Line::where('id', $data['Line'])->value('name');
if (!empty($data['Line'])) {
$indicators[] = 'Line: ' . Line::where('id', $data['Line'])->value('name');
}
if (! empty($data['created_from'])) {
$indicators[] = 'From: '.$data['created_from'];
if (!empty($data['created_from'])) {
$indicators[] = 'From: ' . $data['created_from'];
}
if (! empty($data['created_to'])) {
$indicators[] = 'To: '.$data['created_to'];
if (!empty($data['created_to'])) {
$indicators[] = 'To: ' . $data['created_to'];
}
return $indicators;
}),
})
])
->filtersFormMaxHeight('280px')
->actions([
@@ -663,7 +726,7 @@ class ProductionPlanResource extends Resource
Tables\Actions\DeleteBulkAction::make(),
Tables\Actions\ForceDeleteBulkAction::make(),
Tables\Actions\RestoreBulkAction::make(),
FilamentExportBulkAction::make('export'),
FilamentExportBulkAction::make('export')
]),
])
->headerActions([
@@ -671,14 +734,14 @@ class ProductionPlanResource extends Resource
->label('Import Production Plans')
->color('warning')
->importer(ProductionPlanImporter::class)
->visible(function () {
->visible(function() {
return Filament::auth()->user()->can('view import production plan');
}),
ExportAction::make()
->label('Export Production Plans')
->color('warning')
->exporter(ProductionPlanExporter::class)
->visible(function () {
->visible(function() {
return Filament::auth()->user()->can('view export production plan');
}),
]);

View File

@@ -1,295 +0,0 @@
<?php
namespace App\Filament\Resources;
use App\Filament\Exports\RequestQuotationExporter;
use App\Filament\Imports\RequestQuotationImporter;
use App\Filament\Resources\RequestQuotationResource\Pages;
use App\Filament\Resources\RequestQuotationResource\RelationManagers;
use App\Models\RequestQuotation;
use Filament\Facades\Filament;
use Filament\Forms;
use Filament\Forms\Form;
use Filament\Resources\Resource;
use Filament\Tables;
use Filament\Tables\Table;
use Illuminate\Database\Eloquent\Builder;
use Illuminate\Database\Eloquent\SoftDeletingScope;
use Illuminate\Support\Facades\Auth;
use Filament\Tables\Actions\ImportAction;
use Filament\Tables\Actions\ExportAction;
class RequestQuotationResource extends Resource
{
protected static ?string $model = RequestQuotation::class;
protected static ?string $navigationIcon = 'heroicon-o-rectangle-stack';
protected static ?string $navigationGroup = 'Request For Quotation';
public static function form(Form $form): Form
{
$canEdit = Auth::user()?->can('edit_transport_fields');
$canEditData = Auth::user()?->can('edit_all_transport_fields');
return $form
->schema([
Forms\Components\TextInput::make('rfq_number')
->label('RFQ Number')
->readOnly()
->required(),
Forms\Components\Select::make('spot_rate_transport_master_id')
->label('Group Name')
->relationship('spotRateTransportMaster', 'group_name')
->required(),
Forms\Components\DateTimePicker::make('rfq_date_time')
->label('RFQ Date Time')
->disabled(fn () => !$canEditData)
->required(),
Forms\Components\TextInput::make('pickup_address')
->label('PickUp Address')
->disabled(fn () => !$canEditData)
->required(),
Forms\Components\TextInput::make('delivery_address')
->label('Delivery Address')
->disabled(fn () => !$canEditData)
->required(),
Forms\Components\TextInput::make('weight')
->label('Weight')
->disabled(fn () => !$canEditData)
->required(),
Forms\Components\TextInput::make('volumetrice_size_inch')
->label('Volumetrice')
->disabled(fn () => !$canEditData)
->required(),
Forms\Components\TextInput::make('type_of_vehicle')
->label('Type of Vehicle')
->disabled(fn () => !$canEditData)
->required(),
Forms\Components\TextInput::make('special_type')
->label('Special Type')
->disabled(fn () => !$canEditData)
->required(),
Forms\Components\TextInput::make('no_of_vehicle')
->label('No of Vehicle')
->disabled(fn () => !$canEditData)
->required(),
Forms\Components\TextInput::make('product_name')
->label('Product Name')
->disabled(fn () => !$canEditData)
->required(),
Forms\Components\TextInput::make('loading_by')
->label('Loading By')
->disabled(fn () => !$canEditData)
->required(),
Forms\Components\TextInput::make('unloading_by')
->label('Unloading By')
->disabled(fn () => !$canEditData)
->required(),
Forms\Components\TextInput::make('pick_and_delivery')
->label('Pick and Delivery')
->disabled(fn () => !$canEditData)
->required(),
Forms\Components\TextInput::make('payment_term')
->label('Payment Term')
->disabled(fn () => !$canEditData)
->required(),
Forms\Components\TextInput::make('paid_topay')
->label('Paid Today')
->disabled(fn () => !$canEditData)
->required(),
Forms\Components\DateTimePicker::make('require_date_time')
->label('Require Date Time')
->disabled(fn () => !$canEditData)
->required(),
Forms\Components\DateTimePicker::make('rfq_rec_on_or_before')
->label('RFQ Receive On Or Before')
->disabled(fn () => !$canEditData)
->required(),
// Forms\Components\TextInput::make('transporter_name')
// ->label('Transporter Name')
// ->disabled(fn () => !($canEdit || $canEditData)),
// Forms\Components\TextInput::make('total_freight_charge')
// ->label('Total Freight Charge')
// ->disabled(fn () => !($canEdit || $canEditData)),
// Forms\Components\TextInput::make('transit_day')
// ->label('Transit Day')
// ->disabled(fn () => !($canEdit || $canEditData)),
Forms\Components\Hidden::make('created_by')
->label('Created By'),
Forms\Components\Hidden::make('updated_by')
->label('Updated By'),
]);
}
public static function table(Table $table): Table
{
return $table
->columns([
Tables\Columns\TextColumn::make('No.')
->label('No.')
->alignCenter()
->getStateUsing(function ($record, $livewire, $column, $rowLoop) {
$paginator = $livewire->getTableRecords();
$perPage = method_exists($paginator, 'perPage') ? $paginator->perPage() : 10;
$currentPage = method_exists($paginator, 'currentPage') ? $paginator->currentPage() : 1;
return ($currentPage - 1) * $perPage + $rowLoop->iteration;
}),
Tables\Columns\TextColumn::make('rfq_number')
->label('RFQ Number')
->alignCenter()
->sortable(),
Tables\Columns\TextColumn::make('spotRateTransportMaster.group_name')
->label('Group Name')
->alignCenter()
->sortable(),
Tables\Columns\TextColumn::make('rfq_date_time')
->label('RFQ Date Time')
->alignCenter()
->dateTime()
->sortable(),
Tables\Columns\TextColumn::make('pickup_address')
->label('PickUp Address')
->alignCenter()
->sortable(),
Tables\Columns\TextColumn::make('delivery_address')
->label('Delivery Address')
->alignCenter()
->sortable(),
Tables\Columns\TextColumn::make('weight')
->label('Weight')
->alignCenter()
->sortable(),
Tables\Columns\TextColumn::make('volumetrice_size_inch')
->label('Volumetrice Size Inch')
->alignCenter()
->sortable(),
Tables\Columns\TextColumn::make('type_of_vehicle')
->label('Type Of Vehicle')
->alignCenter()
->sortable(),
Tables\Columns\TextColumn::make('product_name')
->label('Product Name')
->alignCenter()
->sortable(),
Tables\Columns\TextColumn::make('loading_by')
->label('Loading By')
->alignCenter()
->sortable(),
Tables\Columns\TextColumn::make('unloading_by')
->label('Unloading By')
->alignCenter()
->sortable(),
Tables\Columns\TextColumn::make('unloading_by')
->label('Unloading By')
->alignCenter()
->sortable(),
Tables\Columns\TextColumn::make('pick_and_delivery')
->label('Pick and Delivery')
->alignCenter()
->sortable(),
Tables\Columns\TextColumn::make('payment_term')
->label('Payment Term')
->alignCenter()
->sortable(),
Tables\Columns\TextColumn::make('paid_topay')
->label('Paid Today')
->alignCenter()
->sortable(),
Tables\Columns\TextColumn::make('require_date_time')
->label('Require Date Time')
->alignCenter()
->sortable(),
Tables\Columns\TextColumn::make('rfq_rec_on_or_before')
->label('RFQ Receive On Or Before')
->alignCenter()
->sortable(),
Tables\Columns\TextColumn::make('transporter_name')
->label('Transporter Name')
->alignCenter()
->sortable(),
Tables\Columns\TextColumn::make('total_freight_charge')
->label('Total Freight Charge')
->alignCenter()
->sortable(),
Tables\Columns\TextColumn::make('transit_day')
->label('Transit Day')
->alignCenter()
->sortable(),
Tables\Columns\TextColumn::make('created_at')
->label('Created At')
->alignCenter()
->dateTime()
->sortable()
->toggleable(isToggledHiddenByDefault: true),
Tables\Columns\TextColumn::make('updated_at')
->label('Updated At')
->alignCenter()
->dateTime()
->sortable()
->toggleable(isToggledHiddenByDefault: true),
Tables\Columns\TextColumn::make('deleted_at')
->label('Deleted At')
->alignCenter()
->dateTime()
->sortable()
->toggleable(isToggledHiddenByDefault: true),
])
->filters([
Tables\Filters\TrashedFilter::make(),
])
->actions([
Tables\Actions\ViewAction::make(),
Tables\Actions\EditAction::make(),
])
->bulkActions([
Tables\Actions\BulkActionGroup::make([
Tables\Actions\DeleteBulkAction::make(),
Tables\Actions\ForceDeleteBulkAction::make(),
Tables\Actions\RestoreBulkAction::make(),
]),
])
->headerActions([
ImportAction::make()
->label('Import RequestQuotation')
->color('warning')
->importer(RequestQuotationImporter::class)
->visible(function() {
return Filament::auth()->user()->can('view import request quotation');
}),
ExportAction::make()
->label('Export RequestQuotation')
->color('warning')
->exporter(RequestQuotationExporter::class)
->visible(function() {
return Filament::auth()->user()->can('view export request quotation');
}),
]);
}
public static function getRelations(): array
{
return [
//
];
}
public static function getPages(): array
{
return [
'index' => Pages\ListRequestQuotations::route('/'),
'create' => Pages\CreateRequestQuotation::route('/create'),
'view' => Pages\ViewRequestQuotation::route('/{record}'),
'edit' => Pages\EditRequestQuotation::route('/{record}/edit'),
];
}
public static function getEloquentQuery(): Builder
{
return parent::getEloquentQuery()
->withoutGlobalScopes([
SoftDeletingScope::class,
]);
}
}

View File

@@ -1,40 +0,0 @@
<?php
namespace App\Filament\Resources\RequestQuotationResource\Pages;
use App\Filament\Resources\RequestQuotationResource;
use App\Models\RequestQuotation;
use Filament\Actions;
use Filament\Resources\Pages\CreateRecord;
class CreateRequestQuotation extends CreateRecord
{
protected static string $resource = RequestQuotationResource::class;
public function mount(): void
{
parent::mount();
$this->form->fill([
'rfq_number' => $this->generateRfqNumber(),
]);
}
protected function generateRfqNumber(): string
{
$year = now()->year;
$lastRfq = RequestQuotation::whereYear('created_at', $year)
->orderBy('id', 'desc')
->value('rfq_number');
if ($lastRfq) {
$lastNumber = (int) substr($lastRfq, -3);
$nextNumber = str_pad($lastNumber + 1, 3, '0', STR_PAD_LEFT);
} else {
$nextNumber = '001';
}
return "C.R.I-{$year}-{$nextNumber}";
}
}

View File

@@ -1,22 +0,0 @@
<?php
namespace App\Filament\Resources\RequestQuotationResource\Pages;
use App\Filament\Resources\RequestQuotationResource;
use Filament\Actions;
use Filament\Resources\Pages\EditRecord;
class EditRequestQuotation extends EditRecord
{
protected static string $resource = RequestQuotationResource::class;
protected function getHeaderActions(): array
{
return [
Actions\ViewAction::make(),
Actions\DeleteAction::make(),
Actions\ForceDeleteAction::make(),
Actions\RestoreAction::make(),
];
}
}

View File

@@ -1,19 +0,0 @@
<?php
namespace App\Filament\Resources\RequestQuotationResource\Pages;
use App\Filament\Resources\RequestQuotationResource;
use Filament\Actions;
use Filament\Resources\Pages\ListRecords;
class ListRequestQuotations extends ListRecords
{
protected static string $resource = RequestQuotationResource::class;
protected function getHeaderActions(): array
{
return [
Actions\CreateAction::make(),
];
}
}

View File

@@ -1,19 +0,0 @@
<?php
namespace App\Filament\Resources\RequestQuotationResource\Pages;
use App\Filament\Resources\RequestQuotationResource;
use Filament\Actions;
use Filament\Resources\Pages\ViewRecord;
class ViewRequestQuotation extends ViewRecord
{
protected static string $resource = RequestQuotationResource::class;
protected function getHeaderActions(): array
{
return [
Actions\EditAction::make(),
];
}
}

View File

@@ -1,345 +0,0 @@
<?php
namespace App\Filament\Resources;
use App\Filament\Resources\RfqTransporterBidResource\Pages;
use App\Filament\Resources\RfqTransporterBidResource\RelationManagers;
use App\Models\RfqTransporterBid;
use Filament\Facades\Filament;
use Filament\Forms;
use Filament\Forms\Components\Section;
use Filament\Forms\Components\TextInput;
use Filament\Forms\Form;
use Filament\Resources\Resource;
use Filament\Tables;
use Filament\Tables\Table;
use Illuminate\Database\Eloquent\Builder;
use Illuminate\Database\Eloquent\SoftDeletingScope;
use Illuminate\Validation\Rule;
class RfqTransporterBidResource extends Resource
{
protected static ?string $model = RfqTransporterBid::class;
protected static ?string $navigationIcon = 'heroicon-o-rectangle-stack';
protected static ?string $navigationGroup = 'Request For Quotation';
public static function getEloquentQuery(): Builder
{
$user = Filament::auth()->user();
return parent::getEloquentQuery()
->withoutGlobalScopes([
SoftDeletingScope::class,
])
->when(
! $user->hasAnyRole(['Super Admin', 'TransporterBidSupervisor']),
fn (Builder $query) => $query
->where('transporter_name', $user->name)
->whereNotNull('request_quotation_id')
);
}
public static function form(Form $form): Form
{
return $form
->schema([
Forms\Components\Select::make('request_quotation_id')
->label('RFQ Number')
// ->relationship('requestQuotation', 'rfq_number')
->relationship(
'requestQuotation',
'rfq_number',
function (Builder $query) {
$userName = Filament::auth()->user()?->name;
$masterIds = \App\Models\SpotRateTransportMaster::whereRaw(
"user_name::jsonb @> ?",
[json_encode([$userName])]
)
->pluck('id')
->unique()
->toArray();
if (empty($masterIds)) {
$query->whereRaw('1 = 0');
return;
}
$query->whereIn('spot_rate_transport_master_id', $masterIds);
}
)
->reactive()
// ->disabled(fn ($record) => !Filament::auth()->user()?->hasAnyRole(['Super Admin', 'TransporterBidSupervisor']))
->disabled(fn ($record) =>
!Filament::auth()->user()?->hasAnyRole(['Super Admin', 'TransporterBidSupervisor'])
&& $record
)
->afterStateUpdated(function ($state, callable $set) {
$rfq = \App\Models\RequestQuotation::find($state);
if ($rfq) {
$set('pickup_address', $rfq->pickup_address);
$set('delivery_address', $rfq->delivery_address);
$set('type_of_vehicle', $rfq->type_of_vehicle);
$set('weight', $rfq->weight);
$set('volumetrice_size_inch', $rfq->volumetrice_size_inch);
$set('no_of_vehicle', $rfq->no_of_vehicle);
$set('product_name', $rfq->product_name);
$set('pick_and_delivery', $rfq->pick_and_delivery);
$set('payment_term', $rfq->payment_term);
$set('paid_topay', $rfq->paid_topay);
$set('loading_by', $rfq->loading_by);
$set('unloading_by', $rfq->unloading_by);
$set('special_type', $rfq->special_type);
$set('rfq_date_time', $rfq->rfq_date_time);
$set('require_date_time', $rfq->require_date_time);
$set('rfq_rec_on_or_before', $rfq->rfq_rec_on_or_before);
}
})
->afterStateHydrated(function ($state, callable $set) {
$rfq = \App\Models\RequestQuotation::find($state);
if ($rfq) {
$set('pickup_address', $rfq->pickup_address);
$set('delivery_address', $rfq->delivery_address);
$set('type_of_vehicle', $rfq->type_of_vehicle);
$set('weight', $rfq->weight);
$set('volumetrice_size_inch', $rfq->volumetrice_size_inch);
$set('no_of_vehicle', $rfq->no_of_vehicle);
$set('product_name', $rfq->product_name);
$set('pick_and_delivery', $rfq->pick_and_delivery);
$set('payment_term', $rfq->payment_term);
$set('paid_topay', $rfq->paid_topay);
$set('loading_by', $rfq->loading_by);
$set('unloading_by', $rfq->unloading_by);
$set('special_type', $rfq->special_type);
$set('rfq_date_time', $rfq->rfq_date_time);
$set('require_date_time', $rfq->require_date_time);
$set('rfq_rec_on_or_before', $rfq->rfq_rec_on_or_before);
}
})
->required(),
Forms\Components\Section::make('RFQ Details')
->visible(fn ($get) => $get('request_quotation_id') != null)
->reactive()
->schema([
TextInput::make('pickup_address')->label('Pickup Address')->disabled(),
TextInput::make('delivery_address')->label('Delivery Address')->disabled(),
TextInput::make('type_of_vehicle')->label('Vehicle Type')->disabled(),
TextInput::make('weight')->label('Weight')->disabled(),
TextInput::make('volumetrice_size_inch')->label('Volumetric Size')->disabled(),
TextInput::make('no_of_vehicle')->label('No. of Vehicle')->disabled(),
TextInput::make('product_name')->label('Product Name')->disabled(),
TextInput::make('pick_and_delivery')->label('Pick & Delivery')->disabled(),
TextInput::make('payment_term')->label('Payment Term')->disabled(),
TextInput::make('paid_topay')->label('Paid / To Pay')->disabled(),
TextInput::make('loading_by')->label('Loading By')->disabled(),
TextInput::make('unloading_by')->label('Unloading By')->disabled(),
TextInput::make('special_type')->label('Special Type')->disabled(),
TextInput::make('rfq_date_time')->label('RFQ Created On')->disabled(),
TextInput::make('require_date_time')->label('Required Date')->disabled(),
TextInput::make('rfq_rec_on_or_before')->label('RFQ Received On/Before')->disabled(),
]),
Forms\Components\TextInput::make('transporter_name')
->label('Transporter Name')
->readOnly()
->default(Filament::auth()->user()?->name)
->required()
->rule(function (callable $get) {
return Rule::unique('rfq_transporter_bids', 'transporter_name')
->where('request_quotation_id', $get('request_quotation_id'))
->ignore($get('id'));
}),
Forms\Components\TextInput::make('total_freight_charge')
->label('Total Freight Charge')
->required()
// ->disabled(fn ($record) => $record && $record->created_by != Filament::auth()->user()?->name)
// ->hidden(fn ($record) => !Filament::auth()->user()?->hasAnyRole(['Super Admin', 'TransporterBidSupervisor']) && $record->transporter_name != Filament::auth()->user()?->name),
->hidden(fn ($record) =>
!Filament::auth()->user()?->hasAnyRole(['Super Admin', 'TransporterBidSupervisor'])
&& ($record && $record->transporter_name != Filament::auth()->user()?->name) // Ensure $record is not null before checking transporter_name
),
Forms\Components\TextInput::make('transit_day')
->label('Transit Day')
->required()
// ->disabled(fn ($record) => $record && $record->created_by != Filament::auth()->user()?->name),
// ->hidden(fn ($record) => !Filament::auth()->user()?->hasAnyRole(['Super Admin', 'TransporterBidSupervisor']) && $record->transporter_name != Filament::auth()->user()?->name),
->hidden(fn ($record) =>
!Filament::auth()->user()?->hasAnyRole(['Super Admin', 'TransporterBidSupervisor'])
&& ($record && $record->transporter_name != Filament::auth()->user()?->name) // Ensure $record is not null before checking transporter_name
),
Forms\Components\Hidden::make('created_by')
->label('Created By')
->default(Filament::auth()->user()?->name),
Forms\Components\Hidden::make('updated_by')
->label('Updated By')
->default(Filament::auth()->user()?->name),
]);
}
public static function table(Table $table): Table
{
return $table
->columns([
Tables\Columns\TextColumn::make('No.')
->label('No.')
->alignCenter()
->getStateUsing(function ($record, $livewire, $column, $rowLoop) {
$paginator = $livewire->getTableRecords();
$perPage = method_exists($paginator, 'perPage') ? $paginator->perPage() : 10;
$currentPage = method_exists($paginator, 'currentPage') ? $paginator->currentPage() : 1;
return ($currentPage - 1) * $perPage + $rowLoop->iteration;
}),
Tables\Columns\TextColumn::make('requestQuotation.rfq_number')
->label('RFQ Number')
->searchable()
->alignCenter()
->sortable(),
Tables\Columns\TextColumn::make('requestQuotation.pickup_address')
->label('PickUp Address')
->searchable()
->alignCenter()
->sortable(),
Tables\Columns\TextColumn::make('requestQuotation.delivery_address')
->label('Delivery Address')
->searchable()
->alignCenter()
->sortable(),
Tables\Columns\TextColumn::make('requestQuotation.type_of_vehicle')
->label('Type Of Vehicle')
->searchable()
->alignCenter()
->sortable(),
Tables\Columns\TextColumn::make('requestQuotation.weight')
->label('Weight')
->searchable()
->alignCenter()
->sortable(),
Tables\Columns\TextColumn::make('requestQuotation.volumetrice_size_inch')
->label('Volumetrice Size Inch')
->searchable()
->alignCenter()
->sortable(),
Tables\Columns\TextColumn::make('requestQuotation.no_of_vehicle')
->label('No Of Vehicle')
->searchable()
->alignCenter()
->sortable(),
Tables\Columns\TextColumn::make('requestQuotation.product_name')
->label('Product Name')
->searchable()
->alignCenter()
->sortable(),
Tables\Columns\TextColumn::make('requestQuotation.pick_and_delivery')
->label('Pick And Delivery')
->searchable()
->alignCenter()
->sortable(),
Tables\Columns\TextColumn::make('requestQuotation.payment_term')
->label('Payment Term')
->searchable()
->alignCenter()
->sortable(),
Tables\Columns\TextColumn::make('requestQuotation.paid_topay')
->label('Paid Today')
->searchable()
->alignCenter()
->sortable(),
Tables\Columns\TextColumn::make('requestQuotation.loading_by')
->label('Loading By')
->searchable()
->alignCenter()
->sortable(),
Tables\Columns\TextColumn::make('requestQuotation.unloading_by')
->label('Unloading By')
->searchable()
->alignCenter()
->sortable(),
Tables\Columns\TextColumn::make('requestQuotation.special_type')
->label('Special Type')
->searchable()
->alignCenter()
->sortable(),
Tables\Columns\TextColumn::make('requestQuotation.rfq_date_time')
->label('RFQ DateTime')
->searchable()
->alignCenter()
->sortable(),
Tables\Columns\TextColumn::make('requestQuotation.require_date_time')
->label('RFQ Require DateTime')
->searchable()
->alignCenter()
->sortable(),
Tables\Columns\TextColumn::make('requestQuotation.rfq_rec_on_or_before')
->label('RFQ Rec On Or Before')
->searchable()
->alignCenter()
->sortable(),
Tables\Columns\TextColumn::make('created_at')
->dateTime()
->sortable()
->toggleable(isToggledHiddenByDefault: true),
Tables\Columns\TextColumn::make('created_by')
->label('Created By')
->searchable()
->alignCenter()
->sortable(),
Tables\Columns\TextColumn::make('updated_at')
->dateTime()
->sortable()
->toggleable(isToggledHiddenByDefault: true),
Tables\Columns\TextColumn::make('updated_by')
->label('Updated By')
->searchable()
->alignCenter()
->sortable(),
Tables\Columns\TextColumn::make('deleted_at')
->dateTime()
->sortable()
->toggleable(isToggledHiddenByDefault: true),
])
->filters([
Tables\Filters\TrashedFilter::make(),
])
->actions([
Tables\Actions\ViewAction::make(),
Tables\Actions\EditAction::make(),
])
->bulkActions([
Tables\Actions\BulkActionGroup::make([
Tables\Actions\DeleteBulkAction::make(),
Tables\Actions\ForceDeleteBulkAction::make(),
Tables\Actions\RestoreBulkAction::make(),
]),
]);
}
public static function getRelations(): array
{
return [
//
];
}
public static function getPages(): array
{
return [
'index' => Pages\ListRfqTransporterBids::route('/'),
'create' => Pages\CreateRfqTransporterBid::route('/create'),
'view' => Pages\ViewRfqTransporterBid::route('/{record}'),
'edit' => Pages\EditRfqTransporterBid::route('/{record}/edit'),
];
}
// public static function getEloquentQuery(): Builder
// {
// return parent::getEloquentQuery()
// ->withoutGlobalScopes([
// SoftDeletingScope::class,
// ]);
// }
}

View File

@@ -1,64 +0,0 @@
<?php
namespace App\Filament\Resources\RfqTransporterBidResource\Pages;
use App\Filament\Resources\RfqTransporterBidResource;
use App\Models\RfqTransporterBid;
use App\Models\User;
use App\Notifications\PushAlertNotification;
use Filament\Actions;
use Filament\Facades\Filament;
use Filament\Notifications\Notification;
use Filament\Resources\Pages\CreateRecord;
class CreateRfqTransporterBid extends CreateRecord
{
protected static string $resource = RfqTransporterBidResource::class;
protected function afterCreate(): void
{
$record = $this->record;
// Calculate rank based on total_freight_charge
$rank = RfqTransporterBid::where('request_quotation_id', $this->record->request_quotation_id)
->orderBy('total_freight_charge')
->pluck('id')
->search($this->record->id) + 1;
$recipients = User::role(['Super Admin', 'Rfq Supervisor'])->get();
$currentUser = Filament::auth()->user();
if ($currentUser && ! $recipients->contains('id', $currentUser->id)) {
$recipients->push($currentUser);
}
// $user1 = Filament::auth()->user();
$rfqNumber = $this->record->requestQuotation->rfq_number;
$body = "{$currentUser->name} has updated the bid for RFQ No '{$rfqNumber}'. The current rank is #{$rank}.";
Notification::make()
->title('Rank Updated')
->body("{$currentUser->name} has updated the bid for RFQ No '{$rfqNumber}'. The current rank is #{$rank}.")
->success()
->sendToDatabase($recipients);
// Push notification
foreach ($recipients as $user) {
$user->notify(
new PushAlertNotification(
'New Bid Added',
$body
)
);
}
\Log::info('Create bid notification sent', [
'bid_id' => $record->id,
'rank' => $rank,
'recipients' => $recipients->pluck('id'),
]);
}
}

View File

@@ -1,175 +0,0 @@
<?php
namespace App\Filament\Resources\RfqTransporterBidResource\Pages;
use App\Filament\Resources\RfqTransporterBidResource;
use App\Models\RequestQuotation;
use App\Models\RfqTransporterBid;
use App\Models\SpotRateTransportMaster;
use App\Models\User;
use App\Notifications\PushAlertNotification;
use Filament\Actions;
use Filament\Facades\Filament;
use Filament\Notifications\Notification;
use Filament\Resources\Pages\EditRecord;
use Illuminate\Support\Facades\Log;
class EditRfqTransporterBid extends EditRecord
{
protected static string $resource = RfqTransporterBidResource::class;
protected function afterSave(): void
{
if (! $this->record->wasChanged('total_freight_charge')) {
return;
}
$rank = RfqTransporterBid::where('request_quotation_id', $this->record->request_quotation_id)
->orderBy('total_freight_charge')
->pluck('id')
->search($this->record->id) + 1;
$requestQuotation = RequestQuotation::findOrFail(
$this->record->request_quotation_id
);
$spotRateId = $requestQuotation->spot_rate_transport_master_id;
$spotRate = SpotRateTransportMaster::findOrFail($spotRateId);
$userNames = $spotRate->user_name;
Log::info('User names from spot rate', [
'user_name_raw' => $spotRate->user_name,
]);
if (!is_array($userNames)) {
Log::warning('user_name is not array, resetting', [
'user_name' => $userNames,
]);
$userNames = [];
}
$users = User::whereIn('name', $userNames)->get();
Log::info('Matched users', [
'count' => $users->count(),
'user_ids' => $users->pluck('id'),
]);
// $recipients = User::role(['Super Admin', 'Rfq Supervisor', 'TransporterBid Employee'])->get();
// $recipients1 = User::role(['Super Admin', 'Rfq Supervisor', 'TransporterBid Employee'])->whereHas('pushSubscriptions')->get();
$currentUser = Filament::auth()->user();
// if ($currentUser && ! $recipients1->contains('id', $currentUser->id)) {
// $recipients1->push($currentUser);
// }
// if ($currentUser && ! $recipients->contains('id', $currentUser->id)) {
// $recipients->push($currentUser);
// }
// $user1 = Filament::auth()->user();
$rfqNumber = $this->record->requestQuotation->rfq_number;
$body = "{$currentUser->name} has updated the bid for RFQ No '{$rfqNumber}'. The current rank is #{$rank}.";
// Notification::make()
// ->title('Rank Updated')
// ->body("{$currentUser->name} current rank is #{$rank}")
// ->success()
// ->sendToDatabase($recipients);
// \Log::info('Notification sent', [
// 'rank' => $rank,
// 'recipients' => $recipients->pluck('id'),
// ]);
Notification::make()
->title('Rank Updated')
->body("{$currentUser->name} has updated the bid for RFQ No '{$rfqNumber}'. The current rank is #{$rank}.")
->success()
->sendToDatabase($users);
// foreach ($recipients1 as $user) {
// $user->notify(
// new PushAlertNotification(
// 'Rank Updated',
// $body
// )
// );
// }
// foreach ($users as $user) {
// Log::info('Checking push subscription for user', [
// 'user_id' => $user->id,
// 'name' => $user->name,
// 'subscription_count' => $user->pushSubscriptions()->count(),
// ]);
// if ($user->pushSubscriptions()->exists()) {
// Log::info('Sending push notification', [
// 'user_id' => $user->id,
// ]);
// $user->notify(
// new PushAlertNotification(
// 'Rank Updated',
// $body
// )
// );
// }
// else {
// Log::warning('User has NO push subscription', [
// 'user_id' => $user->id,
// ]);
// }
// }
foreach ($users as $user) {
$count = $user->pushSubscriptions()->count();
Log::info('Checking push subscription for user', [
'user_id' => $user->id,
'name' => $user->name,
'subscription_count' => $count,
]);
if ($count == 0) {
Log::warning('User has NO push subscription', [
'user_id' => $user->id,
]);
continue;
}
Log::info('Sending push notification', [
'user_id' => $user->id,
]);
// ✅ THIS IS ALL YOU NEED
$user->notify(new PushAlertNotification(
'Rank Updated',
$body
));
}
}
protected function getHeaderActions(): array
{
return [
Actions\ViewAction::make(),
Actions\DeleteAction::make(),
Actions\ForceDeleteAction::make(),
Actions\RestoreAction::make(),
];
}
}

View File

@@ -1,19 +0,0 @@
<?php
namespace App\Filament\Resources\RfqTransporterBidResource\Pages;
use App\Filament\Resources\RfqTransporterBidResource;
use Filament\Actions;
use Filament\Resources\Pages\ListRecords;
class ListRfqTransporterBids extends ListRecords
{
protected static string $resource = RfqTransporterBidResource::class;
protected function getHeaderActions(): array
{
return [
Actions\CreateAction::make(),
];
}
}

View File

@@ -1,19 +0,0 @@
<?php
namespace App\Filament\Resources\RfqTransporterBidResource\Pages;
use App\Filament\Resources\RfqTransporterBidResource;
use Filament\Actions;
use Filament\Resources\Pages\ViewRecord;
class ViewRfqTransporterBid extends ViewRecord
{
protected static string $resource = RfqTransporterBidResource::class;
protected function getHeaderActions(): array
{
return [
Actions\EditAction::make(),
];
}
}

View File

@@ -1,130 +0,0 @@
<?php
namespace App\Filament\Resources;
use App\Filament\Resources\SpotRateTransportMasterResource\Pages;
use App\Filament\Resources\SpotRateTransportMasterResource\RelationManagers;
use App\Models\SpotRateTransportMaster;
use App\Models\User;
use Filament\Facades\Filament;
use Filament\Forms;
use Filament\Forms\Form;
use Filament\Resources\Resource;
use Filament\Tables;
use Filament\Tables\Table;
use Illuminate\Database\Eloquent\Builder;
use Illuminate\Database\Eloquent\SoftDeletingScope;
use Illuminate\Validation\Rule;
use Illuminate\Support\Facades\DB;
class SpotRateTransportMasterResource extends Resource
{
protected static ?string $model = SpotRateTransportMaster::class;
protected static ?string $navigationIcon = 'heroicon-o-rectangle-stack';
protected static ?string $navigationGroup = 'Request For Quotation';
public static function form(Form $form): Form
{
return $form
->schema([
Forms\Components\TextInput::make('group_name')
->label('Group Name')
->required(),
Forms\Components\Select::make('user_name')
->label('User')
->multiple()
->preload()
->reactive()
->options(
User::pluck('name', 'name')->toArray()
)
->searchable()
->required(),
Forms\Components\Hidden::make('id')
->label('id'),
Forms\Components\Hidden::make('created_by')
->label('Created By')
->default(Filament::auth()->user()?->name),
Forms\Components\Hidden::make('updated_by')
->label('Updated By')
->default(Filament::auth()->user()?->name),
]);
}
public static function table(Table $table): Table
{
return $table
->columns([
Tables\Columns\TextColumn::make('No.')
->label('No.')
->getStateUsing(function ($record, $livewire, $column, $rowLoop) {
$paginator = $livewire->getTableRecords();
$perPage = method_exists($paginator, 'perPage') ? $paginator->perPage() : 10;
$currentPage = method_exists($paginator, 'currentPage') ? $paginator->currentPage() : 1;
return ($currentPage - 1) * $perPage + $rowLoop->iteration;
}),
Tables\Columns\TextColumn::make('group_name')
->label('Group Name')
->sortable(),
Tables\Columns\TextColumn::make('user_name')
->label('User Name')
->sortable(),
Tables\Columns\TextColumn::make('created_at')
->label('Created At')
->dateTime()
->sortable()
->toggleable(isToggledHiddenByDefault: true),
Tables\Columns\TextColumn::make('updated_at')
->label('Updated At')
->dateTime()
->sortable()
->toggleable(isToggledHiddenByDefault: true),
Tables\Columns\TextColumn::make('deleted_at')
->dateTime()
->sortable()
->toggleable(isToggledHiddenByDefault: true),
])
->filters([
Tables\Filters\TrashedFilter::make(),
])
->actions([
Tables\Actions\ViewAction::make(),
Tables\Actions\EditAction::make(),
])
->bulkActions([
Tables\Actions\BulkActionGroup::make([
Tables\Actions\DeleteBulkAction::make(),
Tables\Actions\ForceDeleteBulkAction::make(),
Tables\Actions\RestoreBulkAction::make(),
]),
]);
}
public static function getRelations(): array
{
return [
//
];
}
public static function getPages(): array
{
return [
'index' => Pages\ListSpotRateTransportMasters::route('/'),
'create' => Pages\CreateSpotRateTransportMaster::route('/create'),
'view' => Pages\ViewSpotRateTransportMaster::route('/{record}'),
'edit' => Pages\EditSpotRateTransportMaster::route('/{record}/edit'),
];
}
public static function getEloquentQuery(): Builder
{
return parent::getEloquentQuery()
->withoutGlobalScopes([
SoftDeletingScope::class,
]);
}
}

View File

@@ -1,43 +0,0 @@
<?php
namespace App\Filament\Resources\SpotRateTransportMasterResource\Pages;
use App\Filament\Resources\SpotRateTransportMasterResource;
use App\Models\SpotRateTransportMaster;
use Filament\Actions;
use Filament\Notifications\Notification;
use Filament\Resources\Pages\CreateRecord;
class CreateSpotRateTransportMaster extends CreateRecord
{
protected static string $resource = SpotRateTransportMasterResource::class;
protected function beforeCreate(): void
{
$groupName = $this->data['group_name'] ?? null;
$userNames = $this->data['user_name'] ?? [];
foreach ($userNames as $userName) {
$query = SpotRateTransportMaster::where('group_name', $groupName)
->whereJsonContains('user_name', $userName);
if ($query->exists()) {
Notification::make()
->title('Duplicate User')
->body("User {$userName} already exists in this group.")
->danger()
->persistent()
->send();
// Prevent create
$this->halt();
return;
}
}
}
}

View File

@@ -1,56 +0,0 @@
<?php
namespace App\Filament\Resources\SpotRateTransportMasterResource\Pages;
use App\Filament\Resources\SpotRateTransportMasterResource;
use App\Models\SpotRateTransportMaster;
use Filament\Actions;
use Filament\Notifications\Notification;
use Filament\Resources\Pages\EditRecord;
class EditSpotRateTransportMaster extends EditRecord
{
protected static string $resource = SpotRateTransportMasterResource::class;
protected function beforeSave(): void
{
$groupName = $this->data['group_name'] ?? null;
$userNames = $this->data['user_name'] ?? [];
$recordId = $this->record->id ?? null;
foreach ($userNames as $userName) {
$query = SpotRateTransportMaster::where('group_name', $groupName)
->whereJsonContains('user_name', $userName);
// Exclude current record for update
if ($recordId) {
$query->where('id', '!=', $recordId);
}
if ($query->exists()) {
Notification::make()
->title('Duplicate User')
->body("User {$userName} already exists in this group.")
->danger()
->persistent()
->send();
// Prevent save/update
$this->halt();
return;
}
}
}
protected function getHeaderActions(): array
{
return [
Actions\ViewAction::make(),
Actions\DeleteAction::make(),
Actions\ForceDeleteAction::make(),
Actions\RestoreAction::make(),
];
}
}

View File

@@ -1,19 +0,0 @@
<?php
namespace App\Filament\Resources\SpotRateTransportMasterResource\Pages;
use App\Filament\Resources\SpotRateTransportMasterResource;
use Filament\Actions;
use Filament\Resources\Pages\ListRecords;
class ListSpotRateTransportMasters extends ListRecords
{
protected static string $resource = SpotRateTransportMasterResource::class;
protected function getHeaderActions(): array
{
return [
Actions\CreateAction::make(),
];
}
}

View File

@@ -1,19 +0,0 @@
<?php
namespace App\Filament\Resources\SpotRateTransportMasterResource\Pages;
use App\Filament\Resources\SpotRateTransportMasterResource;
use Filament\Actions;
use Filament\Resources\Pages\ViewRecord;
class ViewSpotRateTransportMaster extends ViewRecord
{
protected static string $resource = SpotRateTransportMasterResource::class;
protected function getHeaderActions(): array
{
return [
Actions\EditAction::make(),
];
}
}

View File

@@ -1,146 +0,0 @@
<?php
namespace App\Filament\Widgets;
use App\Models\RequestQuotation;
use App\Models\RfqTransporterBid;
use Filament\Facades\Filament;
use Filament\Widgets\StatsOverviewWidget as BaseWidget;
use Filament\Widgets\StatsOverviewWidget\Stat;
class RfqChart extends BaseWidget
{
// protected function getStats(): array
// {
// $transporter = session('transport_name');
// $rfqNumber = session('rfq_number');
// if (!$transporter || !$rfqNumber) {
// return [
// Stat::make('Total Freight Charge', '-'),
// Stat::make('Rank', '-'),
// ];
// }
// $selectedRfq = RequestQuotation::query()
// ->where('transporter_name', $transporter)
// ->where('rfq_number', $rfqNumber)
// ->first();
// if (!$selectedRfq) {
// return [
// Stat::make('Total Freight Charge', '-'),
// Stat::make('Rank', '-'),
// ];
// }
// $myAmount = (float) $selectedRfq->total_freight_charge;
// $rank = RequestQuotation::query()
// ->whereRaw(
// 'CAST(total_freight_charge AS DECIMAL(10,2)) < ?',
// [$myAmount]
// )
// ->selectRaw('CAST(total_freight_charge AS DECIMAL(10,2))')
// ->distinct()
// ->count() + 1;
// $medal = match (true) {
// $rank == 1 => '🥇',
// $rank == 2 => '🥈',
// $rank == 3 => '🥉',
// default => '',
// };
// return [
// Stat::make(
// 'Total Freight Charge',
// number_format($selectedRfq->total_freight_charge, 2)
// )
// ->description('Transporter: ' . $selectedRfq->transporter_name)
// ->color($rank == 1 ? 'success' : 'primary'),
// Stat::make(
// 'Rank',
// trim("{$medal} #{$rank}")
// )
// ->description('Among all transporters')
// ->color(
// $rank == 1 ? 'success' :
// ($rank <= 3 ? 'warning' : 'gray')
// ),
// ];
// }
protected function getStats(): array
{
$transporter = session('transport_name');
$rfqNumber = session('rfq_id');
if (!$transporter || !$rfqNumber) {
return [
Stat::make('Total Freight Charge', '-'),
Stat::make('Rank', '-'),
];
}
$selectedRfq = RfqTransporterBid::query()
->where('transporter_name', $transporter)
->where('request_quotation_id', $rfqNumber)
->first();
if (!$selectedRfq) {
return [
Stat::make('Total Freight Charge', '-'),
Stat::make('Rank', '-'),
];
}
$myAmount = (float) $selectedRfq->total_freight_charge;
// $rank = RfqTransporterBid::query()
// ->whereRaw(
// 'CAST(total_freight_charge AS DECIMAL(10,2)) < ?',
// [$myAmount]
// )
// ->selectRaw('CAST(total_freight_charge AS DECIMAL(10,2))')
// ->distinct()
// ->count() + 1;
$rank = RfqTransporterBid::query()
->where('request_quotation_id', $rfqNumber) // 🔥 MISSING CONDITION
->whereRaw(
'CAST(total_freight_charge AS DECIMAL(10,2)) < ?',
[$myAmount]
)
->selectRaw('CAST(total_freight_charge AS DECIMAL(10,2))')
->distinct()
->count() + 1;
$medal = match (true) {
$rank == 1 => '🥇',
$rank == 2 => '🥈',
$rank == 3 => '🥉',
default => '',
};
return [
Stat::make(
'Total Freight Charge',
number_format($selectedRfq->total_freight_charge, 2)
)
->description('Transporter: ' . $selectedRfq->transporter_name)
->color($rank == 1 ? 'success' : 'primary'),
Stat::make(
'Rank',
trim("{$medal} #{$rank}")
)
->description('Among all transporters')
->color(
$rank == 1 ? 'success' :
($rank <= 3 ? 'warning' : 'gray')
),
];
}
}

View File

@@ -1,205 +0,0 @@
<?php
namespace App\Filament\Widgets;
use App\Models\RfqTransporterBid;
use Filament\Widgets\ChartWidget;
use Illuminate\Support\Js;
class RfqRankChart extends ChartWidget
{
protected static ?string $heading = 'Chart';
// protected function getData(): array
// {
// $rfqId = session('rfq_id');
// if (!$rfqId) {
// return [
// 'datasets' => [],
// 'labels' => [],
// ];
// }
// // Get bids ordered by lowest freight charge
// $bids = RfqTransporterBid::query()
// ->where('request_quotation_id', $rfqId)
// ->orderByRaw('CAST(total_freight_charge AS DECIMAL(10,2)) ASC')
// ->get();
// // $labels = [];
// // $ranks = [];
// // $rank = 1;
// // foreach ($bids as $bid) {
// // $labels[] = $bid->transporter_name;
// // $ranks[] = $rank++;
// // }
// // return [
// // 'datasets' => [
// // [
// // 'label' => 'Rank (Lower is Better)',
// // 'data' => $ranks,
// // 'fill' => false,
// // 'tension' => 0.3,
// // ],
// // ],
// // 'labels' => $labels,
// // ];
// $labels = [];
// $ranks = [];
// $colors = [];
// $rank = 1;
// foreach ($bids as $bid) {
// $labels[] = $bid->transporter_name;
// $ranks[] = $rank;
// // Rank-based colors
// $colors[] = match ($rank) {
// 1 => '#FFD700', // Gold
// 2 => '#C0C0C0', // Silver
// 3 => '#CD7F32', // Bronze
// default => '#3B82F6', // Blue
// };
// $rank++;
// }
// return [
// 'datasets' => [
// [
// 'label' => 'Rank (1 = Best)',
// 'data' => $ranks,
// // 🎨 Styling
// 'borderColor' => '#3B82F6',
// 'backgroundColor' => $colors,
// 'pointBackgroundColor' => $colors,
// 'pointBorderColor' => '#000',
// 'pointRadius' => 7,
// 'pointHoverRadius' => 10,
// 'borderWidth' => 3,
// 'tension' => 0.4,
// 'fill' => false,
// ],
// ],
// 'labels' => $labels,
// ];
// }
protected function getData(): array
{
$rfqId = session('rfq_id');
if (!$rfqId) {
return [
'datasets' => [],
'labels' => [],
];
}
/**
* STEP 1: Get bids sorted by freight charge (for ranking)
*/
$rankedBids = RfqTransporterBid::query()
->where('request_quotation_id', $rfqId)
->orderByRaw('CAST(total_freight_charge AS DECIMAL(10,2)) ASC')
->get();
$rankMap = [];
$rank = 1;
foreach ($rankedBids as $bid) {
$rankMap[$bid->id] = $rank++;
}
/**
* STEP 2: Get bids in natural order (for wave effect)
* You can change orderBy to:
* - created_at
* - transporter_name
*/
$chartBids = RfqTransporterBid::query()
->where('request_quotation_id', $rfqId)
->orderBy('id')
->get();
$labels = [];
$amounts = [];
$colors = [];
$ranks = [];
foreach ($chartBids as $bid) {
$labels[] = $bid->transporter_name;
$amounts[] = (float) $bid->total_freight_charge;
$rank = $rankMap[$bid->id];
$ranks[] = $rank;
$colors[] = match ($rank) {
1 => '#FFD700',
2 => '#C0C0C0',
3 => '#CD7F32',
default => '#2563EB',
};
}
return [
'datasets' => [
[
'label' => 'Freight Charge',
'data' => $amounts,
'rankData' => $ranks,
'borderColor' => '#2563EB',
'backgroundColor' => $colors,
'pointBackgroundColor' => $colors,
'pointBorderColor' => '#000',
'pointRadius' => 7,
'pointHoverRadius' => 11,
'borderWidth' => 3,
'tension' => 0.45,
'fill' => false,
],
],
'labels' => $labels,
];
}
protected function getOptions(): array
{
return [
'plugins' => [
'datalabels' => [
'anchor' => 'start',
'align' => 'start',
'offset' => -15,
'color' => '#000',
'font' => [
'weight' => 'bold',
],
'formatter' => Js::from("function(value) { return Number(value); }"),
],
],
'scales' => [
'y' => [
'beginAtZero' => true,
'ticks' => [
'stepSize' => 0.5,
],
],
],
];
}
protected function getType(): string
{
return 'bar';
}
}

View File

@@ -1,236 +0,0 @@
<?php
namespace App\Livewire;
use App\Exports\ProductionPlanExport;
use App\Models\ProductionPlan;
use App\Models\ProductionQuantity;
use Livewire\Component;
use Carbon\Carbon;
use DB;
use Maatwebsite\Excel\Facades\Excel;
class ProductionTargetPlan extends Component
{
public $plantId, $lineId, $month, $year;
public $records = [];
public $dates = [];
public $leaveDates = [];
public $productionPlanDates = '';
protected $listeners = [
'loadData' => 'loadProductionData',
'loadData1' => 'exportProductionData',
];
public function getMonthDates($month, $year)
{
$start = Carbon::createFromDate($year, $month, 1);
$days = $start->daysInMonth;
$dates = [];
for ($i = 1; $i <= $days; $i++) {
$dates[] = Carbon::createFromDate($year, $month, $i)
->format('Y-m-d');
}
return $dates;
}
public function loadProductionData($plantId, $lineId, $month, $year){
if (!$plantId || !$lineId || !$month || !$year) {
$this->records = [];
$this->dates = [];
$this->leaveDates = [];
return;
}
$this->dates = $this->getMonthDates($month, $year);
$data = ProductionPlan::query()
->join('items', 'items.id', '=', 'production_plans.item_id')
->join('lines', 'lines.id', '=', 'production_plans.line_id')
->join('plants', 'plants.id', '=', 'production_plans.plant_id')
->where('production_plans.plant_id', $plantId)
->where('production_plans.line_id', $lineId)
->whereMonth('production_plans.created_at', $month)
->whereYear('production_plans.created_at', $year)
->select(
'production_plans.created_at',
'production_plans.operator_id',
'plants.name as plant',
'items.code as item_code',
'items.description as item_description',
'lines.name as line_name',
'production_plans.leave_dates'
)
->first();
if ($data && $data->leave_dates) {
$this->leaveDates = array_map('trim', explode(',', $data->leave_dates));
}
$producedData = ProductionQuantity::selectRaw("
plant_id,
line_id,
item_id,
DATE(created_at) as prod_date,
COUNT(*) as total_qty
")
->where('plant_id', $plantId)
->where('line_id', $lineId)
->whereMonth('created_at', $month)
->whereYear('created_at', $year)
->groupBy('plant_id', 'line_id', 'item_id', DB::raw('DATE(created_at)'))
->get()
->groupBy(function ($row) {
return $row->plant_id . '_' . $row->line_id . '_' . $row->item_id;
})
->map(function ($group) {
return $group->keyBy('prod_date');
});
$this->records = ProductionPlan::query()
->join('items', 'items.id', '=', 'production_plans.item_id')
->join('lines', 'lines.id', '=', 'production_plans.line_id')
->join('plants', 'plants.id', '=', 'production_plans.plant_id')
->where('production_plans.plant_id', $plantId)
->where('production_plans.line_id', $lineId)
->whereMonth('production_plans.created_at', $month)
->whereYear('production_plans.created_at', $year)
->select(
'production_plans.item_id',
'production_plans.plant_id',
'production_plans.line_id',
'production_plans.plan_quantity',
'production_plans.working_days',
'items.code as item_code',
'items.description as item_description',
'lines.name as line_name',
'plants.name as plant_name'
)
->get()
// ->map(function ($row) use ($producedData) {
// $row = $row->toArray();
// $row['daily_target'] = ($row['working_days'] > 0)
// ? round($row['plan_quantity'] / $row['working_days'], 2)
// : 0;
// // $key = $row['plant_id'].'_'.$row['line_id'].'_'.$row['item_id'];
// // foreach ($this->dates as $date) {
// // $found = $producedData[$key][$date] ?? null;
// // $row['produced_quantity'][$date] = $found->total_qty ?? 0;
// // }
// $remainingDays = $row['working_days'];
// $pendingQty = 0;
// $row['daily_target_dynamic'] = [];
// $row['produced_quantity'] = [];
// $key = $row['plant_id'].'_'.$row['line_id'].'_'.$row['item_id'];
// foreach ($this->dates as $date) {
// $found = $producedData[$key][$date] ?? null;
// $producedQty = $found->total_qty ?? 0;
// // today's adjusted target
// $todayTarget = $baseDailyTarget;
// if ($remainingDays > 1 && $pendingQty > 0) {
// $todayTarget += $pendingQty / $remainingDays;
// }
// $row['daily_target_dynamic'][$date] = round($todayTarget, 2);
// $row['produced_quantity'][$date] = $producedQty;
// // calculate today's shortfall
// $pendingQty += ($todayTarget - $producedQty);
// if ($pendingQty < 0) {
// $pendingQty = 0;
// }
// $remainingDays--;
// }
// return $row;
// })
->map(function ($row) use ($producedData) {
$row = $row->toArray();
$remainingQty = $row['plan_quantity'];
$remainingDays = $row['working_days'];
$row['daily_target_dynamic'] = [];
$row['produced_quantity'] = [];
$key = $row['plant_id'].'_'.$row['line_id'].'_'.$row['item_id'];
foreach ($this->dates as $date) {
// Skip leave dates
if (in_array($date, $this->leaveDates)) {
$row['daily_target_dynamic'][$date] = '-';
$row['produced_quantity'][$date] = '-';
continue;
}
$todayTarget = $remainingDays > 0
? round($remainingQty / $remainingDays, 2)
: 0;
//$todayTarget = $remainingDays > 0
// ? $remainingQty / $remainingDays
// : 0;
$producedQty = isset($producedData[$key][$date])
? $producedData[$key][$date]->total_qty
: 0;
$row['daily_target_dynamic'][$date] = $todayTarget;
$row['produced_quantity'][$date] = $producedQty;
// Carry forward pending
$remainingQty -= $producedQty;
if ($remainingQty < 0) {
$remainingQty = 0;
}
$remainingDays--;
}
return $row;
})
->toArray();
}
public function exportProductionData()
{
return Excel::download(
new ProductionPlanExport($this->records, $this->dates),
'production_plan_data.xlsx'
);
}
public function render()
{
// return view('livewire.production-target-plan');
return view('livewire.production-target-plan', [
'records' => $this->records,
'dates' => $this->dates,
]);
}
}

View File

@@ -12,13 +12,11 @@ class Item extends Model
protected $fillable = [
'plant_id',
'line_id',
'category',
'code',
'description',
'hourly_quantity',
'uom',
'line_capacity',
];
public function plant(): BelongsTo
@@ -26,11 +24,6 @@ class Item extends Model
return $this->belongsTo(Plant::class);
}
public function line(): BelongsTo
{
return $this->belongsTo(Line::class);
}
public function stickerMasters()
{
return $this->hasMany(StickerMaster::class, 'item_id', 'id');

View File

@@ -13,7 +13,6 @@ class Line extends Model
protected $fillable = [
"plant_id",
"block_id",
"name",
"type",
"group_work_center",
@@ -35,11 +34,6 @@ class Line extends Model
return $this->belongsTo(Plant::class);
}
public function block(): BelongsTo
{
return $this->belongsTo(Block::class);
}
public function testingPanelReadings()
{
return $this->hasMany(TestingPanelReading::class);

View File

@@ -12,15 +12,12 @@ class ProductionPlan extends Model
protected $fillable = [
"plant_id",
"item_id",
"shift_id",
"created_at",
"line_id",
"plan_quantity",
"production_quantity",
"operator_id",
"working_days",
"leave_dates",
];
public function plant(): BelongsTo
@@ -37,9 +34,4 @@ class ProductionPlan extends Model
{
return $this->belongsTo(Line::class);
}
public function item(): BelongsTo
{
return $this->belongsTo(Item::class);
}
}

View File

@@ -16,7 +16,6 @@ class ProductionQuantity extends Model
protected $fillable = [
"plant_id",
"machine_id",
"shift_id",
"line_id",
"item_id",
@@ -51,11 +50,6 @@ class ProductionQuantity extends Model
return $this->belongsTo(Item::class);
}
public function machine(): BelongsTo
{
return $this->belongsTo(Machine::class);
}
protected static function booted()
{
static::created(function ($productionQuantity) {

View File

@@ -1,46 +0,0 @@
<?php
namespace App\Models;
use Illuminate\Database\Eloquent\Model;
use Illuminate\Database\Eloquent\Relations\BelongsTo;
use Illuminate\Database\Eloquent\SoftDeletes;
class RequestQuotation extends Model
{
use SoftDeletes;
protected $fillable = [
'rfq_number',
'rfq_date_time',
'pickup_address',
'delivery_address',
'weight',
'volumetrice_size_inch',
'type_of_vehicle',
'special_type',
'no_of_vehicle',
'product_name',
'loading_by',
'unloading_by',
'pick_and_delivery',
'payment_term',
'paid_topay',
'require_date_time',
'transporter_name',
'total_freight_charge',
'transit_day',
'spot_rate_transport_master_id',
'created_at',
'updated_at',
'created_by',
'updated_by',
];
public function spotRateTransportMaster(): BelongsTo
{
return $this->belongsTo(SpotRateTransportMaster::class);
}
}

View File

@@ -1,30 +0,0 @@
<?php
namespace App\Models;
use Illuminate\Database\Eloquent\Model;
use Illuminate\Database\Eloquent\Relations\BelongsTo;
use Illuminate\Database\Eloquent\SoftDeletes;
use phpseclib3\Crypt\Common\Formats\Signature\Raw;
class RfqTransporterBid extends Model
{
use SoftDeletes;
protected $fillable = [
'request_quotation_id',
'transporter_name',
'total_freight_charge',
'transit_day',
'created_at',
'updated_at',
'created_by',
'updated_by',
];
public function requestQuotation(): BelongsTo
{
return $this->belongsTo(RequestQuotation::class);
// return $this->belongsTo(RequestQuotation::class, 'request_quotation_id');
}
}

View File

@@ -1,25 +0,0 @@
<?php
namespace App\Models;
use Illuminate\Database\Eloquent\Model;
use Illuminate\Database\Eloquent\Relations\BelongsTo;
use Illuminate\Database\Eloquent\SoftDeletes;
class SpotRateTransportMaster extends Model
{
use SoftDeletes;
protected $casts = [
'user_name' => 'array',
];
protected $fillable = [
'group_name',
'user_name',
'created_at',
'updated_at',
'created_by',
'updated_by',
];
}

View File

@@ -13,13 +13,11 @@ use Illuminate\Foundation\Auth\User as Authenticatable;
use Illuminate\Notifications\Notifiable;
use Spatie\Permission\Traits\HasRoles;
use Illuminate\Database\Eloquent\Relations\BelongsTo;
use NotificationChannels\WebPush\HasPushSubscriptions;
use NotificationChannels\WebPush\PushSubscription;
class User extends Authenticatable implements FilamentUser
{
/** @use HasFactory<\Database\Factories\UserFactory> */
use HasFactory, HasRoles, Notifiable, SoftDeletes, HasSuperAdmin, HasPushSubscriptions;
use HasFactory, HasRoles, Notifiable, SoftDeletes, HasSuperAdmin;
/**
* The attributes that are mass assignable.
@@ -65,9 +63,4 @@ class User extends Authenticatable implements FilamentUser
{
return $this->belongsTo(Plant::class);
}
public function pushSubscriptions()
{
return $this->morphMany(PushSubscription::class, 'subscribable');
}
}

View File

@@ -1,19 +0,0 @@
<?php
namespace App\Models;
use Illuminate\Database\Eloquent\Model;
class WebPushSubscription extends Model
{
protected $table = 'push_subscriptions';
protected $fillable = [
'subscribable_type',
'subscribable_id',
'endpoint',
'public_key',
'auth_token',
'content_encoding',
];
}

View File

@@ -1,108 +0,0 @@
<?php
namespace App\Notifications;
use Illuminate\Bus\Queueable;
use Illuminate\Contracts\Queue\ShouldQueue;
use Illuminate\Notifications\Messages\MailMessage;
use Illuminate\Notifications\Notification;
use NotificationChannels\WebPush\WebPushMessage;
use NotificationChannels\WebPush\WebPushChannel;
class PushAlertNotification extends Notification
{
use Queueable;
/**
* Create a new notification instance.
*/
// public function __construct()
// {
// //
// }
public $title;
public $body;
public function __construct($title, $body)
{
$this->title = $title;
$this->body = $body;
}
// public function via($notifiable)
// {
// return [WebPushChannel::class];
// }
public function via($notifiable)
{
return [
'database', // ✅ Filament toast
WebPushChannel::class // ✅ Browser / PWA push
];
}
public function toDatabase($notifiable): array
{
return [
'title' => $this->title,
'body' => $this->body,
];
}
// public function toWebPush($notifiable, $notification)
// {
// return (new WebPushMessage)
// ->title('New Alert 🚨')
// ->icon('/pwa-192x192.png')
// ->body('You have a new notification')
// ->action('Open App', 'open_app')
// ->data(['url' => '/admin']);
// }
public function toWebPush($notifiable, $notification)
{
return (new WebPushMessage)
->title($this->title)
->icon('/pwa-192x192.png')
->body($this->body)
->action('Open App', 'open_app')
->data(['url' => '/admin']);
}
/**
* Get the notification's delivery channels.
*
* @return array<int, string>
*/
// public function via(object $notifiable): array
// {
// return ['mail'];
// }
/**
* Get the mail representation of the notification.
*/
// public function toMail(object $notifiable): MailMessage
// {
// return (new MailMessage)
// ->line('The introduction to the notification.')
// ->action('Notification Action', url('/'))
// ->line('Thank you for using our application!');
// }
/**
* Get the array representation of the notification.
*
* @return array<string, mixed>
*/
public function toArray(object $notifiable): array
{
return [
//
];
}
}

View File

@@ -1,106 +0,0 @@
<?php
namespace App\Policies;
use Illuminate\Auth\Access\Response;
use App\Models\RequestQuotation;
use App\Models\User;
class RequestQuotationPolicy
{
/**
* Determine whether the user can view any models.
*/
public function viewAny(User $user): bool
{
return $user->checkPermissionTo('view-any RequestQuotation');
}
/**
* Determine whether the user can view the model.
*/
public function view(User $user, RequestQuotation $requestquotation): bool
{
return $user->checkPermissionTo('view RequestQuotation');
}
/**
* Determine whether the user can create models.
*/
public function create(User $user): bool
{
return $user->checkPermissionTo('create RequestQuotation');
}
/**
* Determine whether the user can update the model.
*/
public function update(User $user, RequestQuotation $requestquotation): bool
{
return $user->checkPermissionTo('update RequestQuotation');
}
/**
* Determine whether the user can delete the model.
*/
public function delete(User $user, RequestQuotation $requestquotation): bool
{
return $user->checkPermissionTo('delete RequestQuotation');
}
/**
* Determine whether the user can delete any models.
*/
public function deleteAny(User $user): bool
{
return $user->checkPermissionTo('delete-any RequestQuotation');
}
/**
* Determine whether the user can restore the model.
*/
public function restore(User $user, RequestQuotation $requestquotation): bool
{
return $user->checkPermissionTo('restore RequestQuotation');
}
/**
* Determine whether the user can restore any models.
*/
public function restoreAny(User $user): bool
{
return $user->checkPermissionTo('restore-any RequestQuotation');
}
/**
* Determine whether the user can replicate the model.
*/
public function replicate(User $user, RequestQuotation $requestquotation): bool
{
return $user->checkPermissionTo('replicate RequestQuotation');
}
/**
* Determine whether the user can reorder the models.
*/
public function reorder(User $user): bool
{
return $user->checkPermissionTo('reorder RequestQuotation');
}
/**
* Determine whether the user can permanently delete the model.
*/
public function forceDelete(User $user, RequestQuotation $requestquotation): bool
{
return $user->checkPermissionTo('force-delete RequestQuotation');
}
/**
* Determine whether the user can permanently delete any models.
*/
public function forceDeleteAny(User $user): bool
{
return $user->checkPermissionTo('force-delete-any RequestQuotation');
}
}

View File

@@ -1,106 +0,0 @@
<?php
namespace App\Policies;
use Illuminate\Auth\Access\Response;
use App\Models\RfqTransporterBid;
use App\Models\User;
class RfqTransporterBidPolicy
{
/**
* Determine whether the user can view any models.
*/
public function viewAny(User $user): bool
{
return $user->checkPermissionTo('view-any RfqTransporterBid');
}
/**
* Determine whether the user can view the model.
*/
public function view(User $user, RfqTransporterBid $rfqtransporterbid): bool
{
return $user->checkPermissionTo('view RfqTransporterBid');
}
/**
* Determine whether the user can create models.
*/
public function create(User $user): bool
{
return $user->checkPermissionTo('create RfqTransporterBid');
}
/**
* Determine whether the user can update the model.
*/
public function update(User $user, RfqTransporterBid $rfqtransporterbid): bool
{
return $user->checkPermissionTo('update RfqTransporterBid');
}
/**
* Determine whether the user can delete the model.
*/
public function delete(User $user, RfqTransporterBid $rfqtransporterbid): bool
{
return $user->checkPermissionTo('delete RfqTransporterBid');
}
/**
* Determine whether the user can delete any models.
*/
public function deleteAny(User $user): bool
{
return $user->checkPermissionTo('delete-any RfqTransporterBid');
}
/**
* Determine whether the user can restore the model.
*/
public function restore(User $user, RfqTransporterBid $rfqtransporterbid): bool
{
return $user->checkPermissionTo('restore RfqTransporterBid');
}
/**
* Determine whether the user can restore any models.
*/
public function restoreAny(User $user): bool
{
return $user->checkPermissionTo('restore-any RfqTransporterBid');
}
/**
* Determine whether the user can replicate the model.
*/
public function replicate(User $user, RfqTransporterBid $rfqtransporterbid): bool
{
return $user->checkPermissionTo('replicate RfqTransporterBid');
}
/**
* Determine whether the user can reorder the models.
*/
public function reorder(User $user): bool
{
return $user->checkPermissionTo('reorder RfqTransporterBid');
}
/**
* Determine whether the user can permanently delete the model.
*/
public function forceDelete(User $user, RfqTransporterBid $rfqtransporterbid): bool
{
return $user->checkPermissionTo('force-delete RfqTransporterBid');
}
/**
* Determine whether the user can permanently delete any models.
*/
public function forceDeleteAny(User $user): bool
{
return $user->checkPermissionTo('force-delete-any RfqTransporterBid');
}
}

View File

@@ -1,106 +0,0 @@
<?php
namespace App\Policies;
use Illuminate\Auth\Access\Response;
use App\Models\SpotRateTransportMaster;
use App\Models\User;
class SpotRateTransportMasterPolicy
{
/**
* Determine whether the user can view any models.
*/
public function viewAny(User $user): bool
{
return $user->checkPermissionTo('view-any SpotRateTransportMaster');
}
/**
* Determine whether the user can view the model.
*/
public function view(User $user, SpotRateTransportMaster $spotratetransportmaster): bool
{
return $user->checkPermissionTo('view SpotRateTransportMaster');
}
/**
* Determine whether the user can create models.
*/
public function create(User $user): bool
{
return $user->checkPermissionTo('create SpotRateTransportMaster');
}
/**
* Determine whether the user can update the model.
*/
public function update(User $user, SpotRateTransportMaster $spotratetransportmaster): bool
{
return $user->checkPermissionTo('update SpotRateTransportMaster');
}
/**
* Determine whether the user can delete the model.
*/
public function delete(User $user, SpotRateTransportMaster $spotratetransportmaster): bool
{
return $user->checkPermissionTo('delete SpotRateTransportMaster');
}
/**
* Determine whether the user can delete any models.
*/
public function deleteAny(User $user): bool
{
return $user->checkPermissionTo('delete-any SpotRateTransportMaster');
}
/**
* Determine whether the user can restore the model.
*/
public function restore(User $user, SpotRateTransportMaster $spotratetransportmaster): bool
{
return $user->checkPermissionTo('restore SpotRateTransportMaster');
}
/**
* Determine whether the user can restore any models.
*/
public function restoreAny(User $user): bool
{
return $user->checkPermissionTo('restore-any SpotRateTransportMaster');
}
/**
* Determine whether the user can replicate the model.
*/
public function replicate(User $user, SpotRateTransportMaster $spotratetransportmaster): bool
{
return $user->checkPermissionTo('replicate SpotRateTransportMaster');
}
/**
* Determine whether the user can reorder the models.
*/
public function reorder(User $user): bool
{
return $user->checkPermissionTo('reorder SpotRateTransportMaster');
}
/**
* Determine whether the user can permanently delete the model.
*/
public function forceDelete(User $user, SpotRateTransportMaster $spotratetransportmaster): bool
{
return $user->checkPermissionTo('force-delete SpotRateTransportMaster');
}
/**
* Determine whether the user can permanently delete any models.
*/
public function forceDeleteAny(User $user): bool
{
return $user->checkPermissionTo('force-delete-any SpotRateTransportMaster');
}
}

View File

@@ -1,106 +0,0 @@
<?php
namespace App\Policies;
use Illuminate\Auth\Access\Response;
use App\Models\StickerValidation;
use App\Models\User;
class StickerValidationPolicy
{
/**
* Determine whether the user can view any models.
*/
public function viewAny(User $user): bool
{
return $user->checkPermissionTo('view-any StickerValidation');
}
/**
* Determine whether the user can view the model.
*/
public function view(User $user, StickerValidation $stickervalidation): bool
{
return $user->checkPermissionTo('view StickerValidation');
}
/**
* Determine whether the user can create models.
*/
public function create(User $user): bool
{
return $user->checkPermissionTo('create StickerValidation');
}
/**
* Determine whether the user can update the model.
*/
public function update(User $user, StickerValidation $stickervalidation): bool
{
return $user->checkPermissionTo('update StickerValidation');
}
/**
* Determine whether the user can delete the model.
*/
public function delete(User $user, StickerValidation $stickervalidation): bool
{
return $user->checkPermissionTo('delete StickerValidation');
}
/**
* Determine whether the user can delete any models.
*/
public function deleteAny(User $user): bool
{
return $user->checkPermissionTo('delete-any StickerValidation');
}
/**
* Determine whether the user can restore the model.
*/
public function restore(User $user, StickerValidation $stickervalidation): bool
{
return $user->checkPermissionTo('restore StickerValidation');
}
/**
* Determine whether the user can restore any models.
*/
public function restoreAny(User $user): bool
{
return $user->checkPermissionTo('restore-any StickerValidation');
}
/**
* Determine whether the user can replicate the model.
*/
public function replicate(User $user, StickerValidation $stickervalidation): bool
{
return $user->checkPermissionTo('replicate StickerValidation');
}
/**
* Determine whether the user can reorder the models.
*/
public function reorder(User $user): bool
{
return $user->checkPermissionTo('reorder StickerValidation');
}
/**
* Determine whether the user can permanently delete the model.
*/
public function forceDelete(User $user, StickerValidation $stickervalidation): bool
{
return $user->checkPermissionTo('force-delete StickerValidation');
}
/**
* Determine whether the user can permanently delete any models.
*/
public function forceDeleteAny(User $user): bool
{
return $user->checkPermissionTo('force-delete-any StickerValidation');
}
}

View File

@@ -4,7 +4,6 @@ namespace App\Providers\Filament;
use Althinect\FilamentSpatieRolesPermissions\FilamentSpatieRolesPermissionsPlugin;
use App\Filament\Pages\InvoiceDashboard;
use App\Filament\Pages\NotificationSettings;
use Filament\Facades\Filament;
use Filament\Http\Middleware\Authenticate;
use Filament\Http\Middleware\AuthenticateSession;
@@ -60,7 +59,6 @@ class AdminPanelProvider extends PanelProvider
->discoverResources(in: app_path('Filament/Resources'), for: 'App\\Filament\\Resources')
->discoverPages(in: app_path('Filament/Pages'), for: 'App\\Filament\\Pages')
->pages([
])
->discoverWidgets(in: app_path('Filament/Widgets'), for: 'App\\Filament\\Widgets')
// ->widgets([
@@ -125,15 +123,6 @@ class AdminPanelProvider extends PanelProvider
public function boot(): void
{
FilamentView::registerRenderHook('panels::body.end', function () {
if (url()->current() == config('app.url') . '/admin') {
return '<script src="' . asset('js/push.js') . '"></script>';
}
return '';
});
FilamentView::registerRenderHook('panels::head.end', function () {
// Only inject on the "home" page (or specific route)
if (url()->current() == config('app.url') . '/admin') {

View File

@@ -11,11 +11,9 @@
"althinect/filament-spatie-roles-permissions": "^2.3",
"diogogpinto/filament-auth-ui-enhancer": "^1.0",
"erag/laravel-pwa": "^1.9",
"ffhs/filament-package_ffhs_approvals": "^1.0",
"filament/filament": "^3.3",
"intervention/image": "^3.11",
"irazasyed/telegram-bot-sdk": "^3.15",
"laravel-notification-channels/webpush": "^10.4",
"laravel/framework": "^11.31",
"laravel/sanctum": "^4.0",
"laravel/tinker": "^2.9",

477
composer.lock generated
View File

@@ -4,7 +4,7 @@
"Read more about it at https://getcomposer.org/doc/01-basic-usage.md#installing-dependencies",
"This file is @generated automatically"
],
"content-hash": "0e64d9b0a3c4d596ff8cd51b521c0565",
"content-hash": "69ede7e9877dd08efdeb795bfb6b7d29",
"packages": [
{
"name": "alperenersoy/filament-export",
@@ -1810,85 +1810,6 @@
},
"time": "2025-10-17T16:34:55+00:00"
},
{
"name": "ffhs/filament-package_ffhs_approvals",
"version": "1.0.1",
"source": {
"type": "git",
"url": "https://github.com/ffhs/filament-package_ffhs_approvals.git",
"reference": "712475522b63bf45a9e63a649d391cfe22132818"
},
"dist": {
"type": "zip",
"url": "https://api.github.com/repos/ffhs/filament-package_ffhs_approvals/zipball/712475522b63bf45a9e63a649d391cfe22132818",
"reference": "712475522b63bf45a9e63a649d391cfe22132818",
"shasum": ""
},
"require": {
"filament/filament": "^3.0",
"php": "^8.2",
"spatie/laravel-package-tools": "^1.15.0"
},
"require-dev": {
"larastan/larastan": "^3.0",
"laravel/pint": "^1.0",
"nunomaduro/collision": "^8.0",
"orchestra/testbench": "^9.9",
"pestphp/pest": "^3.7",
"pestphp/pest-plugin-arch": "^3.0",
"pestphp/pest-plugin-laravel": "^3.0",
"phpstan/extension-installer": "^1.1",
"phpstan/phpstan-deprecation-rules": "^2.0",
"phpstan/phpstan-phpunit": "^2.0",
"spatie/laravel-ray": "^1.26"
},
"type": "library",
"extra": {
"laravel": {
"aliases": {
"Approvals": "Ffhs\\Approvals\\Facades\\Approvals"
},
"providers": [
"Ffhs\\Approvals\\ApprovalsServiceProvider"
]
}
},
"autoload": {
"psr-4": {
"Ffhs\\Approvals\\": "src/",
"Ffhs\\Approvals\\Database\\Factories\\": "database/factories/"
}
},
"notification-url": "https://packagist.org/downloads/",
"license": [
"MIT"
],
"authors": [
{
"name": "Kromer Luc",
"email": "luc.kromer@ffhs.ch",
"role": "Developer"
},
{
"name": "Matthew Ballou",
"email": "mballou@kirschbaumdevelopment.com",
"role": "Developer"
}
],
"description": "This is my package filament-package_ffhs_approvals",
"homepage": "https://github.com/ffhs/filament-package_ffhs_approvals",
"keywords": [
"ffhs",
"filament-package_ffhs_approvals",
"kirschbaum-development",
"laravel"
],
"support": {
"issues": "https://github.com/ffhs/filament-package_ffhs_approvals/issues",
"source": "https://github.com/ffhs/filament-package_ffhs_approvals"
},
"time": "2025-07-24T14:32:41+00:00"
},
{
"name": "filament/actions",
"version": "v3.3.45",
@@ -3155,72 +3076,6 @@
},
"time": "2025-11-13T14:57:49+00:00"
},
{
"name": "laravel-notification-channels/webpush",
"version": "10.4.0",
"source": {
"type": "git",
"url": "https://github.com/laravel-notification-channels/webpush.git",
"reference": "a504bcbdd6258091b1fafdef6ca95b0891a47c9e"
},
"dist": {
"type": "zip",
"url": "https://api.github.com/repos/laravel-notification-channels/webpush/zipball/a504bcbdd6258091b1fafdef6ca95b0891a47c9e",
"reference": "a504bcbdd6258091b1fafdef6ca95b0891a47c9e",
"shasum": ""
},
"require": {
"illuminate/notifications": "^11.0|^12.0",
"illuminate/support": "^11.0|^12.0",
"minishlink/web-push": "^10.0",
"php": "^8.2"
},
"require-dev": {
"larastan/larastan": "^3.1",
"laravel/pint": "^1.25",
"mockery/mockery": "^1.0",
"orchestra/testbench": "^9.2|^10.0",
"phpunit/phpunit": "^10.5|^11.5.3",
"rector/rector": "^2.0"
},
"type": "library",
"extra": {
"laravel": {
"providers": [
"NotificationChannels\\WebPush\\WebPushServiceProvider"
]
}
},
"autoload": {
"psr-4": {
"NotificationChannels\\WebPush\\": "src"
}
},
"notification-url": "https://packagist.org/downloads/",
"license": [
"MIT"
],
"authors": [
{
"name": "Cretu Eusebiu",
"email": "me@cretueusebiu.com",
"homepage": "http://cretueusebiu.com",
"role": "Developer"
},
{
"name": "Joost de Bruijn",
"email": "joost@aqualabs.nl",
"role": "Maintainer"
}
],
"description": "Web Push Notifications driver for Laravel.",
"homepage": "https://github.com/laravel-notification-channels/webpush",
"support": {
"issues": "https://github.com/laravel-notification-channels/webpush/issues",
"source": "https://github.com/laravel-notification-channels/webpush/tree/10.4.0"
},
"time": "2025-12-19T15:47:27+00:00"
},
{
"name": "laravel/framework",
"version": "v11.46.1",
@@ -5025,73 +4880,6 @@
},
"time": "2019-10-05T02:44:33+00:00"
},
{
"name": "minishlink/web-push",
"version": "v10.0.1",
"source": {
"type": "git",
"url": "https://github.com/web-push-libs/web-push-php.git",
"reference": "08463189d3501cbd78a8625c87ab6680a7397aad"
},
"dist": {
"type": "zip",
"url": "https://api.github.com/repos/web-push-libs/web-push-php/zipball/08463189d3501cbd78a8625c87ab6680a7397aad",
"reference": "08463189d3501cbd78a8625c87ab6680a7397aad",
"shasum": ""
},
"require": {
"ext-curl": "*",
"ext-json": "*",
"ext-mbstring": "*",
"ext-openssl": "*",
"guzzlehttp/guzzle": "^7.9.2",
"php": ">=8.2",
"spomky-labs/base64url": "^2.0.4",
"web-token/jwt-library": "^3.4.9|^4.0.6"
},
"require-dev": {
"friendsofphp/php-cs-fixer": "^v3.91.3",
"phpstan/phpstan": "^2.1.33",
"phpstan/phpstan-strict-rules": "^2.0",
"phpunit/phpunit": "^11.5.46|^12.5.2",
"symfony/polyfill-iconv": "^1.33"
},
"suggest": {
"ext-bcmath": "Optional for performance.",
"ext-gmp": "Optional for performance."
},
"type": "library",
"autoload": {
"psr-4": {
"Minishlink\\WebPush\\": "src"
}
},
"notification-url": "https://packagist.org/downloads/",
"license": [
"MIT"
],
"authors": [
{
"name": "Louis Lagrange",
"email": "lagrange.louis@gmail.com",
"homepage": "https://github.com/Minishlink"
}
],
"description": "Web Push library for PHP",
"homepage": "https://github.com/web-push-libs/web-push-php",
"keywords": [
"Push API",
"WebPush",
"notifications",
"push",
"web"
],
"support": {
"issues": "https://github.com/web-push-libs/web-push-php/issues",
"source": "https://github.com/web-push-libs/web-push-php/tree/v10.0.1"
},
"time": "2025-12-15T10:04:28+00:00"
},
{
"name": "monolog/monolog",
"version": "3.9.0",
@@ -7908,180 +7696,6 @@
],
"time": "2025-09-24T06:40:28+00:00"
},
{
"name": "spomky-labs/base64url",
"version": "v2.0.4",
"source": {
"type": "git",
"url": "https://github.com/Spomky-Labs/base64url.git",
"reference": "7752ce931ec285da4ed1f4c5aa27e45e097be61d"
},
"dist": {
"type": "zip",
"url": "https://api.github.com/repos/Spomky-Labs/base64url/zipball/7752ce931ec285da4ed1f4c5aa27e45e097be61d",
"reference": "7752ce931ec285da4ed1f4c5aa27e45e097be61d",
"shasum": ""
},
"require": {
"php": ">=7.1"
},
"require-dev": {
"phpstan/extension-installer": "^1.0",
"phpstan/phpstan": "^0.11|^0.12",
"phpstan/phpstan-beberlei-assert": "^0.11|^0.12",
"phpstan/phpstan-deprecation-rules": "^0.11|^0.12",
"phpstan/phpstan-phpunit": "^0.11|^0.12",
"phpstan/phpstan-strict-rules": "^0.11|^0.12"
},
"type": "library",
"autoload": {
"psr-4": {
"Base64Url\\": "src/"
}
},
"notification-url": "https://packagist.org/downloads/",
"license": [
"MIT"
],
"authors": [
{
"name": "Florent Morselli",
"homepage": "https://github.com/Spomky-Labs/base64url/contributors"
}
],
"description": "Base 64 URL Safe Encoding/Decoding PHP Library",
"homepage": "https://github.com/Spomky-Labs/base64url",
"keywords": [
"base64",
"rfc4648",
"safe",
"url"
],
"support": {
"issues": "https://github.com/Spomky-Labs/base64url/issues",
"source": "https://github.com/Spomky-Labs/base64url/tree/v2.0.4"
},
"funding": [
{
"url": "https://github.com/Spomky",
"type": "github"
},
{
"url": "https://www.patreon.com/FlorentMorselli",
"type": "patreon"
}
],
"time": "2020-11-03T09:10:25+00:00"
},
{
"name": "spomky-labs/pki-framework",
"version": "1.4.1",
"source": {
"type": "git",
"url": "https://github.com/Spomky-Labs/pki-framework.git",
"reference": "f0e9a548df4e3942886adc9b7830581a46334631"
},
"dist": {
"type": "zip",
"url": "https://api.github.com/repos/Spomky-Labs/pki-framework/zipball/f0e9a548df4e3942886adc9b7830581a46334631",
"reference": "f0e9a548df4e3942886adc9b7830581a46334631",
"shasum": ""
},
"require": {
"brick/math": "^0.10|^0.11|^0.12|^0.13|^0.14",
"ext-mbstring": "*",
"php": ">=8.1"
},
"require-dev": {
"ekino/phpstan-banned-code": "^1.0|^2.0|^3.0",
"ext-gmp": "*",
"ext-openssl": "*",
"infection/infection": "^0.28|^0.29|^0.31",
"php-parallel-lint/php-parallel-lint": "^1.3",
"phpstan/extension-installer": "^1.3|^2.0",
"phpstan/phpstan": "^1.8|^2.0",
"phpstan/phpstan-deprecation-rules": "^1.0|^2.0",
"phpstan/phpstan-phpunit": "^1.1|^2.0",
"phpstan/phpstan-strict-rules": "^1.3|^2.0",
"phpunit/phpunit": "^10.1|^11.0|^12.0",
"rector/rector": "^1.0|^2.0",
"roave/security-advisories": "dev-latest",
"symfony/string": "^6.4|^7.0|^8.0",
"symfony/var-dumper": "^6.4|^7.0|^8.0",
"symplify/easy-coding-standard": "^12.0"
},
"suggest": {
"ext-bcmath": "For better performance (or GMP)",
"ext-gmp": "For better performance (or BCMath)",
"ext-openssl": "For OpenSSL based cyphering"
},
"type": "library",
"autoload": {
"psr-4": {
"SpomkyLabs\\Pki\\": "src/"
}
},
"notification-url": "https://packagist.org/downloads/",
"license": [
"MIT"
],
"authors": [
{
"name": "Joni Eskelinen",
"email": "jonieske@gmail.com",
"role": "Original developer"
},
{
"name": "Florent Morselli",
"email": "florent.morselli@spomky-labs.com",
"role": "Spomky-Labs PKI Framework developer"
}
],
"description": "A PHP framework for managing Public Key Infrastructures. It comprises X.509 public key certificates, attribute certificates, certification requests and certification path validation.",
"homepage": "https://github.com/spomky-labs/pki-framework",
"keywords": [
"DER",
"Private Key",
"ac",
"algorithm identifier",
"asn.1",
"asn1",
"attribute certificate",
"certificate",
"certification request",
"cryptography",
"csr",
"decrypt",
"ec",
"encrypt",
"pem",
"pkcs",
"public key",
"rsa",
"sign",
"signature",
"verify",
"x.509",
"x.690",
"x509",
"x690"
],
"support": {
"issues": "https://github.com/Spomky-Labs/pki-framework/issues",
"source": "https://github.com/Spomky-Labs/pki-framework/tree/1.4.1"
},
"funding": [
{
"url": "https://github.com/Spomky",
"type": "github"
},
{
"url": "https://www.patreon.com/FlorentMorselli",
"type": "patreon"
}
],
"time": "2025-12-20T12:57:40+00:00"
},
{
"name": "symfony/clock",
"version": "v7.3.0",
@@ -10890,95 +10504,6 @@
}
],
"time": "2024-11-21T01:49:47+00:00"
},
{
"name": "web-token/jwt-library",
"version": "4.1.3",
"source": {
"type": "git",
"url": "https://github.com/web-token/jwt-library.git",
"reference": "690d4dd47b78f423cb90457f858e4106e1deb728"
},
"dist": {
"type": "zip",
"url": "https://api.github.com/repos/web-token/jwt-library/zipball/690d4dd47b78f423cb90457f858e4106e1deb728",
"reference": "690d4dd47b78f423cb90457f858e4106e1deb728",
"shasum": ""
},
"require": {
"brick/math": "^0.12|^0.13|^0.14",
"php": ">=8.2",
"psr/clock": "^1.0",
"spomky-labs/pki-framework": "^1.2.1"
},
"conflict": {
"spomky-labs/jose": "*"
},
"suggest": {
"ext-bcmath": "GMP or BCMath is highly recommended to improve the library performance",
"ext-gmp": "GMP or BCMath is highly recommended to improve the library performance",
"ext-openssl": "For key management (creation, optimization, etc.) and some algorithms (AES, RSA, ECDSA, etc.)",
"ext-sodium": "Sodium is required for OKP key creation, EdDSA signature algorithm and ECDH-ES key encryption with OKP keys",
"paragonie/sodium_compat": "Sodium is required for OKP key creation, EdDSA signature algorithm and ECDH-ES key encryption with OKP keys",
"spomky-labs/aes-key-wrap": "For all Key Wrapping algorithms (AxxxKW, AxxxGCMKW, PBES2-HSxxx+AyyyKW...)",
"symfony/console": "Needed to use console commands",
"symfony/http-client": "To enable JKU/X5U support."
},
"type": "library",
"autoload": {
"psr-4": {
"Jose\\Component\\": ""
}
},
"notification-url": "https://packagist.org/downloads/",
"license": [
"MIT"
],
"authors": [
{
"name": "Florent Morselli",
"homepage": "https://github.com/Spomky"
},
{
"name": "All contributors",
"homepage": "https://github.com/web-token/jwt-framework/contributors"
}
],
"description": "JWT library",
"homepage": "https://github.com/web-token",
"keywords": [
"JOSE",
"JWE",
"JWK",
"JWKSet",
"JWS",
"Jot",
"RFC7515",
"RFC7516",
"RFC7517",
"RFC7518",
"RFC7519",
"RFC7520",
"bundle",
"jwa",
"jwt",
"symfony"
],
"support": {
"issues": "https://github.com/web-token/jwt-library/issues",
"source": "https://github.com/web-token/jwt-library/tree/4.1.3"
},
"funding": [
{
"url": "https://github.com/Spomky",
"type": "github"
},
{
"url": "https://www.patreon.com/FlorentMorselli",
"type": "patreon"
}
],
"time": "2025-12-18T14:27:35+00:00"
}
],
"packages-dev": [

View File

@@ -1,38 +0,0 @@
<?php
use Illuminate\Database\Migrations\Migration;
use Illuminate\Database\Schema\Blueprint;
use Illuminate\Support\Facades\Schema;
return new class extends Migration
{
/**
* Run the migrations.
*/
public function up(): void
{
$sql = <<<'SQL'
CREATE TABLE spot_rate_transport_masters (
id BIGINT GENERATED always AS IDENTITY PRIMARY KEY,
group_name TEXT NOT NULL,
user_name TEXT DEFAULT NULL,
created_at TIMESTAMP NOT NULL DEFAULT NOW(),
updated_at TIMESTAMP NOT NULL DEFAULT NOW(),
created_by TEXT DEFAULT NULL,
updated_by TEXT DEFAULT NULL,
deleted_at TIMESTAMP
);
SQL;
DB::statement($sql);
}
/**
* Reverse the migrations.
*/
public function down(): void
{
Schema::dropIfExists('spot_rate_transport_masters');
}
};

View File

@@ -1,60 +0,0 @@
<?php
use Illuminate\Database\Migrations\Migration;
use Illuminate\Database\Schema\Blueprint;
use Illuminate\Support\Facades\Schema;
return new class extends Migration
{
/**
* Run the migrations.
*/
public function up(): void
{
$sql = <<<'SQL'
CREATE TABLE request_quotations (
id BIGINT GENERATED always AS IDENTITY PRIMARY KEY,
spot_rate_transport_master_id BIGINT NOT NULL,
rfq_number TEXT NOT NULL,
rfq_date_time TIMESTAMP NOT NULL DEFAULT NOW(),
pickup_address TEXT NOT NULL,
delivery_address TEXT NOT NULL,
weight TEXT NOT NULL,
volumetrice_size_inch TEXT NOT NULL,
type_of_vehicle TEXT NOT NULL,
special_type TEXT NOT NULL,
no_of_vehicle TEXT NOT NULL,
product_name TEXT NOT NULL,
loading_by TEXT NOT NULL,
unloading_by TEXT NOT NULL,
pick_and_delivery TEXT NOT NULL,
payment_term TEXT NOT NULL,
paid_topay TEXT NOT NULL,
require_date_time TIMESTAMP NOT NULL DEFAULT NOW(),
rfq_rec_on_or_before TIMESTAMP NOT NULL DEFAULT NOW(),
transporter_name TEXT NULL,
total_freight_charge TEXT NULL,
transit_day TEXT NULL,
created_at TIMESTAMP NOT NULL DEFAULT NOW(),
updated_at TIMESTAMP NOT NULL DEFAULT NOW(),
created_by TEXT DEFAULT NULL,
updated_by TEXT DEFAULT NULL,
deleted_at TIMESTAMP,
FOREIGN KEY (spot_rate_transport_master_id) REFERENCES spot_rate_transport_masters (id)
);
SQL;
DB::statement($sql);
}
/**
* Reverse the migrations.
*/
public function down(): void
{
Schema::dropIfExists('request_quotations');
}
};

View File

@@ -1,44 +0,0 @@
<?php
use Illuminate\Database\Migrations\Migration;
use Illuminate\Database\Schema\Blueprint;
use Illuminate\Support\Facades\Schema;
return new class extends Migration
{
/**
* Run the migrations.
*/
public function up(): void
{
$sql = <<<'SQL'
CREATE TABLE rfq_transporter_bids (
id BIGINT GENERATED always AS IDENTITY PRIMARY KEY,
request_quotation_id BIGINT NOT NULL,
transporter_name TEXT NULL,
total_freight_charge TEXT NULL,
transit_day TEXT NULL,
created_at TIMESTAMP NOT NULL DEFAULT NOW(),
updated_at TIMESTAMP NOT NULL DEFAULT NOW(),
created_by TEXT DEFAULT NULL,
updated_by TEXT DEFAULT NULL,
deleted_at TIMESTAMP,
FOREIGN KEY (request_quotation_id) REFERENCES request_quotations(id)
);
SQL;
DB::statement($sql);
}
/**
* Reverse the migrations.
*/
public function down(): void
{
Schema::dropIfExists('rfq_transporter_bids');
}
};

View File

@@ -1,34 +0,0 @@
<?php
use Illuminate\Database\Migrations\Migration;
use Illuminate\Database\Schema\Blueprint;
use Illuminate\Support\Facades\Schema;
return new class extends Migration
{
/**
* Run the migrations.
*/
public function up(): void
{
$sql = <<<'SQL'
ALTER TABLE production_plans
ADD COLUMN item_id BIGINT DEFAULT NULL,
ADD CONSTRAINT production_plans_item_id_fkey
FOREIGN KEY (item_id) REFERENCES items(id);
SQL;
DB::statement($sql);
}
/**
* Reverse the migrations.
*/
public function down(): void
{
// Schema::table('production_plans', function (Blueprint $table) {
// //
// });
}
};

View File

@@ -1,33 +0,0 @@
<?php
use Illuminate\Database\Migrations\Migration;
use Illuminate\Database\Schema\Blueprint;
use Illuminate\Support\Facades\Schema;
return new class extends Migration
{
/**
* Run the migrations.
*/
public function up(): void
{
$sql = <<<'SQL'
ALTER TABLE lines
ADD COLUMN block_id BIGINT DEFAULT NULL,
ADD CONSTRAINT lines_block_id_fkey
FOREIGN KEY (block_id) REFERENCES blocks(id);
SQL;
DB::statement($sql);
}
/**
* Reverse the migrations.
*/
public function down(): void
{
// Schema::table('lines', function (Blueprint $table) {
// //
// });
}
};

View File

@@ -1,40 +0,0 @@
<?php
use Illuminate\Database\Migrations\Migration;
use Illuminate\Database\Schema\Blueprint;
use Illuminate\Support\Facades\Schema;
return new class extends Migration
{
/**
* Run the migrations.
*/
public function up(): void
{
$sql1 = <<<'SQL'
ALTER TABLE items
ADD COLUMN line_id BIGINT DEFAULT NULL,
ADD CONSTRAINT items_line_id_fkey
FOREIGN KEY (line_id) REFERENCES lines(id);
SQL;
DB::statement($sql1);
$sql2 = <<<'SQL'
ALTER TABLE items
ADD COLUMN line_capacity TEXT DEFAULT NULL
SQL;
DB::statement($sql2);
}
/**
* Reverse the migrations.
*/
public function down(): void
{
// Schema::table('items', function (Blueprint $table) {
// //
// });
}
};

View File

@@ -1,33 +0,0 @@
<?php
use Illuminate\Database\Migrations\Migration;
use Illuminate\Database\Schema\Blueprint;
use Illuminate\Support\Facades\Schema;
return new class extends Migration
{
/**
* Run the migrations.
*/
public function up(): void
{
$sql = <<<'SQL'
ALTER TABLE production_quantities
ADD COLUMN machine_id BIGINT DEFAULT NULL,
ADD CONSTRAINT production_quantities_machine_id_fkey
FOREIGN KEY (machine_id) REFERENCES machines(id);
SQL;
DB::statement($sql);
}
/**
* Reverse the migrations.
*/
public function down(): void
{
// Schema::table('production_quantities', function (Blueprint $table) {
// //
// });
}
};

View File

@@ -1,31 +0,0 @@
<?php
use Illuminate\Database\Migrations\Migration;
use Illuminate\Database\Schema\Blueprint;
use Illuminate\Support\Facades\Schema;
return new class extends Migration
{
/**
* Run the migrations.
*/
public function up(): void
{
$sql1 = <<<'SQL'
ALTER TABLE production_plans
ADD COLUMN working_days TEXT DEFAULT NULL
SQL;
DB::statement($sql1);
}
/**
* Reverse the migrations.
*/
public function down(): void
{
// Schema::table('production_plans', function (Blueprint $table) {
// //
// });
}
};

View File

@@ -1,31 +0,0 @@
<?php
use Illuminate\Database\Migrations\Migration;
use Illuminate\Database\Schema\Blueprint;
use Illuminate\Support\Facades\Schema;
return new class extends Migration
{
/**
* Run the migrations.
*/
public function up(): void
{
$sql1 = <<<'SQL'
ALTER TABLE production_plans
ADD COLUMN leave_dates TEXT DEFAULT NULL
SQL;
DB::statement($sql1);
}
/**
* Reverse the migrations.
*/
public function down(): void
{
// Schema::table('production_plans', function (Blueprint $table) {
// //
// });
}
};

View File

@@ -1,113 +0,0 @@
// async function registerPush() {
// try {
// console.log("Registering for push notifications");
// if (!('serviceWorker' in navigator)) {
// console.error("ServiceWorker not supported");
// return;
// }
// const permission = await Notification.requestPermission();
// console.log("Permission:", permission);
// if (permission !== 'granted') {
// console.warn("Notification permission denied");
// return;
// }
// const registration = await navigator.serviceWorker.register('/sw.js');
// console.log("SW registered:", registration);
// // const subscription = await registration.pushManager.subscribe({
// // userVisibleOnly: true,
// // applicationServerKey: vapidKey
// // });
// const subscription = await registration.pushManager.subscribe({
// userVisibleOnly: true,
// applicationServerKey: urlBase64ToUint8Array(vapidKey),
// });
// console.log('VAPID key:', vapidKey);
// console.log("Subscription created:", subscription);
// const res = await fetch('/push/subscribe', {
// method: 'POST',
// headers: {
// 'Content-Type': 'application/json',
// 'X-CSRF-TOKEN': csrfToken
// },
// body: JSON.stringify(subscription)
// });
// console.log("Server response:", await res.text());
// alert("Push enabled ✅");
// } catch (e) {
// console.error("Push registration failed ❌", e);
// }
// }
async function registerPush() {
try {
console.log("Registering for push notifications");
if (!('serviceWorker' in navigator)) {
console.error("ServiceWorker not supported");
return;
}
const permission = await Notification.requestPermission();
if (permission !== 'granted') {
console.warn("Notification permission denied");
return;
}
const registration = await navigator.serviceWorker.register('/sw.js');
// ✅ GET first
let subscription = await registration.pushManager.getSubscription();
// ✅ CREATE only if not exists
if (!subscription) {
subscription = await registration.pushManager.subscribe({
userVisibleOnly: true,
applicationServerKey: urlBase64ToUint8Array(vapidKey),
});
console.log("New subscription created");
} else {
console.log("Existing subscription reused");
}
// 🔥 ALWAYS send to backend
await fetch('/push/subscribe', {
method: 'POST',
headers: {
'Content-Type': 'application/json',
'X-CSRF-TOKEN': csrfToken
},
body: JSON.stringify(subscription)
});
alert("Push enabled ✅");
} catch (e) {
console.error("Push registration failed ❌", e);
}
}
function urlBase64ToUint8Array(base64String) {
const padding = '='.repeat((4 - base64String.length % 4) % 4);
const base64 = (base64String + padding)
.replace(/-/g, '+')
.replace(/_/g, '/');
const rawData = window.atob(base64);
const outputArray = new Uint8Array(rawData.length);
for (let i = 0; i < rawData.length; ++i) {
outputArray[i] = rawData.charCodeAt(i);
}
return outputArray;
}

View File

@@ -1,8 +1,5 @@
let deferredPrompt;
/* -----------------------------
ANDROID / CHROME INSTALL FLOW
------------------------------*/
window.addEventListener("beforeinstallprompt", (e) => {
e.preventDefault();
deferredPrompt = e;
@@ -10,55 +7,6 @@ window.addEventListener("beforeinstallprompt", (e) => {
// Prevent duplicate banner
if (document.getElementById("install-banner")) return;
showInstallBanner({
message: '📱 Install <b>Quality</b> App?',
buttonText: 'Install',
onClick: async () => {
deferredPrompt.prompt();
const { outcome } = await deferredPrompt.userChoice;
console.log("User install choice:", outcome);
deferredPrompt = null;
}
});
});
// /* -----------------------------
// IOS SAFARI MANUAL INSTALL
// ------------------------------*/
// function isIosSafari() {
// return (
// /iP(ad|hone|od)/.test(navigator.userAgent) &&
// /Safari/.test(navigator.userAgent) &&
// !/CriOS|FxiOS|OPiOS/.test(navigator.userAgent)
// );
// }
// function isInStandaloneMode() {
// return window.navigator.standalone == true;
// }
// document.addEventListener("DOMContentLoaded", () => {
// if (
// isIosSafari() &&
// !isInStandaloneMode() &&
// !localStorage.getItem("iosInstallShown")
// ) {
// showInstallBanner({
// message: '📱 Install <b>Quality</b> App<br><small>Tap Share ⬆️ → Add to Home Screen</small>',
// buttonText: 'Got it',
// onClick: () => {
// localStorage.setItem("iosInstallShown", "1");
// }
// });
// }
// });
/* -----------------------------
COMMON INSTALL BANNER UI
------------------------------*/
function showInstallBanner({ message, buttonText, onClick }) {
if (document.getElementById("install-banner")) return;
const banner = document.createElement("div");
banner.id = "install-banner";
banner.innerHTML = `
@@ -76,7 +24,7 @@ function showInstallBanner({ message, buttonText, onClick }) {
box-shadow: 0 4px 10px rgba(0,0,0,0.3);
z-index: 99999;
">
<span style="font-size: 16px;">${message}</span><br>
<span style="font-size: 16px;">📱 Install <b>Quality</b> App?</span><br>
<button id="installBtn" style="
margin-top: 10px;
background: white;
@@ -86,22 +34,22 @@ function showInstallBanner({ message, buttonText, onClick }) {
border-radius: 6px;
font-weight: 600;
cursor: pointer;
">${buttonText}</button>
">Install</button>
</div>
`;
document.body.appendChild(banner);
document.getElementById("installBtn").addEventListener("click", () => {
document.getElementById("installBtn").addEventListener("click", async () => {
banner.remove();
onClick();
deferredPrompt.prompt();
const { outcome } = await deferredPrompt.userChoice;
console.log("User install choice:", outcome);
deferredPrompt = null;
});
}
});
/* -----------------------------
APP INSTALLED EVENT
------------------------------*/
window.addEventListener("appinstalled", () => {
console.log("🎉 App installed successfully!");
console.log("🎉 PDS installed successfully!");
const banner = document.getElementById("install-banner");
if (banner) banner.remove();
});

Binary file not shown.

Before

Width:  |  Height:  |  Size: 9.4 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 9.4 KiB

View File

@@ -1,12 +1,11 @@
{
"name": "QDS",
"short_name": "qds",
"name": "Laravel PWA",
"short_name": "LPT",
"background_color": "#6777ef",
"display": "standalone",
"description": "A Progressive Web Application setup for Laravel projects.",
"theme_color": "#6777ef",
"gcm_sender_id": "103953800507",
"start_url": "/admin",
"start_url": "/",
"icons": [
{
"src": "/logo-192.png",

View File

@@ -1,20 +0,0 @@
self.addEventListener('push', function (event) {
console.log('[SW] Push received');
let payload = {};
if (event.data) {
payload = event.data.json();
}
const title = payload.title || 'New Notification';
const options = {
body: payload.body || '',
icon: payload.icon || '/pwa-192x192.png',
data: payload.data || {},
};
event.waitUntil(
self.registration.showNotification(title, options)
);
});

View File

@@ -1,71 +0,0 @@
<x-filament-panels::page>
{{-- <button
type="button"
class="filament-button filament-button-primary"
onclick="registerPush()"
>
Enable Push Notifications
</button> --}}
<div class="max-w-md mx-auto">
<x-filament::card>
<div class="text-center space-y-4">
<h2 class="text-xl font-semibold">
🔔 Stay Updated
</h2>
<p class="text-sm text-gray-500">
Enable push notifications to receive real-time alerts and updates.
</p>
<button
type="button"
onclick="registerPush()"
class="
filament-button
filament-button-primary
w-full
flex items-center justify-center gap-2
py-3
rounded-lg
shadow-sm
hover:shadow-md
transition
"
>
<x-heroicon-o-bell class="w-5 h-5"/>
<span class="font-medium">Enable Push Notifications</span>
</button>
</div>
</x-filament::card>
</div>
<script>
const vapidKey = "{{ config('webpush.vapid.public_key') }}";
const csrfToken = "{{ csrf_token() }}";
async function registerPush() {
if (!('serviceWorker' in navigator)) return;
const permission = await Notification.requestPermission();
if (permission != 'granted') return;
const registration = await navigator.serviceWorker.register('/service-worker.js');
const subscription = await registration.pushManager.subscribe({
userVisibleOnly: true,
applicationServerKey: vapidKey
});
await fetch('/push/subscribe', {
method: 'POST',
headers: {
'Content-Type': 'application/json',
'X-CSRF-TOKEN': csrfToken
},
body: JSON.stringify(subscription)
});
alert("Push notifications enabled ✅");
}
</script>
</x-filament-panels::page>

View File

@@ -1,13 +0,0 @@
<x-filament-panels::page>
<div class="space-y-4">
{{-- Render the Select form fields --}}
<div class="space-y-4">
{{ $this->form }}
</div>
</div>
</x-filament-panels::page>

View File

@@ -45,7 +45,7 @@
</div> --}}
<div class="flex gap-6 -mt-6">
<!-- Scan QR Code -->
<div class="w-full">
<div class="w-1/2">
<label for="qr-scan-input" class="block text-sm font-medium text-gray-700 mb-2">
SCAN QR CODE
</label>
@@ -60,7 +60,7 @@
</div>
<!-- Last Scanned QR -->
{{-- <div class="w-1/2">
<div class="w-1/2">
<label for="recent-qr-input" class="block text-sm font-medium text-gray-700 mb-2">
LAST SCANNED QR
</label>
@@ -71,7 +71,7 @@
readonly
wire:model="recent_qr"
/>
</div> --}}
</div>
</div>

View File

@@ -1,19 +0,0 @@
<x-filament-panels::page>
<div class="space-y-4">
{{-- Render the Select form fields --}}
<div class="space-y-4">
{{ $this->form }}
</div>
<x-filament::button
wire:click="export"
color="primary"
class="mt-4"
>
Export
</x-filament::button>
<div class="bg-white shadow rounded-xl p-4 mt-6">
<livewire:production-target-plan />
</div>
</div>
</x-filament-panels::page>

View File

@@ -1,14 +0,0 @@
<x-filament-panels::page>
<div class="space-y-4">
{{-- Render the Select form fields --}}
<div class="space-y-4">
{{ $this->filtersForm($this->form) }}
{{-- {{ $this->form }} --}}
</div>
{{-- Render the chart widget below the form --}}
<div class="mt-6">
@livewire(\App\Filament\Widgets\RfqChart::class)
</div>
</div>
</x-filament-panels::page>

View File

@@ -1,14 +0,0 @@
<x-filament-panels::page>
<div class="space-y-4">
{{-- Render the Select form fields --}}
<div class="space-y-4">
{{ $this->filtersForm($this->form) }}
{{-- {{ $this->form }} --}}
</div>
{{-- Render the chart widget below the form --}}
<div class="mt-6">
@livewire(\App\Filament\Widgets\RfqRankChart::class)
</div>
</div>
</x-filament-panels::page>

View File

@@ -1,19 +0,0 @@
<x-filament-panels::page>
<h1 class="text-3xl font-bold mb-6">Welcome to CRI Digital Manufacturing IIOT</h1>
<div class="w-full overflow-hidden rounded-xl shadow">
<img
src="{{ asset('images/iiot-banner.jpg') }}"
alt="CRI Digital Manufacturing IIoT"
class="w-full h-64 object-cover"
>
</div>
<p class="text-lg text-gray-600 mb-6">
This dashboard provides real-time visibility into your manufacturing operations,
enabling you to monitor production, track performance, and make data-driven decisions
across plants and lines—all from one centralized platform.
</p>
</x-filament-panels::page>

View File

@@ -37,7 +37,7 @@ document.addEventListener('livewire:init', () => {
});
</script> --}}
{{-- <script>
<script>
document.addEventListener('DOMContentLoaded', () => {
window.addEventListener('open-stickers-sequence', (event) => {
console.log('EVENT RECEIVED');
@@ -47,23 +47,5 @@ document.addEventListener('DOMContentLoaded', () => {
});
});
});
</script> --}}
<script>
window.addEventListener('open-stickers-sequence', async (event) => {
const urls = event.detail.urls;
for (const url of urls) {
const win = window.open(url, '_blank');
win.onload = () => {
win.focus();
win.print();
};
// wait before next
await new Promise(r => setTimeout(r, 1500));
}
});
</script>

View File

@@ -1,151 +0,0 @@
<!-- <select id="yearSelect">
<option value="">Select Year</option>
</select> -->
<div id="calendar" wire:ignore></div>
<!-- <input type="text" name="working_days" placeholder="Working Days"> -->
<link href="https://cdn.jsdelivr.net/npm/fullcalendar@6.1.8/index.global.min.css" rel="stylesheet">
<script src="https://cdn.jsdelivr.net/npm/fullcalendar@6.1.8/index.global.min.js"></script>
<script>
document.addEventListener('DOMContentLoaded', function () {
let selectedDates = [];
let calendarEl = document.getElementById('calendar');
var calendar = new FullCalendar.Calendar(calendarEl, {
initialView: 'dayGridMonth',
height: 600,
showNonCurrentDates: true,
datesSet: function(info) {
// Clear previous month selections
selectedDates = [];
// Remove background events
calendar.removeAllEvents();
// Recalculate working days for new month
updateWorkingDays(info.view.currentStart);
},
dateClick: function(info) {
let viewMonth = calendar.view.currentStart.getMonth();
let clickedMonth = info.date.getMonth();
if (viewMonth != clickedMonth) return;
let dateStr = info.dateStr;
if (selectedDates.includes(dateStr)) {
selectedDates = selectedDates.filter(d => d !== dateStr);
calendar.getEvents().forEach(event => {
if (event.startStr == dateStr) event.remove();
});
} else {
selectedDates.push(dateStr);
calendar.addEvent({
start: dateStr,
display: 'background',
color: '#f03f17'
});
}
updateWorkingDays(info.date);
}
});
// var calendar = new FullCalendar.Calendar(calendarEl, {
// initialView: 'dayGridMonth',
// height: 600,
// showNonCurrentDates: true,
// dateClick: function(info) {
// let viewMonth = calendar.view.currentStart.getMonth();
// let clickedMonth = info.date.getMonth();
// // let month = info.date.getMonth() + 1; // JS month: 0-11 → 1-12
// // let year = info.date.getFullYear();
// if (viewMonth != clickedMonth) {
// return; // Ignore next/prev month dates
// }
// let dateStr = info.dateStr;
// if (selectedDates.includes(dateStr)) {
// selectedDates = selectedDates.filter(d => d !== dateStr);
// calendar.getEvents().forEach(event => {
// if (event.startStr == dateStr) {
// event.remove();
// }
// });
// } else {
// selectedDates.push(dateStr);
// calendar.addEvent({
// start: dateStr,
// display: 'background',
// color: '#f03f17'
// });
// }
// updateWorkingDays(info.date);
// }
// });
// yearSelect.addEventListener('change', function () {
// let year = this.value;
// if (!year) return;
// let currentDate = calendar.getDate();
// let newDate = new Date(year, currentDate.getMonth(), 1);
// calendar.gotoDate(newDate);
// });
function updateWorkingDays(date) {
let totalDays = new Date(
date.getFullYear(),
date.getMonth()+1,
0
).getDate();
let workingDays = totalDays - selectedDates.length;
// document.querySelector('input[name="working_days"]').value = workingDays;
const input = document.querySelector('#working_days');
input.value = workingDays;
input.dispatchEvent(new Event('input'));
const monthInput = document.querySelector('#month');
monthInput.value = date.getMonth() + 1; // 112 month number
monthInput.dispatchEvent(new Event('input'));
const yearInput = document.querySelector('#year');
yearInput.value = date.getFullYear();
yearInput.dispatchEvent(new Event('input'));
const selectedDatesInput = document.querySelector('#selected_dates');
selectedDatesInput.value = selectedDates.join(',');
selectedDatesInput.dispatchEvent(new Event('input'));
}
calendar.render();
});
</script>

View File

@@ -1,9 +0,0 @@
<div class="flex space-x-2 items-center">
<button
type="button"
class="inline-flex items-center px-3 py-1 bg-primary-600 text-white rounded hover:bg-primary-700"
wire:click="saveWorkingDays"
>
Save
</button>
</div>

View File

@@ -1,85 +0,0 @@
<div class="p-4">
<h2 class="text-lg font-bold mb-4 text-gray-700 uppercase tracking-wider">
PRODUCTION PLAN TABLE:
</h2>
<div class="overflow-x-auto rounded-lg shadow">
<table class="w-full divide-y divide-gray-200 text-sm text-center">
{{-- <thead class="bg-gray-100 text-s font-semibold uppercase text-gray-700">
<tr>
<th class="border px-4 py-2">No</th>
<th class="border px-4 py-2">Created Datetime</th>
<th class="border px-4 py-2 whitespace-nowrap">Created By</th>
<th class="border px-4 py-2 whitespace-nowrap">Plant</th>
<th class="border px-4 py-2">Line</th>
<th class="border px-4 py-2 whitespace-nowrap">Item Code</th>
<th class="border px-4 py-2">Production Plan Dates</th>
</tr>
</thead> --}}
<thead class="bg-gray-100 text-s font-semibold uppercase text-gray-700">
<tr>
<th class="border px-4 py-2" rowspan="3">No</th>
<th class="border px-4 py-2 whitespace-nowrap" rowspan="3">Plant</th>
<th class="border px-4 py-2 whitespace-nowrap" rowspan="3">Line</th>
<th class="border px-4 py-2 whitespace-nowrap" rowspan="3">Item Code</th>
<th class="border px-4 py-2 whitespace-nowrap" colspan="{{ count($dates) * 2 }}" class="text-center">
Production Plan Dates
</th>
</tr>
<tr>
@foreach($dates as $date)
<th colspan="2" class="text-center">
{{ $date }}
</th>
@endforeach
</tr>
<tr>
@foreach($dates as $date)
<th class="border px-4 py-2 whitespace-nowrap">Target Plan</th>
<th class="border px-4 py-2 whitespace-nowrap">Produced Quantity</th>
@endforeach
</tr>
</thead>
<tbody class="divide-y divide-gray-100">
@forelse ($records as $index => $record)
<tr class="hover:bg-gray-50">
<td class="border px-4 py-2">{{ $index + 1 }}</td>
<td class="border px-4 py-2 whitespace-nowrap">{{ $record['plant_name'] }}</td>
<td class="border px-4 py-2 whitespace-nowrap">{{ $record['line_name'] }}</td>
<td class="border px-4 py-2 whitespace-nowrap">{{ $record['item_code'] }}</td>
{{-- @foreach($dates as $date)
<td class="border px-4 py-2 whitespace-nowrap">{{ $record['target_plan'][$date] ?? '-' }}</td>
<td class="border px-4 py-2 whitespace-nowrap">{{ $record['production_plan'][$date] ?? '-' }}</td>
@endforeach --}}
@foreach($dates as $date)
@if(in_array($date, $leaveDates))
<td class="border px-4 py-2 whitespace-nowrap">-</td>
<td class="border px-4 py-2 whitespace-nowrap">-</td>
@else
{{-- <td class="border px-4 py-2 whitespace-nowrap">{{ $record['daily_target'] ?? '-' }}</td> --}}
<td class="border px-4 py-2 whitespace-nowrap">
{{ $record['daily_target_dynamic'][$date] ?? '-' }}
</td>
<td class="border px-4 py-2 whitespace-nowrap">
{{ $record['produced_quantity'][$date] ?? '-' }}
</td>
{{-- <td class="border px-4 py-2 whitespace-nowrap">{{ $record['produced_quantity'] ?? '-' }}</td> --}}
@endif
@endforeach
</tr>
@empty
<tr>
<td colspan="9" class="px-4 py-4 text-center text-gray-500">
No production plan data found.
</td>
</tr>
@endforelse
</tbody>
</table>
</div>
</div>

View File

@@ -25,15 +25,12 @@ use App\Http\Controllers\ObdController;
use App\Http\Controllers\PalletController;
use App\Http\Controllers\PdfController;
use App\Http\Controllers\PlantController;
use App\Http\Controllers\PrintController;
use App\Http\Controllers\ProductionStickerReprintController;
use App\Http\Controllers\SapFileController;
use App\Http\Controllers\StickerMasterController;
// use App\Http\Controllers\TelegramController;
use App\Http\Controllers\TestingPanelController;
use App\Http\Controllers\UserController;
use App\Models\WebPushSubscription;
use Filament\Facades\Filament;
use Illuminate\Foundation\Http\Middleware\VerifyCsrfToken;
use Illuminate\Http\Request;
use Illuminate\Support\Facades\Route;
@@ -188,46 +185,3 @@ Route::post('file/store', [SapFileController::class, 'store'])->name('file.store
// Route::post('send-telegram', [TelegramController::class, 'sendMessage']);
// Route::post('invoice-exit', [InvoiceValidationController::class, 'handle']);
Route::post('/print-pdf', [PrintController::class, 'print']);
Route::post('/push/subscribe', function (Request $request) {
$user = Filament::auth()->user();
abort_if(!$user, 401);
$request->validate([
'endpoint' => 'required|string',
'keys.p256dh' => 'required|string',
'keys.auth' => 'required|string',
]);
// WebPushSubscription::updateOrCreate(
// ['endpoint' => $request->endpoint],
// [
// 'subscribable_type' => get_class($user),
// 'subscribable_id' => $user->id,
// 'public_key' => $request->keys['p256dh'],
// 'auth_token' => $request->keys['auth'],
// 'content_encoding' => $request->contentEncoding ?? 'aesgcm',
// ]
// );
WebPushSubscription::updateOrCreate(
[
'endpoint' => $request->endpoint,
'subscribable_type' => get_class($user),
'subscribable_id' => $user->id,
],
[
'public_key' => $request->keys['p256dh'],
'auth_token' => $request->keys['auth'],
'content_encoding' => $request->contentEncoding ?? 'aesgcm',
]
);
return response()->json(['success' => true]);
});

View File

@@ -6,7 +6,6 @@ use App\Models\EquipmentMaster;
use App\Models\InvoiceValidation;
use App\Models\Plant;
use App\Models\User;
use App\Models\WebPushSubscription;
use Filament\Facades\Filament;
use Illuminate\Support\Facades\Mail;
use Illuminate\Support\Facades\Route;
@@ -18,75 +17,6 @@ use App\Http\Livewire\CustomLogin;
return redirect('/admin');
});
// Route::get('/admin', function () {
// return redirect('/admin/welcome');
// });
// Route::post('/push/subscribe', function (Request $request) {
// $request->user()->updatePushSubscription(
// $request->endpoint,
// $request->keys['p256dh'],
// $request->keys['auth']
// );
// return response()->json(['success' => true]);
// })->middleware('auth');
// Route::post('/push/subscribe', function (Request $request) {
// $user = Filament::auth()->user();
// abort_if(!$user, 401);
// $user->updatePushSubscription(
// $request->endpoint,
// $request->keys['p256dh'],
// $request->keys['auth'],
// $request->contentEncoding ?? 'aesgcm'
// );
// return response()->json(['success' => true]);
// });
Route::post('/push/subscribe', function (Request $request) {
$user = Filament::auth()->user();
abort_if(!$user, 401);
$request->validate([
'endpoint' => 'required|string',
'keys.p256dh' => 'required|string',
'keys.auth' => 'required|string',
]);
WebPushSubscription::updateOrCreate(
['endpoint' => $request->endpoint],
[
'subscribable_type' => get_class($user),
'subscribable_id' => $user->id,
'public_key' => $request->keys['p256dh'],
'auth_token' => $request->keys['auth'],
'content_encoding' => $request->contentEncoding ?? 'aesgcm',
]
);
// WebPushSubscription::updateOrCreate(
// [
// 'endpoint' => $request->endpoint,
// 'subscribable_type' => get_class($user),
// 'subscribable_id' => $user->id,
// ],
// [
// 'public_key' => $request->keys['p256dh'],
// 'auth_token' => $request->keys['auth'],
// 'content_encoding' => $request->contentEncoding ?? 'aesgcm',
// ]
// );
return response()->json(['success' => true]);
});
// routes/web.php
Route::post('/save-serials-to-session', function (Request $request) {
session(['serial_numbers' => $request->serial_numbers]);