89 Commits

Author SHA1 Message Date
2bc8584e7a Update .github/workflows/gemini-pr-review.yaml
Some checks failed
Scan for leaked secrets using Kingfisher / kingfisher-secrets-scan (push) Successful in 11s
Scan for leaked secrets using Kingfisher / kingfisher-secrets-scan (pull_request) Successful in 10s
Gemini PR Review / review (pull_request) Successful in 29s
Laravel Pint / pint (pull_request) Has been cancelled
Laravel Larastan / larastan (pull_request) Has been cancelled
2025-12-02 10:55:46 +00:00
d126e931c8 Merge pull request 'decreased font size of the sticker printing table' (#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-02 03:05:34 +00:00
dhanabalan
e525e3c526 decreased font size of the sticker printing table
Some checks failed
Scan for leaked secrets using Kingfisher / kingfisher-secrets-scan (push) Successful in 10s
Scan for leaked secrets using Kingfisher / kingfisher-secrets-scan (pull_request) Successful in 10s
Gemini PR Review / review (pull_request) Failing after 38s
Laravel Larastan / larastan (pull_request) Failing after 2m18s
Laravel Pint / pint (pull_request) Has been cancelled
2025-12-02 08:35:17 +05:30
62bf68ad2e Merge pull request 'corrected logic in sticker printing page' (#55) from ranjith-dev into master
All checks were successful
Scan for leaked secrets using Kingfisher / kingfisher-secrets-scan (push) Successful in 10s
Reviewed-on: #55
2025-12-02 02:54:47 +00:00
dhanabalan
caf2f3c1e7 corrected logic in sticker printing page
Some checks failed
Scan for leaked secrets using Kingfisher / kingfisher-secrets-scan (push) Successful in 11s
Scan for leaked secrets using Kingfisher / kingfisher-secrets-scan (pull_request) Successful in 11s
Gemini PR Review / review (pull_request) Failing after 38s
Laravel Larastan / larastan (pull_request) Failing after 2m24s
Laravel Pint / pint (pull_request) Failing after 2m7s
2025-12-02 08:24:22 +05:30
c6c63dcb35 Merge pull request 'Added ref no above the qr code in sticker printing' (#54) from ranjith-dev into master
All checks were successful
Scan for leaked secrets using Kingfisher / kingfisher-secrets-scan (push) Successful in 10s
Reviewed-on: #54
2025-12-01 12:20:43 +00:00
dhanabalan
2ceb76f008 Added ref no above the qr code in sticker printing
Some checks failed
Scan for leaked secrets using Kingfisher / kingfisher-secrets-scan (push) Successful in 11s
Scan for leaked secrets using Kingfisher / kingfisher-secrets-scan (pull_request) Successful in 10s
Gemini PR Review / review (pull_request) Failing after 27s
Laravel Larastan / larastan (pull_request) Failing after 2m15s
Laravel Pint / pint (pull_request) Failing after 7m11s
2025-12-01 17:50:30 +05:30
d1663ae58a Merge pull request 'Added serial qr code validation in create page of sticker printing' (#53) from ranjith-dev into master
All checks were successful
Scan for leaked secrets using Kingfisher / kingfisher-secrets-scan (push) Successful in 10s
Reviewed-on: #53
2025-12-01 12:11:15 +00:00
dhanabalan
988d109acc Added serial qr code validation in create page of sticker printing
Some checks failed
Scan for leaked secrets using Kingfisher / kingfisher-secrets-scan (push) Successful in 11s
Scan for leaked secrets using Kingfisher / kingfisher-secrets-scan (pull_request) Successful in 10s
Gemini PR Review / review (pull_request) Failing after 22s
Laravel Larastan / larastan (pull_request) Failing after 2m15s
Laravel Pint / pint (pull_request) Failing after 2m13s
2025-12-01 17:41:00 +05:30
deb46cdda2 Merge pull request 'chnaged indentation in item resource page' (#52) from ranjith-dev into master
Some checks failed
Scan for leaked secrets using Kingfisher / kingfisher-secrets-scan (push) Has been cancelled
Reviewed-on: #52
2025-12-01 12:10:12 +00:00
dhanabalan
bc8163a535 chnaged indentation in item resource page
Some checks failed
Scan for leaked secrets using Kingfisher / kingfisher-secrets-scan (push) Successful in 12s
Scan for leaked secrets using Kingfisher / kingfisher-secrets-scan (pull_request) Successful in 10s
Gemini PR Review / review (pull_request) Failing after 21s
Laravel Pint / pint (pull_request) Failing after 2m22s
Laravel Larastan / larastan (pull_request) Failing after 2m29s
2025-12-01 17:39:58 +05:30
002bdc597d Merge pull request 'Added crt logic policy for sticker printing' (#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-01 10:50:34 +00:00
dhanabalan
6834e37429 Added crt logic policy for sticker printing
Some checks failed
Scan for leaked secrets using Kingfisher / kingfisher-secrets-scan (push) Successful in 10s
Scan for leaked secrets using Kingfisher / kingfisher-secrets-scan (pull_request) Successful in 12s
Gemini PR Review / review (pull_request) Failing after 24s
Laravel Larastan / larastan (pull_request) Failing after 2m20s
Laravel Pint / pint (pull_request) Failing after 2m25s
2025-12-01 16:20:19 +05:30
a406d1b58a Merge pull request 'commented logic for sticker prinitng policy' (#50) from ranjith-dev into master
All checks were successful
Scan for leaked secrets using Kingfisher / kingfisher-secrets-scan (push) Successful in 12s
Reviewed-on: #50
2025-12-01 10:26:58 +00:00
dhanabalan
a9012ffc05 commented logic for sticker prinitng policy
Some checks failed
Scan for leaked secrets using Kingfisher / kingfisher-secrets-scan (push) Successful in 10s
Scan for leaked secrets using Kingfisher / kingfisher-secrets-scan (pull_request) Successful in 10s
Gemini PR Review / review (pull_request) Failing after 22s
Laravel Larastan / larastan (pull_request) Failing after 2m23s
Laravel Pint / pint (pull_request) Failing after 2m15s
2025-12-01 15:56:46 +05:30
58d0b9f0ae Merge pull request 'Added sticker printing policy' (#49) from ranjith-dev into master
All checks were successful
Scan for leaked secrets using Kingfisher / kingfisher-secrets-scan (push) Successful in 11s
Reviewed-on: #49
2025-12-01 10:12:17 +00:00
dhanabalan
c67bbc02b6 Added sticker printing policy
Some checks failed
Scan for leaked secrets using Kingfisher / kingfisher-secrets-scan (push) Successful in 10s
Scan for leaked secrets using Kingfisher / kingfisher-secrets-scan (pull_request) Successful in 10s
Gemini PR Review / review (pull_request) Failing after 23s
Laravel Pint / pint (pull_request) Failing after 2m30s
Laravel Larastan / larastan (pull_request) Failing after 3m4s
2025-12-01 15:41:56 +05:30
c0d8ca7b1e Merge pull request 'commented all line sof cod ein sticker printing policy' (#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-01 10:10:03 +00:00
dhanabalan
d71837f314 commented all line sof cod ein sticker printing policy
Some checks failed
Scan for leaked secrets using Kingfisher / kingfisher-secrets-scan (push) Successful in 11s
Scan for leaked secrets using Kingfisher / kingfisher-secrets-scan (pull_request) Successful in 11s
Gemini PR Review / review (pull_request) Failing after 20s
Laravel Pint / pint (pull_request) Failing after 1m55s
Laravel Larastan / larastan (pull_request) Failing after 2m5s
2025-12-01 15:39:39 +05:30
f31ab62ec0 Merge pull request 'commented user model class in spatie page' (#47) from ranjith-dev into master
All checks were successful
Scan for leaked secrets using Kingfisher / kingfisher-secrets-scan (push) Successful in 11s
Reviewed-on: #47
2025-12-01 09:55:11 +00:00
dhanabalan
36a50815f9 commented user model class in spatie page
Some checks failed
Scan for leaked secrets using Kingfisher / kingfisher-secrets-scan (push) Successful in 11s
Scan for leaked secrets using Kingfisher / kingfisher-secrets-scan (pull_request) Successful in 11s
Gemini PR Review / review (pull_request) Failing after 21s
Laravel Pint / pint (pull_request) Failing after 2m3s
Laravel Larastan / larastan (pull_request) Failing after 2m13s
2025-12-01 15:24:58 +05:30
4285a31f94 Merge pull request 'Added permissions for import and export for sticker printing' (#46) from ranjith-dev into master
All checks were successful
Scan for leaked secrets using Kingfisher / kingfisher-secrets-scan (push) Successful in 12s
Reviewed-on: #46
2025-12-01 09:30:07 +00:00
dhanabalan
11678dd846 Added permissions for import and export for sticker printing
Some checks failed
Scan for leaked secrets using Kingfisher / kingfisher-secrets-scan (push) Successful in 10s
Scan for leaked secrets using Kingfisher / kingfisher-secrets-scan (pull_request) Successful in 11s
Gemini PR Review / review (pull_request) Failing after 23s
Laravel Larastan / larastan (pull_request) Failing after 2m4s
Laravel Pint / pint (pull_request) Failing after 2m5s
2025-12-01 14:59:54 +05:30
0c9228bfec Merge pull request 'Updated item selection logic in StickerMasterResource to return an empty array when no plant is selected' (#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-01 09:23:49 +00:00
dhanabalan
035e6cd560 Updated item selection logic in StickerMasterResource to return an empty array when no plant is selected
Some checks failed
Scan for leaked secrets using Kingfisher / kingfisher-secrets-scan (push) Has been cancelled
Gemini PR Review / review (pull_request) Failing after 27s
Scan for leaked secrets using Kingfisher / kingfisher-secrets-scan (pull_request) Successful in 10s
Laravel Larastan / larastan (pull_request) Failing after 2m6s
Laravel Pint / pint (pull_request) Failing after 2m7s
2025-12-01 14:53:15 +05:30
58b45c849d Merge pull request 'Added print button for sticker printing 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-01 09:20:43 +00:00
dhanabalan
91deb448ef Added print button for sticker printing page
Some checks failed
Scan for leaked secrets using Kingfisher / kingfisher-secrets-scan (push) Has been cancelled
Scan for leaked secrets using Kingfisher / kingfisher-secrets-scan (pull_request) Successful in 11s
Gemini PR Review / review (pull_request) Failing after 25s
Laravel Larastan / larastan (pull_request) Failing after 2m9s
Laravel Pint / pint (pull_request) Failing after 2m25s
2025-12-01 14:50:31 +05:30
61a2e7ffad Merge pull request 'Added sticker printing create resource 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-01 09:18:30 +00:00
dhanabalan
c05b536253 Added sticker printing create resource file
Some checks failed
Scan for leaked secrets using Kingfisher / kingfisher-secrets-scan (push) Has been cancelled
Scan for leaked secrets using Kingfisher / kingfisher-secrets-scan (pull_request) Successful in 14s
Gemini PR Review / review (pull_request) Failing after 24s
Laravel Pint / pint (pull_request) Failing after 2m4s
Laravel Larastan / larastan (pull_request) Failing after 2m19s
2025-12-01 14:48:17 +05:30
3779cf3e3b Merge pull request 'Added sticker printing livewire page for table' (#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-01 09:15:31 +00:00
dhanabalan
10071413a1 Added sticker printing livewire page for table
Some checks failed
Scan for leaked secrets using Kingfisher / kingfisher-secrets-scan (push) Has been cancelled
Gemini PR Review / review (pull_request) Failing after 23s
Scan for leaked secrets using Kingfisher / kingfisher-secrets-scan (pull_request) Successful in 10s
Laravel Pint / pint (pull_request) Failing after 2m19s
Laravel Larastan / larastan (pull_request) Failing after 2m24s
2025-12-01 14:45:17 +05:30
acf955dd94 Merge pull request 'Added pdf qr code for sticker print page' (#41) from ranjith-dev into master
Some checks failed
Scan for leaked secrets using Kingfisher / kingfisher-secrets-scan (push) Has been cancelled
Reviewed-on: #41
2025-12-01 09:14:11 +00:00
dhanabalan
624e18e18d Added pdf qr code for sticker print page
Some checks failed
Scan for leaked secrets using Kingfisher / kingfisher-secrets-scan (push) Has been cancelled
Scan for leaked secrets using Kingfisher / kingfisher-secrets-scan (pull_request) Successful in 11s
Gemini PR Review / review (pull_request) Failing after 21s
Laravel Larastan / larastan (pull_request) Failing after 2m9s
Laravel Pint / pint (pull_request) Failing after 2m18s
2025-12-01 14:43:59 +05:30
0de49f14ce Merge pull request 'Added sticker printing policy page' (#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-01 09:13:27 +00:00
dhanabalan
11bbad0cf8 Added sticker printing policy page
Some checks failed
Scan for leaked secrets using Kingfisher / kingfisher-secrets-scan (push) Has been cancelled
Gemini PR Review / review (pull_request) Failing after 24s
Scan for leaked secrets using Kingfisher / kingfisher-secrets-scan (pull_request) Successful in 10s
Laravel Larastan / larastan (pull_request) Failing after 2m21s
Laravel Pint / pint (pull_request) Failing after 2m20s
2025-12-01 14:43:02 +05:30
0473ca33cf Merge pull request 'Added sticker prinitng import and export file' (#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-01 09:12:15 +00:00
dhanabalan
6ac3c664dd Added sticker prinitng import and export file
Some checks failed
Scan for leaked secrets using Kingfisher / kingfisher-secrets-scan (push) Has been cancelled
Scan for leaked secrets using Kingfisher / kingfisher-secrets-scan (pull_request) Successful in 10s
Gemini PR Review / review (pull_request) Failing after 27s
Laravel Larastan / larastan (pull_request) Failing after 2m3s
Laravel Pint / pint (pull_request) Failing after 2m16s
2025-12-01 14:42:01 +05:30
8a01033459 Merge pull request 'Added sticker printing resource file' (#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-01 09:11:15 +00:00
dhanabalan
10f2909b0e Added sticker printing resource file
Some checks failed
Scan for leaked secrets using Kingfisher / kingfisher-secrets-scan (push) Has been cancelled
Gemini PR Review / review (pull_request) Failing after 26s
Scan for leaked secrets using Kingfisher / kingfisher-secrets-scan (pull_request) Successful in 11s
Laravel Larastan / larastan (pull_request) Failing after 2m2s
Laravel Pint / pint (pull_request) Failing after 2m7s
2025-12-01 14:40:58 +05:30
0555f9faff Merge pull request 'Added sticker printing model file' (#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-01 09:09:39 +00:00
dhanabalan
e8ed47a110 Added sticker printing model file
Some checks failed
Scan for leaked secrets using Kingfisher / kingfisher-secrets-scan (push) Has been cancelled
Gemini PR Review / review (pull_request) Failing after 22s
Scan for leaked secrets using Kingfisher / kingfisher-secrets-scan (pull_request) Successful in 11s
Laravel Larastan / larastan (pull_request) Failing after 1m55s
Laravel Pint / pint (pull_request) Failing after 2m17s
2025-12-01 14:39:17 +05:30
8cbbaa4845 Merge pull request 'Added sticker printing migration 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-01 09:08:26 +00:00
dhanabalan
055d7707f4 Added sticker printing migration file
Some checks failed
Scan for leaked secrets using Kingfisher / kingfisher-secrets-scan (push) Has been cancelled
Gemini PR Review / review (pull_request) Failing after 24s
Scan for leaked secrets using Kingfisher / kingfisher-secrets-scan (pull_request) Successful in 11s
Laravel Larastan / larastan (pull_request) Failing after 2m4s
Laravel Pint / pint (pull_request) Failing after 2m16s
2025-12-01 14:38:06 +05:30
cb6b201648 Merge pull request 'Added user model class in spatie' (#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-01 09:06:52 +00:00
dhanabalan
55cf2f6924 Added user model class in spatie
Some checks failed
Scan for leaked secrets using Kingfisher / kingfisher-secrets-scan (push) Successful in 11s
Scan for leaked secrets using Kingfisher / kingfisher-secrets-scan (pull_request) Successful in 11s
Gemini PR Review / review (pull_request) Failing after 27s
Laravel Pint / pint (pull_request) Failing after 2m0s
Laravel Larastan / larastan (pull_request) Failing after 2m14s
2025-12-01 14:36:13 +05:30
c3089a147c Merge pull request 'Refactor processSerialNumber method to improve package validation logic' (#34) from ranjith-dev into master
All checks were successful
Scan for leaked secrets using Kingfisher / kingfisher-secrets-scan (push) Successful in 11s
Reviewed-on: #34
2025-12-01 08:28:43 +00:00
dhanabalan
d389136223 Refactor processSerialNumber method to improve package validation logic
Some checks failed
Scan for leaked secrets using Kingfisher / kingfisher-secrets-scan (push) Successful in 10s
Scan for leaked secrets using Kingfisher / kingfisher-secrets-scan (pull_request) Successful in 11s
Gemini PR Review / review (pull_request) Failing after 22s
Laravel Larastan / larastan (pull_request) Failing after 2m3s
Laravel Pint / pint (pull_request) Failing after 2m18s
2025-12-01 13:58:15 +05:30
45f0e39f73 Merge pull request 'Refactor plant selection logic in ItemResource and StickerMasterResource to order by code' (#33) from ranjith-dev into master
All checks were successful
Scan for leaked secrets using Kingfisher / kingfisher-secrets-scan (push) Successful in 10s
Reviewed-on: #33
2025-12-01 04:40:07 +00:00
dhanabalan
173638cd19 Refactor plant selection logic in ItemResource and StickerMasterResource to order by code
Some checks failed
Scan for leaked secrets using Kingfisher / kingfisher-secrets-scan (push) Successful in 11s
Scan for leaked secrets using Kingfisher / kingfisher-secrets-scan (pull_request) Successful in 12s
Gemini PR Review / review (pull_request) Failing after 22s
Laravel Larastan / larastan (pull_request) Failing after 2m19s
Laravel Pint / pint (pull_request) Failing after 2m50s
2025-12-01 10:09:22 +05:30
fe1e1b9918 Merge pull request 'Added Quality mail alert in alert mail page' (#32) from ranjith-dev into master
All checks were successful
Scan for leaked secrets using Kingfisher / kingfisher-secrets-scan (push) Successful in 11s
Reviewed-on: #32
2025-12-01 04:30:07 +00:00
dhanabalan
c8c38a05f4 Added Quality mail alert in alert mail page
Some checks failed
Scan for leaked secrets using Kingfisher / kingfisher-secrets-scan (push) Successful in 1m0s
Scan for leaked secrets using Kingfisher / kingfisher-secrets-scan (pull_request) Successful in 52s
Gemini PR Review / review (pull_request) Failing after 1m10s
Laravel Pint / pint (pull_request) Failing after 2m20s
Laravel Larastan / larastan (pull_request) Failing after 2m37s
2025-12-01 09:57:34 +05:30
e20915ca82 Merge pull request 'Refactor content method in InvoiceDataMail to use null-safe operator for document_date check' (#29) from ranjith-dev into master
All checks were successful
Scan for leaked secrets using Kingfisher / kingfisher-secrets-scan (push) Successful in 10s
Reviewed-on: #29
2025-11-29 12:58:25 +00:00
dhanabalan
5f4494f5aa Refactor content method in InvoiceDataMail to use null-safe operator for document_date check
Some checks failed
Scan for leaked secrets using Kingfisher / kingfisher-secrets-scan (push) Successful in 11s
Scan for leaked secrets using Kingfisher / kingfisher-secrets-scan (pull_request) Successful in 10s
Gemini PR Review / review (pull_request) Failing after 29s
Laravel Larastan / larastan (pull_request) Failing after 2m44s
Laravel Pint / pint (pull_request) Failing after 2m34s
2025-11-29 18:27:56 +05:30
58e6cbfac0 Merge pull request 'Added proper imports for mail' (#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-11-29 12:57:53 +00:00
dhanabalan
9fa73b2ecc Added proper imports for mail
Some checks failed
Scan for leaked secrets using Kingfisher / kingfisher-secrets-scan (push) Successful in 11s
Scan for leaked secrets using Kingfisher / kingfisher-secrets-scan (pull_request) Successful in 11s
Gemini PR Review / review (pull_request) Failing after 29s
Laravel Pint / pint (pull_request) Failing after 2m19s
Laravel Larastan / larastan (pull_request) Failing after 2m39s
2025-11-29 18:27:23 +05:30
1ace049687 Merge pull request 'Uncommented the mail schedule logic' (#27) from ranjith-dev into master
All checks were successful
Scan for leaked secrets using Kingfisher / kingfisher-secrets-scan (push) Successful in 13s
Reviewed-on: #27
2025-11-29 12:33:52 +00:00
dhanabalan
d75d435456 Uncommented the mail schedule logic
Some checks failed
Scan for leaked secrets using Kingfisher / kingfisher-secrets-scan (push) Successful in 10s
Scan for leaked secrets using Kingfisher / kingfisher-secrets-scan (pull_request) Successful in 11s
Laravel Larastan / larastan (pull_request) Failing after 2m1s
Laravel Pint / pint (pull_request) Failing after 2m0s
Gemini PR Review / review (pull_request) Failing after 26s
2025-11-29 18:02:25 +05:30
e5e85a8eea Merge pull request 'ranjith-dev' (#26) from ranjith-dev into master
All checks were successful
Scan for leaked secrets using Kingfisher / kingfisher-secrets-scan (push) Successful in 13s
Reviewed-on: #26
2025-11-29 12:28:01 +00:00
dhanabalan
ff8aa8b536 Update startDate logic in InvoiceDataMail content method to handle null document_date
Some checks failed
Scan for leaked secrets using Kingfisher / kingfisher-secrets-scan (push) Successful in 11s
Scan for leaked secrets using Kingfisher / kingfisher-secrets-scan (pull_request) Successful in 12s
Gemini PR Review / review (pull_request) Failing after 21s
Laravel Pint / pint (pull_request) Successful in 2m15s
Laravel Larastan / larastan (pull_request) Failing after 3m7s
2025-11-29 17:54:12 +05:30
dhanabalan
53f0a7bfdf Refactor InvoiceDataMail class for improved readability and consistency and __construct arg passing $tableData instead of $tableData = []
All checks were successful
Scan for leaked secrets using Kingfisher / kingfisher-secrets-scan (push) Successful in 11s
2025-11-29 17:37:16 +05:30
555802ab35 Merge pull request 'Updated warning message against tube_sticker and pack_slip master data' (#25) from ranjith-dev into master
All checks were successful
Scan for leaked secrets using Kingfisher / kingfisher-secrets-scan (push) Successful in 14s
Reviewed-on: #25
2025-11-29 11:53:18 +00:00
dhanabalan
1aa1937b39 Updated warning message against tube_sticker and pack_slip master data
Some checks failed
Scan for leaked secrets using Kingfisher / kingfisher-secrets-scan (push) Successful in 11s
Scan for leaked secrets using Kingfisher / kingfisher-secrets-scan (pull_request) Successful in 12s
Gemini PR Review / review (pull_request) Failing after 29s
Laravel Pint / pint (pull_request) Successful in 2m16s
Laravel Larastan / larastan (pull_request) Failing after 3m17s
2025-11-29 17:20:07 +05:30
587b743f12 Merge pull request 'Clear process_order if plant not selected' (#24) from ranjith-dev into master
All checks were successful
Scan for leaked secrets using Kingfisher / kingfisher-secrets-scan (push) Successful in 12s
Reviewed-on: #24
2025-11-29 10:47:24 +00:00
dhanabalan
0812484926 Clear process_order if plant not selected
Some checks failed
Scan for leaked secrets using Kingfisher / kingfisher-secrets-scan (push) Successful in 11s
Scan for leaked secrets using Kingfisher / kingfisher-secrets-scan (pull_request) Successful in 11s
Gemini PR Review / review (pull_request) Failing after 29s
Laravel Pint / pint (pull_request) Successful in 2m17s
Laravel Larastan / larastan (pull_request) Failing after 2m47s
2025-11-29 16:16:57 +05:30
42555d4a81 Merge pull request 'Added reactive validation for plant selection and duplicate checks for coil and SFG numbers in ProcessOrder form' (#23) from ranjith-dev into master
All checks were successful
Scan for leaked secrets using Kingfisher / kingfisher-secrets-scan (push) Successful in 15s
Reviewed-on: #23
2025-11-29 10:43:17 +00:00
dhanabalan
2d4700c9b2 Added reactive validation for plant selection and duplicate checks for coil and SFG numbers in ProcessOrder form
Some checks failed
Scan for leaked secrets using Kingfisher / kingfisher-secrets-scan (push) Successful in 10s
Scan for leaked secrets using Kingfisher / kingfisher-secrets-scan (pull_request) Successful in 11s
Gemini PR Review / review (pull_request) Failing after 29s
Laravel Pint / pint (pull_request) Successful in 2m0s
Laravel Larastan / larastan (pull_request) Failing after 2m57s
2025-11-29 16:11:41 +05:30
fd1e554076 Merge pull request 'commented out machine ID validation logic in storeProcessOrderData method' (#22) from ranjith-dev into master
All checks were successful
Scan for leaked secrets using Kingfisher / kingfisher-secrets-scan (push) Successful in 11s
Reviewed-on: #22
2025-11-29 10:07:18 +00:00
dhanabalan
eb38f4ddcf commented out machine ID validation logic in storeProcessOrderData method
Some checks failed
Scan for leaked secrets using Kingfisher / kingfisher-secrets-scan (push) Successful in 11s
Scan for leaked secrets using Kingfisher / kingfisher-secrets-scan (pull_request) Successful in 11s
Gemini PR Review / review (pull_request) Failing after 31s
Laravel Pint / pint (pull_request) Successful in 2m46s
Laravel Larastan / larastan (pull_request) Failing after 14m10s
2025-11-29 15:36:54 +05:30
022654f192 Merge pull request 'Updated get hasPumpQr status from pack_slip_pump if it does not exist in tube_sticker_pump' (#21) from ranjith-dev into master
All checks were successful
Scan for leaked secrets using Kingfisher / kingfisher-secrets-scan (push) Successful in 10s
Reviewed-on: #21
2025-11-29 09:00:31 +00:00
dhanabalan
faaaa88e8f Updated get hasPumpQr status from pack_slip_pump if it does not exist in tube_sticker_pump
Some checks failed
Scan for leaked secrets using Kingfisher / kingfisher-secrets-scan (push) Successful in 11s
Scan for leaked secrets using Kingfisher / kingfisher-secrets-scan (pull_request) Successful in 11s
Gemini PR Review / review (pull_request) Failing after 31s
Laravel Pint / pint (pull_request) Successful in 3m37s
Laravel Larastan / larastan (pull_request) Failing after 7m56s
2025-11-29 14:29:52 +05:30
55f1088fda Merge pull request 'Updated sfg_number validations as optional and check duplcate only if it exist' (#20) from ranjith-dev into master
All checks were successful
Scan for leaked secrets using Kingfisher / kingfisher-secrets-scan (push) Successful in 11s
Reviewed-on: #20
2025-11-29 06:52:08 +00:00
dhanabalan
d6c7e43715 Updated sfg_number validations as optional and check duplcate only if it exist
Some checks failed
Scan for leaked secrets using Kingfisher / kingfisher-secrets-scan (push) Successful in 11s
Scan for leaked secrets using Kingfisher / kingfisher-secrets-scan (pull_request) Successful in 11s
Gemini PR Review / review (pull_request) Failing after 21s
Laravel Pint / pint (pull_request) Successful in 2m48s
Laravel Larastan / larastan (pull_request) Failing after 4m30s
2025-11-29 12:21:17 +05:30
f9233f44d8 Merge pull request 'commented alert mail rules logic from boot method' (#19) from ranjith-dev into master
All checks were successful
Scan for leaked secrets using Kingfisher / kingfisher-secrets-scan (push) Successful in 13s
Reviewed-on: #19
2025-11-29 06:19:01 +00:00
dhanabalan
f45bb7b74b commented alert mail rules logic from boot method
Some checks failed
Scan for leaked secrets using Kingfisher / kingfisher-secrets-scan (push) Successful in 11s
Scan for leaked secrets using Kingfisher / kingfisher-secrets-scan (pull_request) Successful in 12s
Gemini PR Review / review (pull_request) Failing after 25s
Laravel Pint / pint (pull_request) Successful in 2m18s
Laravel Larastan / larastan (pull_request) Failing after 2m46s
2025-11-29 11:45:37 +05:30
e0fec6b07c Merge pull request 'Added schedule method logic in app service provider' (#18) from ranjith-dev into master
All checks were successful
Scan for leaked secrets using Kingfisher / kingfisher-secrets-scan (push) Successful in 11s
Reviewed-on: #18
2025-11-29 05:35:04 +00:00
dhanabalan
80806d0f17 Added schedule method logic in app service provider
Some checks failed
Scan for leaked secrets using Kingfisher / kingfisher-secrets-scan (push) Successful in 10s
Scan for leaked secrets using Kingfisher / kingfisher-secrets-scan (pull_request) Successful in 13s
Gemini PR Review / review (pull_request) Failing after 33s
Laravel Larastan / larastan (pull_request) Failing after 2m12s
Laravel Pint / pint (pull_request) Failing after 2m14s
2025-11-29 10:42:20 +05:30
6bda9c1459 Merge pull request 'Added LogClear command and Updated log message' (#17) from ranjith-dev into master
All checks were successful
Scan for leaked secrets using Kingfisher / kingfisher-secrets-scan (push) Successful in 10s
Reviewed-on: #17
2025-11-27 06:34:58 +00:00
dhanabalan
2b3db1cde1 feat: Add LogClear command to clear Laravel log files
Some checks failed
Scan for leaked secrets using Kingfisher / kingfisher-secrets-scan (push) Successful in 10s
Scan for leaked secrets using Kingfisher / kingfisher-secrets-scan (pull_request) Successful in 12s
Gemini PR Review / review (pull_request) Failing after 27s
Laravel Larastan / larastan (pull_request) Failing after 2m1s
Laravel Pint / pint (pull_request) Failing after 2m25s
2025-11-27 11:55:21 +05:30
dhanabalan
bf1ae76334 Updated POST API log message
All checks were successful
Scan for leaked secrets using Kingfisher / kingfisher-secrets-scan (push) Successful in 11s
2025-11-27 11:53:50 +05:30
39bdd3df57 Merge pull request 'Updated report view logic' (#16) from ranjith-dev into master
All checks were successful
Scan for leaked secrets using Kingfisher / kingfisher-secrets-scan (push) Successful in 10s
Reviewed-on: #16
2025-11-27 05:41:34 +00:00
dhanabalan
01783c4fc7 Updated report view logic
Some checks failed
Scan for leaked secrets using Kingfisher / kingfisher-secrets-scan (push) Successful in 10s
Scan for leaked secrets using Kingfisher / kingfisher-secrets-scan (pull_request) Successful in 11s
Gemini PR Review / review (pull_request) Failing after 20s
Laravel Larastan / larastan (pull_request) Failing after 1m59s
Laravel Pint / pint (pull_request) Failing after 2m18s
2025-11-27 11:07:04 +05:30
5bcf0703d9 Merge pull request 'Refactor: Clean up imports and enhance form/table structure in InvoiceDataValidation and InvoiceOutValidation resources' (#15) from ranjith-dev into master
All checks were successful
Scan for leaked secrets using Kingfisher / kingfisher-secrets-scan (push) Successful in 11s
Reviewed-on: #15
2025-11-27 05:29:19 +00:00
dhanabalan
95c909b6ac Refactor: Clean up imports and enhance form/table structure in InvoiceDataValidation and InvoiceOutValidation resources
Some checks failed
Scan for leaked secrets using Kingfisher / kingfisher-secrets-scan (push) Successful in 11s
Scan for leaked secrets using Kingfisher / kingfisher-secrets-scan (pull_request) Successful in 10s
Laravel Larastan / larastan (pull_request) Failing after 2m1s
Laravel Pint / pint (pull_request) Failing after 2m7s
Gemini PR Review / review (pull_request) Failing after 44s
2025-11-27 10:59:00 +05:30
80e522b7e6 Merge pull request 'feat: Add validation rules for Machine and Work Center names; enhance ProcessOrder table sorting; refactor StickerMasterResource for improved readability and functionality' (#14) from ranjith-dev into master
All checks were successful
Scan for leaked secrets using Kingfisher / kingfisher-secrets-scan (push) Successful in 10s
Reviewed-on: #14
2025-11-27 04:50:10 +00:00
dhanabalan
c16c967757 feat: Add validation rules for Machine and Work Center names; enhance ProcessOrder table sorting; refactor StickerMasterResource for improved readability and functionality
Some checks failed
Scan for leaked secrets using Kingfisher / kingfisher-secrets-scan (push) Successful in 10s
Scan for leaked secrets using Kingfisher / kingfisher-secrets-scan (pull_request) Successful in 11s
Gemini PR Review / review (pull_request) Failing after 25s
Laravel Pint / pint (pull_request) Failing after 2m2s
Laravel Larastan / larastan (pull_request) Failing after 2m37s
2025-11-27 10:18:36 +05:30
ee101f80ea Merge pull request 'Updated error response codes in updateGR and related methods to return 404 for various validation errors and Added sfg_number duplicate warning' (#13) from ranjith-dev into master
All checks were successful
Scan for leaked secrets using Kingfisher / kingfisher-secrets-scan (push) Successful in 11s
Reviewed-on: #13
2025-11-27 03:08:14 +00:00
dhanabalan
27b4377e9e Updated error response codes in updateGR and related methods to return 404 for various validation errors and Added sfg_number duplicate warning
Some checks failed
Scan for leaked secrets using Kingfisher / kingfisher-secrets-scan (push) Successful in 12s
Scan for leaked secrets using Kingfisher / kingfisher-secrets-scan (pull_request) Successful in 12s
Gemini PR Review / review (pull_request) Failing after 22s
Laravel Pint / pint (pull_request) Failing after 2m14s
Laravel Larastan / larastan (pull_request) Failing after 2m23s
2025-11-27 08:33:31 +05:30
37a99d03c1 Merge pull request 'Enhanced storeProcessOrderData method with improved validation and error handling for plant code, item code, coil number, order quantity, received quantity, SFG number, machine ID, and created by' (#12) from ranjith-dev into master
All checks were successful
Scan for leaked secrets using Kingfisher / kingfisher-secrets-scan (push) Successful in 11s
Reviewed-on: #12
2025-11-26 14:21:05 +00:00
dhanabalan
36e51ad6cb Enhanced storeProcessOrderData method with improved validation and error handling for plant code, item code, coil number, order quantity, received quantity, SFG number, machine ID, and created by
Some checks failed
Scan for leaked secrets using Kingfisher / kingfisher-secrets-scan (push) Successful in 10s
Scan for leaked secrets using Kingfisher / kingfisher-secrets-scan (pull_request) Successful in 11s
Gemini PR Review / review (pull_request) Failing after 24s
Laravel Larastan / larastan (pull_request) Failing after 2m12s
Laravel Pint / pint (pull_request) Failing after 2m26s
2025-11-26 19:48:52 +05:30
32 changed files with 3418 additions and 2102 deletions

View File

@@ -36,8 +36,8 @@ jobs:
restore-keys: |
${{ runner.os }}-npm-global-
- name: Install Gemini CLI globally
run: npm install -g --loglevel=http @google/gemini-cli
# - name: Install Gemini CLI globally
# run: npm install -g --loglevel=http @google/gemini-cli
- name: Generate git diff and review with Gemini
id: review

View File

@@ -0,0 +1,31 @@
<?php
namespace App\Console\Commands;
use Illuminate\Console\Command;
class LogClear extends Command
{
/**
* The name and signature of the console command.
*
* @var string
*/
protected $signature = 'app:log-clear';
/**
* The console command description.
*
* @var string
*/
protected $description = 'Command description';
/**
* Execute the console command.
*/
public function handle()
{
file_put_contents(storage_path('logs/laravel.log'), '');
$this->info('Laravel log cleared!');
}
}

View File

@@ -0,0 +1,54 @@
<?php
namespace App\Filament\Exports;
use App\Models\StickerPrinting;
use Filament\Actions\Exports\ExportColumn;
use Filament\Actions\Exports\Exporter;
use Filament\Actions\Exports\Models\Export;
class StickerPrintingExporter extends Exporter
{
protected static ?string $model = StickerPrinting::class;
public static function getColumns(): array
{
static $rowNumber = 0;
return [
ExportColumn::make('no')
->label('NO')
->state(function ($record) use (&$rowNumber) {
// Increment and return the row number
return ++$rowNumber;
}),
ExportColumn::make('plant.code')
->label('PLANT CODE'),
ExportColumn::make('reference_number')
->label('REFERENCE NUMBER'),
ExportColumn::make('serial_number')
->label('SERIAL NUMBER'),
ExportColumn::make('created_at')
->label('CREATED AT'),
ExportColumn::make('updated_at')
->label('UPDATED AT'),
ExportColumn::make('created_by')
->label('CREATED BY'),
ExportColumn::make('updated_by')
->label('UPDATED BY'),
ExportColumn::make('deleted_at')
->label('DELETED AT')
->enabledByDefault(false),
];
}
public static function getCompletedNotificationBody(Export $export): string
{
$body = 'Your sticker printing export has completed and ' . number_format($export->successful_rows) . ' ' . str('row')->plural($export->successful_rows) . ' exported.';
if ($failedRowsCount = $export->getFailedRowsCount()) {
$body .= ' ' . number_format($failedRowsCount) . ' ' . str('row')->plural($failedRowsCount) . ' failed to export.';
}
return $body;
}
}

View File

@@ -0,0 +1,106 @@
<?php
namespace App\Filament\Imports;
use App\Models\StickerPrinting;
use Filament\Actions\Imports\ImportColumn;
use Filament\Actions\Imports\Importer;
use Filament\Actions\Imports\Models\Import;
use Filament\Actions\Imports\Exceptions\RowImportFailedException;
use App\Models\Plant;
use App\Models\User;
use Str;
use Filament\Facades\Filament;
class StickerPrintingImporter extends Importer
{
protected static ?string $model = StickerPrinting::class;
public static function getColumns(): array
{
return [
ImportColumn::make('plant')
->requiredMapping()
->exampleHeader('PLANT CODE')
->example('1000')
->label('PLANT CODE')
->relationship(resolveUsing: 'code')
->rules(['required']),
ImportColumn::make('reference_number')
->exampleHeader('REFERENCE NUMBER')
->example('REF123456')
->label('REFERENCE NUMBER'),
ImportColumn::make('serial_number')
->exampleHeader('SERIAL NUMBER')
->example('135245325212')
->label('SERIAL NUMBER'),
// ImportColumn::make('created_by')
// ->exampleHeader('CREATED BY')
// ->example('RAW01234')
// ->label('CREATED BY'),
];
}
public function resolveRecord(): ?StickerPrinting
{
// return StickerPrinting::firstOrNew([
// // Update existing records, matching them by `$this->data['column_name']`
// 'email' => $this->data['email'],
// ]);
$warnMsg = [];
$plant = Plant::where('code', $this->data['plant'])->first();
if (Str::length($this->data['serial_number']) < 9 || !ctype_alnum($this->data['serial_number'])) {
$warnMsg[] = "Invalid serial number found";
}
$existing = StickerPrinting::where('plant_id', $plant->id)
->where('serial_number', $this->data['serial_number'])
->first();
if ($existing) {
$warnMsg[] = "Serial number already exists for this plant!";//throw new RowImportFailedException("Serial number already exists for this plant!");
}
$serial = $this->data['serial_number'];
// --- Check duplicate in DB ---
$existsInDB = StickerPrinting::where('plant_id', $plant->id)
->where('serial_number', $serial)
->first();
if ($existsInDB) {
//throw new RowImportFailedException("Serial number '{$serial}' already exists in DB for this plant!");
$warnMsg[] = "Serial number '{$serial}' already exists in DB for this plant!";
}
if (!empty($warnMsg)) {
throw new RowImportFailedException(implode(', ', $warnMsg));
}
StickerPrinting::Create([
'plant_id' => $plant->id,
'reference_number' => $this->data['reference_number'],
'serial_number' => $this->data['serial_number'],
'created_at' => now(),
'updated_at' =>now(),
'created_by' => Filament::auth()->user()?->name,
]);
return null;
//return new StickerPrinting();
}
public static function getCompletedNotificationBody(Import $import): string
{
$body = 'Your sticker printing 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.';
}
return $body;
}
}

View File

@@ -50,7 +50,7 @@ class AlertMailRuleResource extends Resource
'InvoiceValidation' => 'InvoiceValidation',
'InvoiceDataReport' => 'InvoiceDataReport',
'ProductionQuantities' => 'ProductionQuantities',
//'Calibration' => 'Calibration',
'QualityValidation' => 'QualityValidation',
]),
Forms\Components\Select::make('rule_name')
->label('Rule Name')
@@ -60,7 +60,7 @@ class AlertMailRuleResource extends Resource
'MaterialInvoiceMail' => 'Material Invoice Mail',
'ProductionMail' => 'Production Mail',
'InvoiceDataMail' => 'Invoice Data Mail',
//'CalibrationMail' => 'Calibration Mail',
'QualityMail' => 'Quality Mail',
])
->required(),
Forms\Components\TextInput::make('email')

View File

@@ -4,27 +4,23 @@ namespace App\Filament\Resources;
use App\Filament\Exports\InvoiceDataValidationExporter;
use App\Filament\Resources\InvoiceDataValidationResource\Pages;
use App\Filament\Resources\InvoiceDataValidationResource\RelationManagers;
use App\Models\InvoiceDataValidation;
use App\Models\Plant;
use DB;
use Filament\Facades\Filament;
use Filament\Forms;
use Filament\Forms\Components\FileUpload;
use Filament\Forms\Form;
use Filament\Forms\Get;
use Filament\Notifications\Notification;
use Filament\Resources\Resource;
use Filament\Tables;
use Filament\Tables\Actions\ExportAction;
use Filament\Tables\Table;
use Illuminate\Database\Eloquent\Builder;
use Illuminate\Database\Eloquent\SoftDeletingScope;
use Filament\Facades\Filament;
use Filament\Forms\Components\FileUpload;
use Filament\Forms\Components\Select;
use Filament\Notifications\Notification;
use App\Models\Plant;
use Filament\Forms\Get;
use Illuminate\Support\Facades\Storage;
use Maatwebsite\Excel\Facades\Excel;
use App\Models\StickerMaster;
use App\Models\User;
use DB;
use Filament\Tables\Actions\ExportAction;
class InvoiceDataValidationResource extends Resource
{
@@ -67,6 +63,7 @@ class InvoiceDataValidationResource extends Resource
->label('Created By')
->default(Filament::auth()->user()?->name),
Forms\Components\Hidden::make('updated_by')
->label('Updated By')
->default(Filament::auth()->user()?->name),
]);
}
@@ -77,10 +74,12 @@ class InvoiceDataValidationResource extends Resource
->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('plant.code')
@@ -100,8 +99,8 @@ class InvoiceDataValidationResource extends Resource
->sortable(),
Tables\Columns\TextColumn::make('document_number')
->label('Document Number')
->searchable()
->alignCenter()
->searchable()
->sortable(),
Tables\Columns\TextColumn::make('document_date')
->label('Document Date')
@@ -127,15 +126,28 @@ class InvoiceDataValidationResource extends Resource
Tables\Columns\TextColumn::make('created_at')
->label('Created At')
->alignCenter()
->searchable()
->dateTime()
->sortable()
->toggleable(isToggledHiddenByDefault: true),
->sortable(),
// ->toggleable(isToggledHiddenByDefault: true),
Tables\Columns\TextColumn::make('created_by')
->label('Created By')
->alignCenter()
->searchable()
->sortable(),
Tables\Columns\TextColumn::make('updated_at')
->label('Updated At')
->alignCenter()
->searchable()
->dateTime()
->sortable()
->toggleable(isToggledHiddenByDefault: true),
Tables\Columns\TextColumn::make('updated_by')
->label('Updated By')
->alignCenter()
->searchable()
->sortable()
->toggleable(isToggledHiddenByDefault: true),
Tables\Columns\TextColumn::make('deleted_at')
->label('Deleted At')
->alignCenter()
@@ -169,7 +181,7 @@ class InvoiceDataValidationResource extends Resource
->reactive()
->required()
->disk('local')
//->visible(fn (Get $get) => !empty($get('plant_id')))
// ->visible(fn (Get $get) => !empty($get('plant_id')))
->directory('uploads/temp'),
])
->action(function (array $data) {
@@ -191,12 +203,10 @@ class InvoiceDataValidationResource extends Resource
$fullPath = Storage::disk('local')->path($path);
if ($fullPath && file_exists($fullPath))
{
if ($fullPath && file_exists($fullPath)) {
$rows = Excel::toArray(null, $fullPath)[0];
if ((count($rows) - 1) <= 0)
{
if ((count($rows) - 1) <= 0) {
Notification::make()
->title('Records Not Found')
->body("Import the valid 'Invoice Data' file to proceed..!")
@@ -206,6 +216,7 @@ class InvoiceDataValidationResource extends Resource
if ($disk->exists($path)) {
$disk->delete($path);
}
return;
}
@@ -223,43 +234,40 @@ class InvoiceDataValidationResource extends Resource
$invalidLocation = [];
$seenPlantDoc = [];
//$duplicateEntries = [];
// $duplicateEntries = [];
$duplicateEntriesExcel = [];
foreach ($rows as $index => $row)
{
if ($index == 0) continue; // Skip header
foreach ($rows as $index => $row) {
if ($index == 0) {
continue;
} // Skip header
$DisChaDesc = trim($row[3]);
$plantCode = trim($row[4]);
$CustomerCode = trim($row[5]);
$DocNo = trim($row[6]);
$DocDate = trim($row[7]);
$CusTradeName = trim($row[9]);
$CusLocation = trim($row[10]);
$Location = trim($row[36]);
$DisChaDesc = trim($row[3]);
$plantCode = trim($row[4]);
$CustomerCode = trim($row[5]);
$DocNo = trim($row[6]);
$DocDate = trim($row[7]);
$CusTradeName = trim($row[9]);
$CusLocation = trim($row[10]);
$Location = trim($row[36]);
// if (empty($plantCode)) $invalidPlantCode[] = "Row {$index}";
if (empty($DisChaDesc)){
if (empty($DisChaDesc)) {
$invalidDisChaDesc[] = "Row {$index}";
}
if (empty($CustomerCode)){
if (empty($CustomerCode)) {
$invalidCustomerCode[] = "Row {$index}";
}
if (empty($DocNo))
{
if (empty($DocNo)) {
$invalidDocNo[] = "Row {$index}";
}
if (empty($CusTradeName))
{
if (empty($CusTradeName)) {
$invalidCusTradeName[] = "Row {$index}";
}
if (empty($CusLocation))
{
if (empty($CusLocation)) {
$invalidCusLocation[] = "Row {$index}";
}
if (empty($Location))
{
if (empty($Location)) {
$invalidLocation[] = "Row {$index}";
}
// if (empty($createdBy)) $invalidUser[] = "Row {$index}";
@@ -267,11 +275,9 @@ class InvoiceDataValidationResource extends Resource
if (strlen($plantCode) < 4) {
$invalidPlantCode[] = $plantCode;
}
if (!is_numeric($plantCode)) {
if (! is_numeric($plantCode)) {
$invalidPlantType[] = $plantCode;
}
else if (!Plant::where('code', $plantCode)->first())
{
} elseif (! Plant::where('code', $plantCode)->first()) {
$invalidPlaCoFound[] = $plantCode;
}
@@ -288,25 +294,36 @@ class InvoiceDataValidationResource extends Resource
// $duplicateEntries[] = "Duplicate record: Document Number '{$DocNo}' already exists for Plant '{$plant->name}'";
// }
//Also check duplicates within the same file ---
$uniqueKey = $plantCode . '_' . $DocNo;
// Also check duplicates within the same file ---
$uniqueKey = $plantCode.'_'.$DocNo;
if (in_array($uniqueKey, $seenPlantDoc)) {
$duplicateEntriesExcel[] = "Duplicate in file at Row {$index}: Document Number '{$DocNo}' already exists for Plant '{$plant->name}'";
}
$seenPlantDoc[] = $uniqueKey;
}
if (!empty($invalidCustomerCode) || !empty($invalidDocNo) || !empty($invalidDocDate) || !empty($invalidCusTradeName) || !empty($invalidCusLocation))
{
if (! empty($invalidCustomerCode) || ! empty($invalidDocNo) || ! empty($invalidDocDate) || ! empty($invalidCusTradeName) || ! empty($invalidCusLocation)) {
$errorMsg = '';
//if (!empty($invalidDisChaDesc)) $errorMsg .= 'Missing Distribution Channel Description in rows: ' . implode(', ', $invalidDisChaDesc) . '<br>';
if (!empty($invalidCustomerCode)) $errorMsg .= 'Missing Customer Code in rows: ' . implode(', ', $invalidCustomerCode) . '<br>';
if (!empty($invalidDocNo)) $errorMsg .= 'Missing Document Number in rows: ' . implode(', ', $invalidDocNo) . '<br>';
if (!empty($invalidDocDate)) $errorMsg .= 'Missing Document Date in rows: ' . implode(', ', $invalidDocDate) . '<br>';
if (!empty($invalidCusTradeName)) $errorMsg .= 'Missing Customer Trade Name in rows: ' . implode(', ', $invalidCusTradeName) . '<br>';
if (!empty($invalidCusLocation)) $errorMsg .= 'Missing Customer Location in rows: ' . implode(', ', $invalidCusLocation) . '<br>';
if (!empty($invalidLocation)) $errorMsg .= 'Missing Location in rows: ' . implode(', ', $invalidLocation) . '<br>';
// if (!empty($invalidDisChaDesc)) $errorMsg .= 'Missing Distribution Channel Description in rows: ' . implode(', ', $invalidDisChaDesc) . '<br>';
if (! empty($invalidCustomerCode)) {
$errorMsg .= 'Missing Customer Code in rows: '.implode(', ', $invalidCustomerCode).'<br>';
}
if (! empty($invalidDocNo)) {
$errorMsg .= 'Missing Document Number in rows: '.implode(', ', $invalidDocNo).'<br>';
}
if (! empty($invalidDocDate)) {
$errorMsg .= 'Missing Document Date in rows: '.implode(', ', $invalidDocDate).'<br>';
}
if (! empty($invalidCusTradeName)) {
$errorMsg .= 'Missing Customer Trade Name in rows: '.implode(', ', $invalidCusTradeName).'<br>';
}
if (! empty($invalidCusLocation)) {
$errorMsg .= 'Missing Customer Location in rows: '.implode(', ', $invalidCusLocation).'<br>';
}
if (! empty($invalidLocation)) {
$errorMsg .= 'Missing Location in rows: '.implode(', ', $invalidLocation).'<br>';
}
Notification::make()
->title('Missing Mandatory Fields')
@@ -317,45 +334,43 @@ class InvoiceDataValidationResource extends Resource
if ($disk->exists($path)) {
$disk->delete($path);
}
return;
}
else if (!empty($invalidPlantCode))
{
} elseif (! empty($invalidPlantCode)) {
$invalidPlantCode = array_unique($invalidPlantCode);
Notification::make()
->title('Invalid Plant Codes')
->body('The following plant codes should contain minimum 4 digits:<br>' . implode(', ', $invalidPlantCode))
->body('The following plant codes should contain minimum 4 digits:<br>'.implode(', ', $invalidPlantCode))
->danger()
->send();
if ($disk->exists($path)) {
$disk->delete($path);
}
return;
}
else if (!empty($invalidPlantType))
{
} elseif (! empty($invalidPlantType)) {
$invalidPlantType = array_unique($invalidPlantType);
Notification::make()
->title('Invalid Plant Codes')
->body('The following plant codes should contain numeric values:<br>' . implode(', ', $invalidPlantType))
->body('The following plant codes should contain numeric values:<br>'.implode(', ', $invalidPlantType))
->danger()
->send();
if ($disk->exists($path)) {
$disk->delete($path);
}
return;
}
else if (!empty($invalidPlaCoFound))
{
} elseif (! empty($invalidPlaCoFound)) {
$invalidPlaCoFound = array_unique($invalidPlaCoFound);
Notification::make()
->title('Invalid Plant Codes')
->body('The following plant codes not found in plants:<br>' . implode(', ', $invalidPlaCoFound))
->body('The following plant codes not found in plants:<br>'.implode(', ', $invalidPlaCoFound))
->danger()
->send();
if ($disk->exists($path)) {
$disk->delete($path);
}
return;
}
@@ -401,11 +416,10 @@ class InvoiceDataValidationResource extends Resource
// return;
// }
if (!empty($duplicateEntriesExcel))
{
if (! empty($duplicateEntriesExcel)) {
$duplicateGroupedByPlantExcel = [];
foreach ($duplicateEntriesExcel as $message) {//"/Document Number '([^']+)' already exist(?:s)?(?: for Plant (.+))?/"
foreach ($duplicateEntriesExcel as $message) {// "/Document Number '([^']+)' already exist(?:s)?(?: for Plant (.+))?/"
if (preg_match("/Document Number '([^']+)' already exists for Plant '([^']+)'/", $message, $matches)) {
$docNo = $matches[1];
$plantName = $matches[2] ?? 'Unknown';
@@ -415,8 +429,7 @@ class InvoiceDataValidationResource extends Resource
$errorMsg = 'Duplicate Document Number found in Uploaded File :<br>';
foreach ($duplicateGroupedByPlantExcel as $plant => $docNumbers)
{
foreach ($duplicateGroupedByPlantExcel as $plant => $docNumbers) {
// Remove duplicate document numbers for each plant
$uniqueDocNumbers = array_unique($docNumbers);
$count = count($uniqueDocNumbers);
@@ -425,13 +438,13 @@ class InvoiceDataValidationResource extends Resource
$errorMsg .= "Duplicate Document Numbers for Plant <b>{$plant}</b> : {$count} Document Numbers already exist in uploaded file<br>";
} else {
$errorMsg .= "Duplicate Document Numbers for Plant <b>{$plant}</b> : '"
. implode(', ', $uniqueDocNumbers)
. "' already exist in uploaded file<br>";
.implode(', ', $uniqueDocNumbers)
."' already exist in uploaded file<br>";
}
}
Notification::make()
//->title('Duplicate Document Number in Uploaded File')
// ->title('Duplicate Document Number in Uploaded File')
->body($errorMsg)
->danger()
->send();
@@ -439,6 +452,7 @@ class InvoiceDataValidationResource extends Resource
if ($disk->exists($path)) {
$disk->delete($path);
}
return;
}
@@ -455,33 +469,34 @@ class InvoiceDataValidationResource extends Resource
DB::beginTransaction();
try
{
try {
foreach ($rows as $index => $row) {
if ($index == 0) continue;
if ($index == 0) {
continue;
}
$rowNumber = $index + 1;
try {
$DisChaDesc = trim($row[3]);
$plantCode = trim($row[4]);
$DisChaDesc = trim($row[3]);
$plantCode = trim($row[4]);
$CustomerCode = trim($row[5]);
$DocNo = trim($row[6]);
$DocDate = trim($row[7]);
$DocNo = trim($row[6]);
$DocDate = trim($row[7]);
$CusTradeName = trim($row[9]);
$CusLocation = trim($row[10]);
$Location = trim($row[36]);
$CusLocation = trim($row[10]);
$Location = trim($row[36]);
if (empty($DocNo)) {
throw new \Exception("Row '{$rowNumber}' Missing QR Code");
}
$plant = Plant::where('code', $plantCode)->first();
if (!$plant) {
if (! $plant) {
throw new \Exception("Invalid plant code : '{$plantCode}'");
}
if (!empty($DocDate)) {
if (! empty($DocDate)) {
if (preg_match('/^\d{2}[-\/]\d{2}[-\/]\d{4}$/', $DocDate)) {
[$day, $month, $year] = preg_split('/[-\/]/', $DocDate);
$formattedDate = "{$year}-{$month}-{$day}";
@@ -503,26 +518,26 @@ class InvoiceDataValidationResource extends Resource
if ($record) {
$record->update([
'distribution_channel_desc' => $DisChaDesc,
'customer_code' => $CustomerCode,
'document_date' => $formattedDate,
'customer_trade_name' => $CusTradeName,
'customer_location' => $CusLocation,
'location' => $Location,
'updated_by' => $operatorName
'customer_code' => $CustomerCode,
'document_date' => $formattedDate,
'customer_trade_name' => $CusTradeName,
'customer_location' => $CusLocation,
'location' => $Location,
'updated_by' => $operatorName,
]);
$inserted = $record;
} else {
// Record does not exist, create with 'created_by'
$inserted = InvoiceDataValidation::create([
'plant_id' => $plant->id,
'document_number' => $DocNo,
'plant_id' => $plant->id,
'document_number' => $DocNo,
'distribution_channel_desc' => $DisChaDesc,
'customer_code' => $CustomerCode,
'document_date' => $formattedDate,
'customer_trade_name' => $CusTradeName,
'customer_location' => $CusLocation,
'location' => $Location,
'created_by' => $operatorName
'customer_code' => $CustomerCode,
'document_date' => $formattedDate,
'customer_trade_name' => $CusTradeName,
'customer_location' => $CusLocation,
'location' => $Location,
'created_by' => $operatorName,
]);
}
// $inserted = InvoiceDataValidation::create([
@@ -536,7 +551,7 @@ class InvoiceDataValidationResource extends Resource
// 'created_by' => $operatorName
// ]);
if (!$inserted) {
if (! $inserted) {
throw new \Exception("{$curStat} failed for Document Number : {$DocNo}");
}
@@ -545,7 +560,7 @@ class InvoiceDataValidationResource extends Resource
$failedRecords[] = [
'row' => $rowNumber,
'document_number' => $DocNo ?? null,
'error' => $e->getMessage()
'error' => $e->getMessage(),
];
}
}
@@ -554,13 +569,13 @@ class InvoiceDataValidationResource extends Resource
if (count($failedRecords) > 0) {
$failedSummary = collect($failedRecords)
->map(fn($f) => "Row {$f['row']} ({$f['document_number']}) : {$f['error']}")
->map(fn ($f) => "Row {$f['row']} ({$f['document_number']}) : {$f['error']}")
->take(5) // limit preview to first 5 errors
->implode("\n");
Notification::make()
->title('Partial Import Warning')
->body("'{$successCount}' records inserted. " . count($failedRecords) . " failed.\n\n{$failedSummary}")
->body("'{$successCount}' records inserted. ".count($failedRecords)." failed.\n\n{$failedSummary}")
->warning()
->send();
} else {
@@ -570,9 +585,7 @@ class InvoiceDataValidationResource extends Resource
->success()
->send();
}
}
catch (\Exception $e)
{
} catch (\Exception $e) {
DB::rollBack();
Notification::make()
->title('Import Failed')
@@ -582,14 +595,14 @@ class InvoiceDataValidationResource extends Resource
}
}
})
->visible(function() {
->visible(function () {
return Filament::auth()->user()->can('view import invoice data validation');
}),
ExportAction::make()
->label('Export Invoice Data')
->color('warning')
->exporter(InvoiceDataValidationExporter::class)
->visible(function() {
->visible(function () {
return Filament::auth()->user()->can('view export invoice data validation');
}),
]);

View File

@@ -4,27 +4,25 @@ namespace App\Filament\Resources;
use App\Filament\Exports\InvoiceOutValidationExporter;
use App\Filament\Resources\InvoiceOutValidationResource\Pages;
use App\Filament\Resources\InvoiceOutValidationResource\RelationManagers;
use App\Models\InvoiceOutValidation;
use App\Models\Plant;
use App\Models\User;
use Carbon\Carbon;
use DB;
use Filament\Facades\Filament;
use Filament\Forms;
use Filament\Forms\Components\FileUpload;
use Filament\Forms\Components\Section;
use Filament\Forms\Form;
use Filament\Notifications\Notification;
use Filament\Resources\Resource;
use Filament\Tables;
use Filament\Tables\Actions\ExportAction;
use Filament\Tables\Table;
use Illuminate\Database\Eloquent\Builder;
use Illuminate\Database\Eloquent\SoftDeletingScope;
use Filament\Facades\Filament;
use Filament\Forms\Components\FileUpload;
use Filament\Forms\Components\Section;
use Filament\Notifications\Notification;
use Maatwebsite\Excel\Facades\Excel;
use Storage;
use Filament\Tables\Actions\ExportAction;
use PhpOffice\PhpSpreadsheet\Shared\Date as ExcelDate;
use Storage;
class InvoiceOutValidationResource extends Resource
{
@@ -39,24 +37,25 @@ class InvoiceOutValidationResource extends Resource
return $form
->schema([
Section::make('')
->schema([
Forms\Components\Select::make('plant_id')
->label('Plant')
->relationship('plant', 'name')
->required(),
Forms\Components\TextInput::make('qr_code')
->label('QR Code'),
Forms\Components\DateTimePicker::make('scanned_at')
->label('Scanned At'),
Forms\Components\TextInput::make('scanned_by')
->label('Scanned By'),
Forms\Components\Hidden::make('created_by')
->label('Created By')
->default(Filament::auth()->user()?->name),
Forms\Components\Hidden::make('updated_by')
->default(Filament::auth()->user()?->name),
])
->columns(4),
->schema([
Forms\Components\Select::make('plant_id')
->label('Plant')
->relationship('plant', 'name')
->required(),
Forms\Components\TextInput::make('qr_code')
->label('QR Code'),
Forms\Components\DateTimePicker::make('scanned_at')
->label('Scanned At'),
Forms\Components\TextInput::make('scanned_by')
->label('Scanned By'),
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),
])
->columns(4),
]);
}
@@ -66,15 +65,18 @@ class InvoiceOutValidationResource extends Resource
->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('plant.code')
->label('Plant')
->alignCenter()
->searchable()
->sortable(),
Tables\Columns\TextColumn::make('qr_code')
->label('QR Code')
@@ -93,27 +95,33 @@ class InvoiceOutValidationResource extends Resource
->alignCenter()
->sortable(),
Tables\Columns\TextColumn::make('created_at')
->searchable()
->label('Created At')
->dateTime()
->searchable()
->alignCenter()
->sortable(),
//->toggleable(isToggledHiddenByDefault: true),
// ->toggleable(isToggledHiddenByDefault: true),
Tables\Columns\TextColumn::make('created_by')
->label('Created By')
->searchable()
->alignCenter()
->sortable(),
Tables\Columns\TextColumn::make('updated_at')
->label('Updated At')
->dateTime()
->searchable()
->sortable(),
// ->toggleable(isToggledHiddenByDefault: true),
->alignCenter()
->sortable()
->toggleable(isToggledHiddenByDefault: true),
Tables\Columns\TextColumn::make('updated_by')
->label('Updated By')
->searchable()
->alignCenter()
->sortable(),
->sortable()
->toggleable(isToggledHiddenByDefault: true),
Tables\Columns\TextColumn::make('deleted_at')
->dateTime()
->alignCenter()
->sortable()
->toggleable(isToggledHiddenByDefault: true),
])
@@ -143,7 +151,7 @@ class InvoiceOutValidationResource extends Resource
->reactive()
->required()
->disk('local')
//->visible(fn (Get $get) => !empty($get('plant_id')))
// ->visible(fn (Get $get) => !empty($get('plant_id')))
->directory('uploads/temp'),
])
->action(function (array $data) {
@@ -165,12 +173,10 @@ class InvoiceOutValidationResource extends Resource
$fullPath = Storage::disk('local')->path($path);
if ($fullPath && file_exists($fullPath))
{
if ($fullPath && file_exists($fullPath)) {
$rows = Excel::toArray(null, $fullPath)[0];
if ((count($rows) - 1) <= 0)
{
if ((count($rows) - 1) <= 0) {
Notification::make()
->title('Records Not Found')
->body("Import the valid 'Invoice Data' file to proceed..!")
@@ -180,6 +186,7 @@ class InvoiceOutValidationResource extends Resource
if ($disk->exists($path)) {
$disk->delete($path);
}
return;
}
@@ -192,27 +199,34 @@ class InvoiceOutValidationResource extends Resource
$userNotFound = [];
$seenPlantQr = [];
$duplicateQrExcel = [];
//$duplicateQrDb = [];
// $duplicateQrDb = [];
foreach ($rows as $index => $row)
{
if ($index == 0) continue;
foreach ($rows as $index => $row) {
if ($index == 0) {
continue;
}
$qrCode = trim($row[1]);
$plantCode = trim($row[2]);
$scannedAt = trim($row[3]);
$scannedby = trim($row[4]);
$qrCode = trim($row[1]);
$plantCode = trim($row[2]);
$scannedAt = trim($row[3]);
$scannedby = trim($row[4]);
if (empty($plantCode)) $invalidPlantCode[] = "Row {$index}";
if (empty($qrCode)) $invalidqrCode[] = "Row {$index}";
if (empty($scannedAt)) $invalidScannedAt[] = "Row {$index}";
if (empty($scannedby)) $invalidScannedBy[] = "Row {$index}";
if (empty($plantCode)) {
$invalidPlantCode[] = "Row {$index}";
}
if (empty($qrCode)) {
$invalidqrCode[] = "Row {$index}";
}
if (empty($scannedAt)) {
$invalidScannedAt[] = "Row {$index}";
}
if (empty($scannedby)) {
$invalidScannedBy[] = "Row {$index}";
}
if (strlen($plantCode) < 4) {
$invalidPlantCode[] = $plantCode;
}
else if(!Plant::where('code', $plantCode)->first())
{
} elseif (! Plant::where('code', $plantCode)->first()) {
$invalidPlaCoFound[] = $plantCode;
}
@@ -220,7 +234,7 @@ class InvoiceOutValidationResource extends Resource
$plantId = $plant->id;
$uniqueKey = $plantCode . '_' . $qrCode;
$uniqueKey = $plantCode.'_'.$qrCode;
if (in_array($uniqueKey, $seenPlantQr)) {
$duplicateQrExcel[] = "Duplicate in file at Row {$index}: Document Number '{$qrCode}' already exists for Plant '{$plant->name}'";
@@ -237,13 +251,18 @@ class InvoiceOutValidationResource extends Resource
// }
}
if (!empty($invalidqrCode) || !empty($invalidScannedAt) || !empty($invalidScannedBy) || !empty($invalidUser))
{
if (! empty($invalidqrCode) || ! empty($invalidScannedAt) || ! empty($invalidScannedBy) || ! empty($invalidUser)) {
$errorMsg = '';
if (!empty($invalidqrCode)) $errorMsg .= 'Missing Qr code in rows: '.implode(', ', $invalidqrCode) . '<br>';
if (!empty($invalidScannedAt)) $errorMsg .= 'Missing Scanned At in rows: '.implode(', ', $invalidScannedAt) . '<br>';
if (!empty($invalidScannedBy)) $errorMsg .= 'Missing Scanned By in rows: '.implode(', ', $invalidScannedBy) . '<br>';
if (! empty($invalidqrCode)) {
$errorMsg .= 'Missing Qr code in rows: '.implode(', ', $invalidqrCode).'<br>';
}
if (! empty($invalidScannedAt)) {
$errorMsg .= 'Missing Scanned At in rows: '.implode(', ', $invalidScannedAt).'<br>';
}
if (! empty($invalidScannedBy)) {
$errorMsg .= 'Missing Scanned By in rows: '.implode(', ', $invalidScannedBy).'<br>';
}
Notification::make()
->title('Missing Mandatory Fields')
@@ -254,53 +273,56 @@ class InvoiceOutValidationResource extends Resource
if ($disk->exists($path)) {
$disk->delete($path);
}
return;
}
if (!empty($invalidPlantCode)) {
if (! empty($invalidPlantCode)) {
$invalidPlantCode = array_unique($invalidPlantCode);
Notification::make()
->title('Invalid Plant Codes')
->body('The following plant codes should contain minimum 4 digits:<br>' . implode(', ', $invalidPlantCode))
->danger()
->send();
->title('Invalid Plant Codes')
->body('The following plant codes should contain minimum 4 digits:<br>'.implode(', ', $invalidPlantCode))
->danger()
->send();
if ($disk->exists($path)) {
$disk->delete($path);
}
return;
}
if (!empty($invalidPlaCoFound)) {
if (! empty($invalidPlaCoFound)) {
$invalidPlaCoFound = array_unique($invalidPlaCoFound);
Notification::make()
->title('Invalid Plant Codes')
->body('The following plant codes not found in plants:<br>' . implode(', ', $invalidPlaCoFound))
->danger()
->send();
->title('Invalid Plant Codes')
->body('The following plant codes not found in plants:<br>'.implode(', ', $invalidPlaCoFound))
->danger()
->send();
if ($disk->exists($path)) {
$disk->delete($path);
}
return;
}
if (!empty($userNotFound)) {
if (! empty($userNotFound)) {
$userNotFound = array_unique($userNotFound);
Notification::make()
->title('Invalid User')
->body('The following user not found:<br>' . implode(', ', $userNotFound))
->danger()
->send();
->title('Invalid User')
->body('The following user not found:<br>'.implode(', ', $userNotFound))
->danger()
->send();
if ($disk->exists($path)) {
$disk->delete($path);
}
return;
}
if (!empty($duplicateQrExcel))
{
if (! empty($duplicateQrExcel)) {
$duplicateGroupedByPlantQr = [];
foreach ($duplicateQrExcel as $message) {//"/Document Numbers '([^']+)' already exists for Plant Code (\S+)/"
foreach ($duplicateQrExcel as $message) {// "/Document Numbers '([^']+)' already exists for Plant Code (\S+)/"
if (preg_match("/Document Number '([^']+)' already exists for Plant '([^']+)'/", $message, $matches)) {
$qrCode = $matches[1];
$plantCode = $matches[2];
@@ -318,13 +340,13 @@ class InvoiceOutValidationResource extends Resource
$errorMsg .= "Duplicate Document Numbers for Plant <b>{$plantCode}</b> : {$count} Document Numbers already exist in uploaded file<br>";
} else {
$errorMsg .= "Duplicate Document Numbers for Plant <b>{$plantCode}</b> : '"
. implode(', ', $uniqueQrCodes)
. "' already exist in uploaded file<br>";
.implode(', ', $uniqueQrCodes)
."' already exist in uploaded file<br>";
}
}
Notification::make()
//->title('Duplicate Document Number in Uploaded File')
// ->title('Duplicate Document Number in Uploaded File')
->body($errorMsg)
->danger()
->send();
@@ -380,15 +402,16 @@ class InvoiceOutValidationResource extends Resource
DB::beginTransaction();
try
{
try {
foreach ($rows as $index => $row) {
if ($index == 0) continue;
if ($index == 0) {
continue;
}
$rowNumber = $index + 1;
try {
$qrcode = trim($row[1]);
$qrcode = trim($row[1]);
$plantCode = trim($row[2]);
$scannedAt = trim($row[3]);
$scannedBy = trim($row[4]);
@@ -398,12 +421,12 @@ class InvoiceOutValidationResource extends Resource
}
$plant = Plant::where('code', $plantCode)->first();
if (!$plant) {
if (! $plant) {
throw new \Exception("Invalid plant code : '{$plantCode}'");
}
$formattedDate = null;
if (!empty($scannedAt)) {
if (! empty($scannedAt)) {
try {
// $formattedDate = Carbon::createFromFormat('d-m-Y H:i:s', $scannedAt)
// ->format('Y-m-d H:i:s');
@@ -430,7 +453,7 @@ class InvoiceOutValidationResource extends Resource
$record->update([
'scanned_at' => $formattedDate,
'scanned_by' => $scannedBy,
'updated_by' => $operatorName
'updated_by' => $operatorName,
]);
$inserted = $record;
} else {
@@ -440,7 +463,7 @@ class InvoiceOutValidationResource extends Resource
'qr_code' => $qrcode,
'scanned_at' => $formattedDate,
'scanned_by' => $scannedBy,
'created_by' => $operatorName
'created_by' => $operatorName,
]);
}
// $inserted = InvoiceOutValidation::create([
@@ -451,7 +474,7 @@ class InvoiceOutValidationResource extends Resource
// 'created_by' => $operatorName
// ]);
if (!$inserted) {
if (! $inserted) {
throw new \Exception("{$curStat} failed for QR : {$qrcode}");
}
@@ -460,7 +483,7 @@ class InvoiceOutValidationResource extends Resource
$failedRecords[] = [
'row' => $rowNumber,
'qrcode' => $qrcode ?? null,
'error' => $e->getMessage()
'error' => $e->getMessage(),
];
}
}
@@ -469,13 +492,13 @@ class InvoiceOutValidationResource extends Resource
if (count($failedRecords) > 0) {
$failedSummary = collect($failedRecords)
->map(fn($f) => "Row {$f['row']} ({$f['qrcode']}) : {$f['error']}")
->map(fn ($f) => "Row {$f['row']} ({$f['qrcode']}) : {$f['error']}")
->take(5) // limit preview to first 5 errors
->implode("\n");
Notification::make()
->title('Partial Import Warning')
->body("'{$successCount}' records inserted. " . count($failedRecords) . " failed.\n\n{$failedSummary}")
->body("'{$successCount}' records inserted. ".count($failedRecords)." failed.\n\n{$failedSummary}")
->warning()
->send();
} else {
@@ -485,9 +508,7 @@ class InvoiceOutValidationResource extends Resource
->success()
->send();
}
}
catch (\Exception $e)
{
} catch (\Exception $e) {
DB::rollBack();
Notification::make()
->title('Import Failed')
@@ -497,14 +518,14 @@ class InvoiceOutValidationResource extends Resource
}
}
})
->visible(function() {
->visible(function () {
return Filament::auth()->user()->can('view import invoice out validation');
}),
ExportAction::make()
->label('Export Invoice Out Data')
->color('warning')
->exporter(InvoiceOutValidationExporter::class)
->visible(function() {
->visible(function () {
return Filament::auth()->user()->can('view export invoice out validation');
}),
]);

View File

@@ -12,24 +12,24 @@ use App\Models\StickerMaster;
use Filament\Actions\Exports\Enums\ExportFormat;
use Filament\Facades\Filament;
use Filament\Forms;
use Filament\Forms\Components\DateTimePicker;
use Filament\Forms\Components\FileUpload;
use Filament\Forms\Components\Section;
use Filament\Forms\Components\Select;
use Filament\Forms\Components\TextInput;
use Filament\Forms\Form;
use Filament\Forms\Get;
use Filament\Notifications\Notification;
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\Notifications\Notification;
use Illuminate\Validation\Rule;
use Maatwebsite\Excel\Facades\Excel;
use Storage;
use Str;
class ItemResource extends Resource
{
@@ -48,125 +48,125 @@ class ItemResource extends Resource
Section::make('')
->schema([
Forms\Components\Select::make('plant_id')
->relationship('plant', 'name')
->required()
->relationship('plant', 'name')
->required()
// ->preload()
// ->nullable(),
->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();
})
->default(function () {
return optional(Item::latest()->first())->plant_id;
})
->disabled(fn (Get $get) => !empty($get('id')))
// ->afterStateUpdated(fn ($set) => $set('block_id', null) & $set('name', null) & $set('start_time', null) & $set('duration', null) & $set('end_time', null))
->afterStateUpdated(function ($state, callable $set, callable $get) {
$plantId = $get('plant_id');
// Ensure `linestop_id` is not cleared
if (!$plantId) {
$set('iPlantError', 'Please select a plant first.');
return;
}
else
{
$set('iPlantError', null);
}
})
->extraAttributes(fn ($get) => [
'class' => $get('iPlantError') ? 'border-red-500' : '',
])
->hint(fn ($get) => $get('iPlantError') ? $get('iPlantError') : null)
->hintColor('danger'),
Forms\Components\TextInput::make('category')
->label('Category')
->placeholder('Scan the Category'),
Forms\Components\TextInput::make('code')
->required()
->placeholder('Scan the valid code')
->autofocus(true)
// ->unique(ignoreRecord: true)
->alphaNum()
->minLength(6)
// ->autocapitalize('characters')
->reactive()
->disabled(fn (Get $get) => !empty($get('id')))
->afterStateUpdated(function ($state, callable $set, callable $get) {
$code = $get('code');
// Ensure `linestop_id` is not cleared
if (!$code) {
$set('iCodeError', 'Scan the valid code.');
return;
}
else
{
if (strlen($code) < 6) {
$set('iCodeError', 'Item code must be at least 6 digits.');
return;
}
else if (!preg_match('/^[a-zA-Z0-9]{6,}$/', $code)) {
$set('code',null);
$set('iCodeError', 'Item code must contain only alpha-numeric characters.');
return;
}
$set('iCodeError', null);
}
})
->extraAttributes(fn ($get) => [
'class' => $get('iCodeError') ? 'border-red-500' : '',
])
->hint(fn ($get) => $get('iCodeError') ? $get('iCodeError') : null)
->hintColor('danger')
->rule(function (callable $get) {
return Rule::unique('items', 'code')
->where('plant_id', $get('plant_id'))
->ignore($get('id')); // Ignore current record during updates
}),
Forms\Components\TextInput::make('hourly_quantity')
->required()
->label('Hourly Quantity')
->placeholder('Scan the valid quantity')
->integer()
->default(1)
->minValue(1)
->reactive()
->afterStateUpdated(function ($state, callable $set, callable $get) {
$hourQuan = $get('hourly_quantity');
// Ensure `linestop_id` is not cleared
if (!$hourQuan) {
$set('iHourQuanError', 'Scan the valid hourly quantity.');
return;
}
else
{
if (!preg_match('/^[0-9]{1,}$/', $hourQuan)) {
$set('hourly_quantity',null);
$set('iHourQuanError', 'Quantity must be integer value.');
return;
}
$set('iHourQuanError', null);
}
})
->extraAttributes(fn ($get) => [
'class' => $get('iHourQuanError') ? 'border-red-500' : '',
])
->hint(fn ($get) => $get('iHourQuanError') ? $get('iHourQuanError') : null)
->hintColor('danger'),
Forms\Components\TextInput::make('uom')
->required()
->label('Unit of Measure')
->placeholder('Scan the valid uom'),
->reactive()
->options(function (callable $get) {
$userHas = Filament::auth()->user()->plant_id;
Forms\Components\TextInput::make('description')
->placeholder('Scan the valid description')
->required()
->minLength(5)
->columnSpan(['default' => 1, 'sm' => 1]),
return ($userHas && strlen($userHas) > 0) ? Plant::where('id', $userHas)->pluck('name', 'id')->toArray() : Plant::pluck('name', 'id')->toArray();
})
->default(function () {
return optional(Item::latest()->first())->plant_id;
})
->disabled(fn (Get $get) => ! empty($get('id')))
// ->afterStateUpdated(fn ($set) => $set('block_id', null) & $set('name', null) & $set('start_time', null) & $set('duration', null) & $set('end_time', null))
->afterStateUpdated(function ($state, callable $set, callable $get) {
$plantId = $get('plant_id');
// Ensure `linestop_id` is not cleared
if (! $plantId) {
$set('iPlantError', 'Please select a plant first.');
return;
} else {
$set('iPlantError', null);
}
})
->extraAttributes(fn ($get) => [
'class' => $get('iPlantError') ? 'border-red-500' : '',
])
->hint(fn ($get) => $get('iPlantError') ? $get('iPlantError') : null)
->hintColor('danger'),
Forms\Components\TextInput::make('category')
->label('Category')
->placeholder('Scan the Category'),
Forms\Components\TextInput::make('code')
->required()
->placeholder('Scan the valid code')
->autofocus(true)
// ->unique(ignoreRecord: true)
->alphaNum()
->minLength(6)
// ->autocapitalize('characters')
->reactive()
->disabled(fn (Get $get) => ! empty($get('id')))
->afterStateUpdated(function ($state, callable $set, callable $get) {
$code = $get('code');
// Ensure `linestop_id` is not cleared
if (! $code) {
$set('iCodeError', 'Scan the valid code.');
return;
} else {
if (strlen($code) < 6) {
$set('iCodeError', 'Item code must be at least 6 digits.');
return;
} elseif (! preg_match('/^[a-zA-Z0-9]{6,}$/', $code)) {
$set('code', null);
$set('iCodeError', 'Item code must contain only alpha-numeric characters.');
return;
}
$set('iCodeError', null);
}
})
->extraAttributes(fn ($get) => [
'class' => $get('iCodeError') ? 'border-red-500' : '',
])
->hint(fn ($get) => $get('iCodeError') ? $get('iCodeError') : null)
->hintColor('danger')
->rule(function (callable $get) {
return Rule::unique('items', 'code')
->where('plant_id', $get('plant_id'))
->ignore($get('id')); // Ignore current record during updates
}),
Forms\Components\TextInput::make('hourly_quantity')
->required()
->label('Hourly Quantity')
->placeholder('Scan the valid quantity')
->integer()
->default(1)
->minValue(1)
->reactive()
->afterStateUpdated(function ($state, callable $set, callable $get) {
$hourQuan = $get('hourly_quantity');
// Ensure `linestop_id` is not cleared
if (! $hourQuan) {
$set('iHourQuanError', 'Scan the valid hourly quantity.');
return;
} else {
if (! preg_match('/^[0-9]{1,}$/', $hourQuan)) {
$set('hourly_quantity', null);
$set('iHourQuanError', 'Quantity must be integer value.');
return;
}
$set('iHourQuanError', null);
}
})
->extraAttributes(fn ($get) => [
'class' => $get('iHourQuanError') ? 'border-red-500' : '',
])
->hint(fn ($get) => $get('iHourQuanError') ? $get('iHourQuanError') : null)
->hintColor('danger'),
Forms\Components\TextInput::make('uom')
->required()
->label('Unit of Measure')
->placeholder('Scan the valid uom'),
Forms\Components\TextInput::make('description')
->placeholder('Scan the valid description')
->required()
->minLength(5)
->columnSpan(['default' => 1, 'sm' => 1]),
// ->columnSpanFull(),
Forms\Components\TextInput::make('id')
->hidden()
->readOnly(),
Forms\Components\TextInput::make('id')
->hidden()
->readOnly(),
])
->columns(3),
]);
@@ -187,6 +187,7 @@ class ItemResource 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')
@@ -238,7 +239,135 @@ class ItemResource extends Resource
])
->filters([
Tables\Filters\TrashedFilter::make(),
Filter::make('advanced_filters')
->label('Advanced Filters')
->form([
Select::make('Plant')
->label('Select Plant')
->nullable()
->options(function (callable $get) {
$userHas = Filament::auth()->user()->plant_id;
return ($userHas && strlen($userHas) > 0) ? Plant::where('id', $userHas)->orderBy('code')->pluck('name', 'id')->toArray() : Plant::orderBy('code')->pluck('name', 'id')->toArray();
})
->reactive()
->afterStateUpdated(function ($state, callable $set, callable $get): void {
$set('code', null);
$set('operator_id', null);
}),
Select::make('code')
->label('Search by Item Code')
->nullable()
// ->options(function (callable $get) {
// $plantId = $get('Plant');
// return $plantId
// ? Item::where('plant_id', $plantId)->pluck('code', 'id')
// : Item::pluck('code', 'id');
// })
->options(function (callable $get) {
$plantId = $get('Plant');
return $plantId ? Item::where('plant_id', $plantId)->pluck('code', 'id') : [];
})
->searchable()
->reactive(),
TextInput::make('description')
->label('Search by Description')
->placeholder(placeholder: 'Enter Description'),
TextInput::make('category')
->label('Search by Category')
->placeholder(placeholder: 'Enter Category'),
TextInput::make('uom')
->label('Search by UOM')
->placeholder(placeholder: 'Enter UOM'),
DateTimePicker::make(name: 'created_from')
->label('Created From')
->placeholder(placeholder: 'Select From DateTime')
->reactive()
->native(false),
DateTimePicker::make('created_to')
->label('Created To')
->placeholder(placeholder: 'Select To DateTime')
->reactive()
->native(false),
])
->query(function ($query, array $data) {
// Hide all records initially if no filters are applied
if (
empty($data['Plant']) &&
empty($data['code']) &&
empty($data['description']) &&
empty($data['uom']) &&
empty($data['category']) &&
empty($data['created_from']) &&
empty($data['created_to'])
) {
return $query->whereRaw('1 = 0');
}
if (! empty($data['Plant'])) { // $plant = $data['Plant'] ?? null
$query->where('plant_id', $data['Plant']);
}
if (! empty($data['code'])) {
$query->where('id', $data['code']);
}
if (! empty($data['description'])) {
$query->where('description', '%'.$data['description'].'%');
}
if (! empty($data['uom'])) {
$query->where('uom', 'like', '%'.$data['uom'].'%');
}
if (! empty($data['category'])) {
$query->where('category', '%'.$data['category'].'%');
}
if (! empty($data['created_from'])) {
$query->where('created_at', '>=', $data['created_from']);
}
if (! empty($data['created_to'])) {
$query->where('created_at', '<=', $data['created_to']);
}
})
->indicateUsing(function (array $data) {
$indicators = [];
if (! empty($data['Plant'])) {
$indicators[] = 'Plant: '.Plant::where('id', $data['Plant'])->value('name');
}
if (! empty($data['code'])) {
$indicators[] = 'Item Code: '.Item::where('id', $data['code'])->value('code');
}
if (! empty($data['description'])) {
$indicators[] = 'Description: '.$data['description'];
}
if (! empty($data['uom'])) {
$indicators[] = 'UOM: '.$data['uom'];
}
if (! empty($data['category'])) {
$indicators[] = 'Category: '.$data['category'];
}
if (! empty($data['created_from'])) {
$indicators[] = 'From: '.$data['created_from'];
}
if (! empty($data['created_to'])) {
$indicators[] = 'To: '.$data['created_to'];
}
return $indicators;
}),
])
->filtersFormMaxHeight('280px')
->actions([
Tables\Actions\ViewAction::make(),
Tables\Actions\EditAction::make(),
@@ -251,7 +380,6 @@ class ItemResource extends Resource
]),
])
->headerActions([
// Tables\Actions\Action::make('Import Items')
// ->label('Import Items')
// ->form([
@@ -402,7 +530,6 @@ class ItemResource extends Resource
// return;
// }
// $uniqueCodes = array_unique($materialCodes);
// $matchedItems = StickerMaster::with('item')
@@ -483,23 +610,23 @@ class ItemResource extends Resource
->label('Import Items')
->color('warning')
->importer(ItemImporter::class)
->visible(function() {
->visible(function () {
return Filament::auth()->user()->can('view import item');
}),
// ->maxRows(100000),
// ->maxRows(100000),
ExportAction::make()
// ->columnMapping(true)
// ->columnMapping(true)
->label('Export Items')
->color('warning')
// ->fileName("Items Report " . date('Y-m-d H:i:s'))
// ->fileName("Items Report " . date('Y-m-d H:i:s'))
->exporter(ItemExporter::class)
->visible(function() {
->visible(function () {
return Filament::auth()->user()->can('view export item');
}),
// ->formats([
// ExportFormat::Xlsx,
// ExportFormat::Csv,
// ]),
// ->formats([
// ExportFormat::Xlsx,
// ExportFormat::Csv,
// ]),
]);
}

View File

@@ -159,6 +159,7 @@ class MachineResource extends Resource
->hintColor('danger'),
Forms\Components\TextInput::make('name')
->label('Name')
->minLength(5)
->placeholder('Scan the valid Machine Name')
->required()
->rule(function (callable $get) {
@@ -169,6 +170,7 @@ class MachineResource extends Resource
}),
Forms\Components\TextInput::make('work_center')
->label('Work Center')
->minLength(6)
->placeholder('Scan the valid Work Center')
->required()
->rule(function (callable $get) {

View File

@@ -46,6 +46,22 @@ class ProcessOrderResource extends Resource
return ($userHas && strlen($userHas) > 0) ? Plant::where('id', $userHas)->pluck('name', 'id')->toArray() : Plant::pluck('name', 'id')->toArray();
})
->afterStateUpdated(function ($state, $set, callable $get, $livewire) {
$plantId = $get('plant_id');
$set('coil_number', null);
$set('sfg_number', null);
$set('machine_name', null);
if (! $plantId) {
$set('poPlantError', 'Please select a plant first.');
$set('coilNumberError', null);
$set('sfgNumberError', null);
}
})
->extraAttributes(fn ($get) => [
'class' => $get('poPlantError') ? 'border-red-500' : '',
])
->hint(fn ($get) => $get('poPlantError') ? $get('poPlantError') : null)
->hintColor('danger')
->required(),
Forms\Components\Select::make('item_id')
->label('Item Code')
@@ -108,10 +124,63 @@ class ProcessOrderResource extends Resource
// ->readOnly(true),
Forms\Components\TextInput::make('process_order')
->label('Process Order')
->reactive()
->afterStateUpdated(function ($state, $set, callable $get, $livewire) {
$plantId = $get('plant_id');
$set('coil_number', null);
$set('sfg_number', null);
$set('machine_name', null);
if (! $plantId) {
$set('poPlantError', 'Please select a plant first.');
$set('process_order', null);
$set('coilNumberError', null);
$set('sfgNumberError', null);
}
})
->required(),
Forms\Components\TextInput::make('coil_number')
->label('Coil Number')
->default('0')
->reactive()
->afterStateUpdated(function ($state, $set, callable $get, $livewire) {
$plantId = $get('plant_id');
$processOrder = $get('process_order');
$coilNo = $get('coil_number');
if (! $plantId) {
$set('poPlantError', 'Please select a plant first.');
$set('coil_number', null);
$set('sfg_number', null);
$set('machine_name', null);
$set('coilNumberError', null);
$set('sfgNumberError', null);
} elseif (! $processOrder) {
$set('coil_number', null);
$set('sfg_number', null);
$set('machine_name', null);
$set('poPlantError', null);
$set('coilNumberError', null);
$set('sfgNumberError', null);
} elseif ($coilNo || $coilNo == '0') {
$existing = ProcessOrder::where('plant_id', $plantId)
->where('process_order', $processOrder)
->where('coil_number', $coilNo)
->first();
if ($existing) {
$set('poPlantError', null);
$set('coil_number', null);
$set('coilNumberError', "Duplicate Coil : '{$coilNo}' found!");
} else {
$set('poPlantError', null);
$set('coilNumberError', null);
}
}
})
->extraAttributes(fn ($get) => [
'class' => $get('coilNumberError') ? 'border-red-500' : '',
])
->hint(fn ($get) => $get('coilNumberError') ? $get('coilNumberError') : null)
->hintColor('danger')
->required(),
Forms\Components\TextInput::make('order_quantity')
->label('Order Quantity')
@@ -122,10 +191,38 @@ class ProcessOrderResource extends Resource
->required(),
Forms\Components\TextInput::make('sfg_number')
->label('SFG Number')
->required(),
->reactive()
->afterStateUpdated(function ($state, $set, callable $get, $livewire) {
$plantId = $get('plant_id');
$sfgNo = $get('sfg_number');
if (! $plantId) {
$set('poPlantError', 'Please select a plant first.');
$set('sfg_number', null);
$set('machine_name', null);
$set('sfgNumberError', null); // 'Please select a plant first.'
} elseif ($sfgNo) {
$existing = ProcessOrder::where('plant_id', $plantId)
->where('sfg_number', $sfgNo)
->first();
if ($existing) {
$set('poPlantError', null);
$set('sfg_number', null);
$set('machine_name', null);
$set('sfgNumberError', "Duplicate SFG : '{$sfgNo}' found!");
} else {
$set('poPlantError', null);
$set('sfgNumberError', null);
}
}
})
->extraAttributes(fn ($get) => [
'class' => $get('sfgNumberError') ? 'border-red-500' : '',
])
->hint(fn ($get) => $get('sfgNumberError') ? $get('sfgNumberError') : null)
->hintColor('danger'),
Forms\Components\TextInput::make('machine_name')
->label('Machine ID')
->required(),
->label('Machine ID'),
Forms\Components\FileUpload::make('attachment')
->label('PDF Upload')
->acceptedFileTypes(['application/pdf'])
@@ -370,8 +467,7 @@ class ProcessOrderResource extends Resource
->label('Created At')
->alignCenter()
->dateTime()
->sortable()
->toggleable(isToggledHiddenByDefault: true),
->sortable(),
Tables\Columns\TextColumn::make('created_by')
->label('Created By')
->alignCenter()

File diff suppressed because it is too large Load Diff

View File

@@ -0,0 +1,199 @@
<?php
namespace App\Filament\Resources;
use App\Filament\Resources\StickerPrintingResource\Pages;
use App\Models\Plant;
use App\Models\StickerPrinting;
use Filament\Facades\Filament;
use Filament\Forms;
use Filament\Forms\Components\Section;
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 Filament\Tables\Actions\ExportAction;
use Filament\Tables\Actions\ImportAction;
use App\Filament\Exports\StickerPrintingExporter;
use App\Filament\Imports\StickerPrintingImporter;
use Filament\Forms\Components\Actions\Action;
class StickerPrintingResource extends Resource
{
protected static ?string $model = StickerPrinting::class;
protected static ?string $navigationIcon = 'heroicon-o-rectangle-stack';
public static function form(Form $form): Form
{
return $form
->schema([
Section::make('')
->schema([
Forms\Components\Select::make('plant_id')
->label('Plant')
->reactive()
->relationship('plant', 'name')
->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 $set, callable $get) {
$plantId = $get('plant_id');
if (!$plantId) {
$set('reference_number', null);
$set('serial_number', null);
$set('ivPlantError', 'Please select a plant first.');
} else {
$set('ivPlantError', null);
$set('reference_number', null);
$set('serial_number', null);
}
})
->extraAttributes(fn ($get) => [
'class' => $get('ivPlantError') ? 'border-red-500' : '',
])
->hint(fn ($get) => $get('ivPlantError') ? $get('ivPlantError') : null)
->hintColor('danger'),
Forms\Components\TextInput::make('reference_number')
->label('Reference Number')
->reactive()
->readOnly(fn (callable $get) => !empty($get('serial_number')))
->extraAttributes([
'id' => 'invoice_number_input',
'x-data' => '{ value: "" }',
'x-model' => 'value',
'wire:keydown.enter.prevent' => 'processRef(value)',
])
->required(),
Forms\Components\TextInput::make('serial_number')
->label('Serial Number')
->reactive()
// ->required()
->readOnly(fn (callable $get) => empty($get('reference_number')))
->extraAttributes([
'id' => 'serial_number_input',
'x-data' => '{ value: "" }',
'x-model' => 'value',
'wire:keydown.enter.prevent' => 'processSno(value)',
//'x-on:keydown.enter.prevent' => '$wire.processInvoice(value)',
]),
//->required(),
Forms\Components\View::make('forms.components.print-button'),
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),
])
->columns(4),
]);
}
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('plant.name')
->label('Plant')
->searchable()
->sortable(),
Tables\Columns\TextColumn::make('reference_number')
->label('Reference Number')
->searchable()
->sortable(),
Tables\Columns\TextColumn::make('serial_number')
->label('Serial Number')
->searchable()
->sortable(),
Tables\Columns\TextColumn::make('created_by')
->label('Created By')
->searchable()
->sortable(),
Tables\Columns\TextColumn::make('created_at')
->dateTime()
->sortable()
->toggleable(isToggledHiddenByDefault: true),
Tables\Columns\TextColumn::make('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(),
]),
])
->headerActions([
ImportAction::make()
->importer(StickerPrintingImporter::class)
->label('Import Sticker Printing')
->color('warning')
->visible(function () {
return Filament::auth()->user()->can('view import sticker printing');
}),
ExportAction::make()
->exporter(StickerPrintingExporter::class)
->label('Export Sticker Printing')
->color('warning')
->visible(function () {
return Filament::auth()->user()->can('view export sticker printing');
}),
]);
}
public static function getRelations(): array
{
return [
//
];
}
public static function getPages(): array
{
return [
'index' => Pages\ListStickerPrintings::route('/'),
'create' => Pages\CreateStickerPrinting::route('/create'),
'view' => Pages\ViewStickerPrinting::route('/{record}'),
'edit' => Pages\EditStickerPrinting::route('/{record}/edit'),
];
}
public static function getEloquentQuery(): Builder
{
return parent::getEloquentQuery()
->withoutGlobalScopes([
SoftDeletingScope::class,
]);
}
}

View File

@@ -0,0 +1,244 @@
<?php
namespace App\Filament\Resources\StickerPrintingResource\Pages;
use App\Filament\Resources\StickerPrintingResource;
use Filament\Resources\Pages\CreateRecord;
use PDF;
use SimpleSoftwareIO\QrCode\Facades\QrCode;
use Filament\Facades\Filament;
use App\Models\StickerPrinting;
use Filament\Notifications\Notification;
use Str;
class CreateStickerPrinting extends CreateRecord
{
protected static string $resource = StickerPrintingResource::class;
protected static string $view = 'filament.resources.sticker-printing-resource.pages.create-sticker-printing';
public $plantId;
public $ref_number;
public $ref;
public $serial_number;
public function getFormActions(): array
{
return [
$this->getCancelFormAction(),
];
}
protected function getRedirectUrl(): string
{
return $this->getResource()::getUrl('create');
}
public function loadRecords()
{
$this->records = StickerPrinting::where('reference_number', $this->refNumber)
->where('plant_id', $this->plantId)
->latest()
->get();
}
public function processRef($value)
{
//$this->ref_number = $value;
$ref = $this->form->getState()['reference_number'] ?? null;
$user = Filament::auth()->user();
$operatorName = $user->name;
$plantId = $this->form->getState()['plant_id'];
$this->plantId = $plantId;
$this->dispatch('refreshEmptySticker', $plantId, $ref);
$this->dispatch('focus-serial-number');
}
public function processSno($value)
{
$this->serial_number = $value;
$plant = $this->form->getState()['plant_id'] ?? null;
$ref = $this->form->getState()['reference_number'] ?? null;
$sNumber = $this->form->getState()['serial_number'] ?? null;
$pattern1 = '/^(?<item_code>[^|]+)\|(?<serial_number>[^|]+)\|?$/i';
$pattern2 = '/^(?<item_code>[^|]+)\|(?<serial_number>[^|]+)\|(?<batch_number>.+)$/i';
$pattern3 = '/^(?<serial_number>[^|]+)$/i';
if (preg_match($pattern1, $sNumber, $matches) || preg_match($pattern2, $sNumber, $matches) || preg_match($pattern3, $sNumber, $matches)) {
$serial = $matches['serial_number'];
if (Str::length($serial) < 9) {
Notification::make()
->title('Invalid Serial Number')
->body("Serial number should conatin minimum 9 digits '$serial'.")
->warning()
->send();
$this->form->fill([
'plant_id' => $plant,
'reference_number' => $ref,
'serial_number' => '',
]);
return;
}
else if(!ctype_alnum($serial)) {
Notification::make()
->title('Invalid Serial Number')
->body("Serial number should be alphanumeric '$serial'.")
->warning()
->send();
$this->form->fill([
'plant_id' => $plant,
'reference_number' => $ref,
'serial_number' => '',
]);
return;
}
$extractedSerialNumber = $matches['serial_number'];
$sNumber = $extractedSerialNumber;
}
else
{
Notification::make()
->title('Invalid Format')
->body("Serial number must be in the format 'itemcode|serialnumber' or 'itemcode|serialnumber|batchnumber'. or just 'serialnumber'.")
->warning()
->send();
// Reset only serial number field
$this->form->fill([
'plant_id' => $plant,
'reference_number' => $ref,
'serial_number' => '',
]);
return;
}
if ($plant == null || trim($plant) == '' || $ref == null || trim($ref) == '' || $sNumber == null || trim($sNumber) == '')
{
Notification::make()
->title('Unknown: Incomplete Data!')
->body("Please ensure Plant, Reference Number, and Serial Number are provided.")
->danger()
->seconds(3)
->send();
return;
}
$exists = StickerPrinting::where('plant_id', $plant)
->where('serial_number', $sNumber)
->first();
if ($exists) {
Notification::make()
->title('Duplicate Serial Number!')
->body("Serial Number {$sNumber} already exists for this plant.")
->danger()
->seconds(3)
->send();
// Reset only serial number field
$this->form->fill([
'plant_id' => $plant,
'reference_number' => $ref,
'serial_number' => '',
]);
return;
}
StickerPrinting::create([
'plant_id' => $plant,
'reference_number' => $ref,
'serial_number' => $sNumber,
'created_by' => Filament::auth()->user()->name,
]);
$this->dispatch('addStickerToList', $plant, $ref, $sNumber);
$this->form->fill([
'plant_id' => $plant,
'reference_number' => $ref,
'serial_number' => '',
]);
}
public function printSticker() {
$plantId = $this->form->getState()['plant_id'];
$plantId = trim($plantId) ?? null;
$refNumber = trim($this->form->getState()['reference_number'])?? null;
$refNumber = trim($refNumber) ?? null;
$serialNumber = trim($this->form->getState()['serial_number'])?? null;
$serialNumber = trim($serialNumber) ?? null;
// dd($plantId, $refNumber, $serialNumber);
$serialNumbers = StickerPrinting::where('plant_id', $plantId)
->where('reference_number', $refNumber)
->pluck('serial_number')
->toArray();
if (empty($serialNumbers))
{
Notification::make()
->title('No Serial Numbers found!')
->body('Please check the selected Plant & Reference Number.')
->danger()
->send();
return;
}
// Encode as JSON string in QR Code
// $qrData = json_encode([
// 'serial_numbers' => $serialNumbers,
// ]);
//$qrData = implode(',', $serialNumbers);
$qrData = implode("\n", $serialNumbers);
$qrCode = base64_encode(
QrCode::format('png')
->size(1200) // smaller, still high res
->margin(6) // white border
->errorCorrection('Q')// medium-high correction
->generate($qrData)
);
// Send data to Pdf view
$pdf = PDF::loadView('pdf.qrcode', [
'qrCode' => $qrCode,
'referenceNumber' => $refNumber,
]);
return response()->streamDownload(function () use ($pdf) {
echo $pdf->output();
}, "qr-sticker.pdf");
}
}

View File

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

View File

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

View File

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

View File

@@ -35,7 +35,7 @@ class PdfController extends Controller
return response()->json([
'status_code' => 'ERROR',
'status_description' => 'Invalid authorization token!',
], 403);
], 404);
}
$data = $request->all();
@@ -46,12 +46,12 @@ class PdfController extends Controller
return response()->json([
'status_code' => 'ERROR',
'status_description' => "Plant code can't be empty!",
], 400);
], 404);
} elseif (Str::length($data['plant_code']) < 4 || ! is_numeric($data['plant_code']) || ! preg_match('/^[1-9]\d{3,}$/', $data['plant_code'])) {// !ctype_digit($data['plant_code'])
return response()->json([
'status_code' => 'ERROR',
'status_description' => 'Invalid plant code found!',
], 400);
], 404);
}
$plant = Plant::where('code', $data['plant_code'])->first();
@@ -59,7 +59,7 @@ class PdfController extends Controller
return response()->json([
'status_code' => 'ERROR',
'status_description' => 'Plant not found!',
], 400);
], 404);
}
$plantId = $plant->id;
@@ -67,7 +67,7 @@ class PdfController extends Controller
return response()->json([
'status_code' => 'ERROR',
'status_description' => "GR Number can't be empty!",
], 400);
], 404);
}
$grExists = GRMaster::where('plant_id', $plantId)
@@ -87,7 +87,7 @@ class PdfController extends Controller
return response()->json([
'status_code' => 'ERROR',
'status_description' => "Scanned by can't be empty!",
], 400);
], 404);
}
$user = User::where('name', $data['scanned_by'])
@@ -109,7 +109,7 @@ class PdfController extends Controller
'status_code' => 'ERROR',
'status_description' => 'Duplicate item codes found in request!',
'duplicate_item_codes' => array_values($duplicateItemCodes),
], 400);
], 404);
}
$allSerials = [];
@@ -129,7 +129,7 @@ class PdfController extends Controller
'status_code' => 'ERROR',
'status_description' => 'Duplicate serial numbers found in request!',
'duplicate_serial_numbers' => array_values($duplicateSerials),
], 400);
], 404);
}
$invalidLengthItemCodes = [];
@@ -152,7 +152,7 @@ class PdfController extends Controller
'status_code' => 'ERROR',
'status_description' => 'Some item codes are invalid: must be at least 6 digits!',
'invalid_item_codes' => array_values($invalidLengthItemCodes),
], 400);
], 404);
}
$invalidItemCodes = [];
@@ -187,7 +187,7 @@ class PdfController extends Controller
'status_description' => 'Some item codes are invalid!',
'not_found_items' => array_values($invalidItemCodes),
'not_in_plant' => array_values($invalidPlantItems),
], 400);
], 404);
}
$missingSerialsByItem = [];
@@ -226,7 +226,7 @@ class PdfController extends Controller
'status_code' => 'ERROR',
'status_description' => 'Some serial numbers not found in DB for given plant, GR number, and item!',
'missing_serials' => $missingSerialsByItem,
], 400);
], 404);
}
$alreadyCompleted = [];
@@ -259,7 +259,7 @@ class PdfController extends Controller
'status_code' => 'ERROR',
'status_description' => 'Below serial numbers are already completed',
'serial_numbers' => $alreadyCompleted,
], 400);
], 404);
}
// {
// $itemCode = $item['item_code'];
@@ -270,7 +270,7 @@ class PdfController extends Controller
// return response()->json([
// 'status_code' => 'ERROR',
// 'status_description' => "Item code: $itemCode not found"
// ], 400);
// ], 404);
// }
// $itemPlant = Item::where('plant_id', $plantId)
@@ -279,7 +279,7 @@ class PdfController extends Controller
// return response()->json([
// 'status_code' => 'ERROR',
// 'status_description' => "Item code: $itemCode not found for the plant: $data[plant_code]"
// ], 400);
// ], 404);
// }
// $itemId = $itemObj->id;
@@ -330,13 +330,13 @@ class PdfController extends Controller
return response()->json([
'status_code' => 'ERROR',
'status_description' => 'Invalid authorization token!',
], 403);
], 404);
}
$filename = $request->header('process-order');
if (! $filename) {
return response()->json(['error' => 'Missing file-name header'], 400);
return response()->json(['error' => 'Missing file-name header'], 404);
}
$filename = basename($filename);
@@ -377,7 +377,7 @@ class PdfController extends Controller
return response()->json([
'status_code' => 'ERROR',
'status_description' => 'Invalid authorization token!',
], 403);
], 404);
}
$filename = $request->header('gr-number');
@@ -386,8 +386,8 @@ class PdfController extends Controller
return response()->json([
'status_code' => 'ERROR',
'status_description' => 'Gr Number cannot be empty!',
], 403);
// return response()->json(['error' => 'Missing file-name header'], 400);
], 404);
// return response()->json(['error' => 'Missing file-name header'], 404);
}
$filename = basename($filename);
@@ -404,7 +404,7 @@ class PdfController extends Controller
return response()->json([
'status_code' => 'ERROR',
'status_description' => 'Pdf File not found for the provided GrNumber!',
], 403);
], 404);
}
$file = Storage::disk('local')->get($filePath);
@@ -428,7 +428,7 @@ class PdfController extends Controller
return response()->json([
'status_code' => 'ERROR',
'status_description' => 'Invalid authorization token!',
], 403);
], 404);
}
$plantCode = $request->header('plant-code');
@@ -444,7 +444,7 @@ class PdfController extends Controller
return response()->json([
'status_code' => 'ERROR',
'status_description' => 'GR Number cannot be empty!',
], 403);
], 404);
}
$plant = Plant::where('code', $plantCode)->first();
@@ -526,7 +526,7 @@ class PdfController extends Controller
return response()->json([
'status_code' => 'ERROR',
'status_description' => 'Invalid authorization token!',
], 403);
], 404);
}
$plantCode = $request->header('plant-code');
@@ -542,7 +542,7 @@ class PdfController extends Controller
return response()->json([
'status_code' => 'ERROR',
'status_description' => 'Process Order cannot be empty!',
], 403);
], 404);
}
$plant = Plant::where('code', $plantCode)->first();
@@ -596,14 +596,14 @@ class PdfController extends Controller
return response()->json([
'status_code' => 'ERROR',
'status_description' => "Process order '{$processOrder}' for plant '{$plantCode}' has already reached its order quantity.",
], 400);
], 404);
}
// if ($totalReceivedQty > $proOrdAgPlant->order_quantity) {
// return response()->json([
// 'status_code' => 'ERROR',
// 'status_description' => "Process order '{$processOrder}' for plant '{$plantCode}' received quantity is more than its order quantity."
// ], 400);
// ], 404);
// }
return response()->json([
@@ -628,107 +628,229 @@ class PdfController extends Controller
return response()->json([
'status_code' => 'ERROR',
'status_description' => 'Invalid authorization token!',
], 403);
], 404);
}
Log::info('POST : Process Orders API called', ['request_data' => $request->all()]);
$plantCode = $request->header('plant-code');
$processOrder = $request->header('process-order');
$data = $request->all();
if (! $plantCode || ! $processOrder) {
Log::info('Process Order POST API >>', ['plant-code' => $plantCode, 'process-order' => $processOrder, 'post-data' => $data]);
if ($plantCode == null || $plantCode == '' || ! $plantCode) {
return response()->json([
'status_code' => 'ERROR',
'status_description' => 'plant-code and process-order are required',
], 400);
'status_description' => "Plant code can't be empty!",
], 404);
} elseif (! is_numeric($plantCode) || Str::length($plantCode) < 4 || ! preg_match('/^[1-9]\d{3,}$/', $plantCode)) { // !ctype_digit($data['plant_code'])
return response()->json([
'status_code' => 'ERROR',
'status_description' => 'Invalid plant code found!',
], 404);
}
if (! $processOrder) {
return response()->json([
'status_code' => 'ERROR',
'status_description' => 'Process-order are required!',
], 404);
}
$plant = Plant::where('code', $plantCode)->first();
if (! $plant) {
return response()->json([
'status_code' => 'ERROR',
'status_description' => 'Invalid plant code',
'status_description' => "Plant code '{$plantCode}' not found!",
], 404);
}
$plantId = $plant->id;
$validated = $request->validate([
'item_code' => 'nullable|integer',
'coil_number' => 'nullable|string',
'order_quantity' => 'nullable|integer',
'received_quantity' => 'nullable|numeric',
'created_by' => 'nullable|string',
]);
$itemCode = $data['item_code'] ?? '';
$coilNo = $data['coil_number'] ?? '';
$orderQty = $data['order_quantity'] ?? 0;
$receivedQty = $data['received_quantity'] ?? 0;
$sfgNo = $data['sfg_number'] ?? '';
$machineId = $data['machine_id'] ?? '';
$createdBy = $data['created_by'] ?? '';
$item = Item::where('code', $validated['item_code'])
->where('plant_id', $plantId)
->first();
// $validated = $request->validate([
// 'item_code' => 'nullable|integer',
// 'coil_number' => 'nullable|string',
// 'order_quantity' => 'nullable|integer',
// 'received_quantity' => 'nullable|numeric',
// 'sfg_number' => 'nullable|string',
// 'machine_id' => 'nullable|string',
// 'created_by' => 'nullable|string',
// ]);
if (! $item) {
if ($itemCode == null || $itemCode == '' || ! $itemCode) {
return response()->json([
'message' => 'Invalid item_code for this plant',
'status_code' => 'ERROR',
'status_description' => "Item code can't be empty!",
], 404);
} elseif (Str::length($itemCode) < 6) {
return response()->json([
'status_code' => 'ERROR',
'status_description' => 'Item code should contain minimum 6 digits!',
], 404);
} elseif (! ctype_alnum($itemCode)) {
return response()->json([
'status_code' => 'ERROR',
'status_description' => 'Item code should contain only alpha-numeric values!',
], 404);
}
$createdBy = $validated['created_by'] ?? null;
if ($coilNo == null || $coilNo == '') {
return response()->json([
'status_code' => 'ERROR',
'status_description' => "Coil number can't be empty!",
], 404);
} elseif (! is_numeric($coilNo) || Str::length($coilNo) <= 0 || ! preg_match('/^\d{1,}$/', $coilNo)) { // !ctype_digit($data['plant_code'])
return response()->json([
'status_code' => 'ERROR',
'status_description' => 'Invalid coil number found!',
], 404);
}
// if ($sfgNo == null || $sfgNo == '' || ! $sfgNo) {
// return response()->json([
// 'status_code' => 'ERROR',
// 'status_description' => "SFG number can't be empty!",
// ], 404);
// }
// if ($machineId == null || $machineId == '' || ! $machineId) {
// return response()->json([
// 'status_code' => 'ERROR',
// 'status_description' => "Machine ID can't be empty!",
// ], 404);
// }
if ($createdBy == null || $createdBy == '' || ! $createdBy) {
return response()->json([
'status_code' => 'ERROR',
'status_description' => "User name can't be empty!",
], 404);
} elseif ($createdBy == 'jothi') {
$createdBy = 'Admin';
}
$user = User::where('name', $createdBy)->first();
$userPlant = User::where('name', $createdBy)->where('plant_id', $plantId)->first();
if (! $user) {
return response()->json([
'status_code' => 'ERROR',
'status_description' => "User '{$createdBy}' not found",
'status_description' => "User name '{$createdBy}' not found!",
], 404);
} elseif (! $userPlant && ! $user->hasRole('Super Admin')) {
return response()->json([
'status_code' => 'ERROR',
'status_description' => "User name '{$createdBy}' not found for the plant code '{$plantCode}'!",
], 404);
} elseif (! $user->hasRole('Super Admin') && ! $user->hasRole('Process Employee') && ! $user->hasRole('Process Supervisor')) {
return response()->json([
'status_code' => 'ERROR',
'status_description' => 'User does not have rights!',
], 404);
}
$existing = ProcessOrder::where('plant_id', $plant->id)
$item = Item::where('code', $itemCode)->first();
if (! $item) {
return response()->json([
'status_code' => 'ERROR',
'status_description' => "Item code '{$itemCode}' not found!",
], 404);
}
$itemPlant = Item::where('code', $itemCode)
->where('plant_id', $plantId)
->first();
if (! $itemPlant) {
return response()->json([
'status_code' => 'ERROR',
'status_description' => "Item code '{$itemCode}' not found for the plant code '{$plantCode}'!",
], 404);
}
$itemId = $itemPlant->id;
if ($sfgNo != null && $sfgNo != '' && Str::length($sfgNo) > 0 && $sfgNo) {
$existing = ProcessOrder::where('plant_id', $plantId)
->where('sfg_number', $sfgNo)
->first();
if ($existing) {
return response()->json([
'status_code' => 'ERROR',
'status_description' => "SFG number '{$sfgNo}' already exist for the plant code '{$plantCode}'!",
], 404);
}
} else {
$sfgNo = null;
}
$existing = ProcessOrder::where('plant_id', $plantId)
->where('process_order', $processOrder)
->where('item_id', '!=', $item->id)
->where('item_id', '!=', $itemId)
->first();
if ($existing) {
return response()->json([
'status_code' => 'ERROR',
'status_description' => "Process order '{$processOrder}' for plant '{$plantCode}' already has item_code '{$existing->item->code}'",
], 409);
'status_description' => "Process order '{$processOrder}' already has item_code '{$existing->item->code}' for the plant code '{$plantCode}'!",
], 404);
}
$alreadyReceived = ProcessOrder::where('plant_id', $plant->id)
$existing = ProcessOrder::where('plant_id', $plantId)
->where('process_order', $processOrder)
->where('item_id', $item->id)
->where('coil_number', $coilNo)
->first();
if ($existing) {
return response()->json([
'status_code' => 'ERROR',
'status_description' => "Process order '{$processOrder}' with coil number '{$coilNo}' already exist for the plant code '{$plantCode}'!",
], 404);
}
$alreadyReceived = ProcessOrder::where('plant_id', $plantId)
->where('process_order', $processOrder)
->where('item_id', $itemId)
->sum('received_quantity');
$newReceived = $validated['received_quantity'] ?? 0;
$orderQty = $validated['order_quantity'] ?? 0;
if ($orderQty == 0) {
$orderQty = ProcessOrder::where('plant_id', $plant->id)
$orderQty = ProcessOrder::where('plant_id', $plantId)
->where('process_order', $processOrder)
->where('item_id', $item->id)
->where('item_id', $itemId)
->value('order_quantity') ?? 0;
}
$total = $alreadyReceived + $newReceived;
$total = $alreadyReceived + $receivedQty;
if ($total > $orderQty) {
return response()->json([
'status_code' => 'ERROR',
'status_description' => "Received quantity cannot exceed order quantity.
Order Qty = {$orderQty}, Already Received = {$alreadyReceived},Trying to Insert = {$newReceived}",
'status_description' => "Received quantity should not exceed order quantity! Order Qty = {$orderQty}, Already Received Qty = {$alreadyReceived}, Trying to Insert Qty = {$receivedQty}",
], 404);
}
try {
ProcessOrder::Create(
[
'plant_id' => $plant->id,
'plant_id' => $plantId,
'process_order' => $processOrder,
'item_id' => $item->id,
'coil_number' => $validated['coil_number'] ?? '',
'order_quantity' => $validated['order_quantity'] ?? 0,
'received_quantity' => $validated['received_quantity'] ?? 0,
'created_by' => $validated['created_by'] ?? '',
'item_id' => $itemId,
'coil_number' => $coilNo,
'order_quantity' => $orderQty,
'received_quantity' => $receivedQty,
'sfg_number' => $sfgNo,
'machine_name' => $machineId,
'created_by' => $createdBy,
]
);

View File

@@ -2,7 +2,6 @@
namespace App\Livewire;
use App\Filament\Resources\InvoiceValidationResource\Pages\CreateInvoiceValidation;
use App\Models\InvoiceValidation;
use App\Models\StickerMaster;
use Filament\Facades\Filament;
@@ -34,14 +33,14 @@ class InvoiceDataTable extends Component
public bool $showCapacitorInput = false;
// protected $listeners = ['refreshInvoiceData' => 'loadData',];
// protected $listeners = ['refreshInvoiceData' => 'loadData',];
protected $listeners = [
'refreshCompletedInvoice' => 'loadCompletedData',
'refreshEmptyInvoice' => 'loadEmptyData',
'refreshInvoiceData' => 'loadData',
'refreshMaterialInvoiceData' => 'loadMaterialData',
'openCapacitorModal' => 'showCapacitorInputBox'
'openCapacitorModal' => 'showCapacitorInputBox',
];
public $capacitorInput = '';
@@ -96,101 +95,83 @@ class InvoiceDataTable extends Component
$this->materialInvoice = false;
// $this->showCapacitorInput = false;
//->where('serial_number', '!=', '')
// ->where('serial_number', '!=', '')
$this->invoiceData = InvoiceValidation::where('invoice_number', $this->invoiceNumber)
->where('plant_id', $plantId)->where('scanned_status', null)
->get()
->map(function ($record) {
return [
'sticker_master_id' => $record->sticker_master_id,
'serial_number' => $record->serial_number,
'motor_scanned_status' => $record->motor_scanned_status ?? '',
'pump_scanned_status' => $record->pump_scanned_status ?? '',
'capacitor_scanned_status' => $record->capacitor_scanned_status ?? '',
'scanned_status_set' => $record->scanned_status_set ?? '',
'scanned_status' => $record->scanned_status ?? '',
'panel_box_supplier' => $record->panel_box_supplier ?? '',
'panel_box_serial_number' => $record->panel_box_serial_number ?? '',
'created_at' => $record->created_at,
'operator_id' => $record->operator_id,
];
})
->toArray();
->where('plant_id', $plantId)->where('scanned_status', null)
->get()
->map(function ($record) {
return [
'sticker_master_id' => $record->sticker_master_id,
'serial_number' => $record->serial_number,
'motor_scanned_status' => $record->motor_scanned_status ?? '',
'pump_scanned_status' => $record->pump_scanned_status ?? '',
'capacitor_scanned_status' => $record->capacitor_scanned_status ?? '',
'scanned_status_set' => $record->scanned_status_set ?? '',
'scanned_status' => $record->scanned_status ?? '',
'panel_box_supplier' => $record->panel_box_supplier ?? '',
'panel_box_serial_number' => $record->panel_box_serial_number ?? '',
'created_at' => $record->created_at,
'operator_id' => $record->operator_id,
];
})
->toArray();
$this->packageCount = 0;
//Loop through and replace 'code' using related StickerMaster > Item > code
// Loop through and replace 'code' using related StickerMaster > Item > code
foreach ($this->invoiceData as &$row) {
$stickCount = 0;
$scannedCount = 0;
// $stickerMaster = \App\Models\StickerMaster::with('item')->find($row['sticker_master_id'] ?? null);
// $stickerMaster = \App\Models\StickerMaster::with('item')->find($row['sticker_master_id'] ?? null);
$row['code'] = StickerMaster::with('item')->find($row['sticker_master_id'] ?? null)?->item?->code ?? 'N/A';
$curStick = StickerMaster::where('id', $row['sticker_master_id'])->first();
if ($curStick)
{
if ($curStick->tube_sticker_motor == 1 || $curStick->tube_sticker_pump == 1 || $curStick->tube_sticker_pumpset == 1 || Str::length($curStick->panel_box_code) > 0)
{
if ($curStick->tube_sticker_motor == 1)
{
$stickCount++;
}
if ($curStick->tube_sticker_pump == 1)
{
$stickCount++;
}
if ($curStick->tube_sticker_pumpset == 1)
{
$stickCount++;
}
if (Str::length($curStick->panel_box_code) > 0)
{
$stickCount++;
}
if ($curStick) {
if (Str::length($curStick->panel_box_code) > 0) {
$stickCount++;
}
else if ($curStick->pack_slip_motor == 1 || $curStick->pack_slip_pump == 1 || $curStick->pack_slip_pumpset == 1)
{
if ($curStick->pack_slip_motor == 1)
{
if ($curStick->tube_sticker_motor == 1 || $curStick->tube_sticker_pump == 1 || $curStick->tube_sticker_pumpset == 1) {
if ($curStick->tube_sticker_motor == 1) {
$stickCount++;
}
if ($curStick->pack_slip_pump == 1)
{
if ($curStick->tube_sticker_pump == 1 || ($curStick->tube_sticker_pumpset != 1 && $curStick->tube_sticker_pump != 1 && $curStick->pack_slip_pump == 1)) {
$stickCount++;
}
if ($curStick->pack_slip_pumpset == 1)
{
if ($curStick->tube_sticker_pumpset == 1) {
$stickCount++;
}
} elseif ($curStick->pack_slip_motor == 1 || $curStick->pack_slip_pump == 1 || $curStick->pack_slip_pumpset == 1) {
if ($curStick->pack_slip_motor == 1) {
$stickCount++;
}
if ($curStick->pack_slip_pump == 1) {
$stickCount++;
}
if ($curStick->pack_slip_pumpset == 1) {
$stickCount++;
}
}
}
if ($row['motor_scanned_status'] == 1)
{
if ($row['motor_scanned_status'] == 1) {
$scannedCount++;
}
if ($row['pump_scanned_status'] == 1)
{
if ($row['pump_scanned_status'] == 1) {
$scannedCount++;
}
if ($row['capacitor_scanned_status'] == 1)
{
if ($row['capacitor_scanned_status'] == 1) {
$scannedCount++;
}
if ($row['scanned_status_set'] == 1)
{
if ($row['scanned_status_set'] == 1) {
$scannedCount++;
}
$this->packageCount += $stickCount - $scannedCount;
}
if ($onCapFocus)
{
if ($onCapFocus) {
$this->dispatch('focus-capacitor-input');
}
else
{
} else {
$this->dispatch('focus-serial-number');
}
}
@@ -207,43 +188,36 @@ class InvoiceDataTable extends Component
$this->materialInvoice = true;
// $this->showCapacitorInput = false;
//->where('serial_number', '!=', '')
// ->where('serial_number', '!=', '')
$this->invoiceData = InvoiceValidation::where('invoice_number', $this->invoiceNumber)->where('plant_id', $plantId)->where('serial_number', null)
->get()
->map(function ($record) {
return [
'sticker_master_id' => $record->sticker_master_id,
// 'material_type' => StickerMaster::where('id', $record->sticker_master_id)->first()->material_type ?? '',
'quantity' => $record->quantity ?? '',
'serial_number' => $record->serial_number ?? '',
'batch_number' => $record->batch_number ?? '',
'created_at' => $record->created_at,
'operator_id' => $record->operator_id,
];
})
->toArray();
->get()
->map(function ($record) {
return [
'sticker_master_id' => $record->sticker_master_id,
// 'material_type' => StickerMaster::where('id', $record->sticker_master_id)->first()->material_type ?? '',
'quantity' => $record->quantity ?? '',
'serial_number' => $record->serial_number ?? '',
'batch_number' => $record->batch_number ?? '',
'created_at' => $record->created_at,
'operator_id' => $record->operator_id,
];
})
->toArray();
//Loop through and replace 'code' using related StickerMaster > Item > code
// Loop through and replace 'code' using related StickerMaster > Item > code
foreach ($this->invoiceData as &$row) {
// $stickerMaster = \App\Models\StickerMaster::with('item')->find($row['sticker_master_id'] ?? null);
$row['code'] = StickerMaster::with('item')->find($row['sticker_master_id'] ?? null)?->item?->code ?? 'N/A';
$matType = StickerMaster::where('id', $row['sticker_master_id'] ?? null)->first()->material_type ?? '';
if ($matType === 1)
{
// $stickerMaster = \App\Models\StickerMaster::with('item')->find($row['sticker_master_id'] ?? null);
$row['code'] = StickerMaster::with('item')->find($row['sticker_master_id'] ?? null)?->item?->code ?? 'N/A';
$matType = StickerMaster::where('id', $row['sticker_master_id'] ?? null)->first()->material_type ?? '';
if ($matType === 1) {
$row['material_type'] = 'Individual';
}
else if ($matType === 2)
{
} elseif ($matType === 2) {
$row['material_type'] = 'Bundle';
}
else if ($matType === 3)
{
} elseif ($matType === 3) {
$row['material_type'] = 'Quantity';
}
else
{
} else {
$row['material_type'] = 'N/A';
}
}
}
$this->dispatch('focus-serial-number');
}
@@ -275,11 +249,11 @@ class InvoiceDataTable extends Component
$user = Filament::auth()->user();
$operatorName = $user->name;
if (!$this->capacitorInput) {
if (! $this->capacitorInput) {
return;
}
if (!preg_match('/^[^\/]+\/[^\/]+\/.+$/', $this->capacitorInput)) {
if (! preg_match('/^[^\/]+\/[^\/]+\/.+$/', $this->capacitorInput)) {
Notification::make()
->title('Invalid Panel Box QR Format:')
->body('Scan the valid panel box QR code to proceed!')
@@ -287,6 +261,7 @@ class InvoiceDataTable extends Component
// ->duration(3000)
->seconds(2)
->send();
return;
}
@@ -298,9 +273,9 @@ class InvoiceDataTable extends Component
$existsInStickerMaster = StickerMaster::where('panel_box_code', $itemCode)->where('plant_id', $this->plantId)->whereHas('item', function ($query) {
$query->where('code', $this->currentItemCode);
})
->exists();
->exists();
if (!$existsInStickerMaster) {
if (! $existsInStickerMaster) {
Notification::make()
->title('Unknown: Panel Box Code')
->body("Unknown panel box code: $itemCode found for item code: $this->currentItemCode")
@@ -309,12 +284,12 @@ class InvoiceDataTable extends Component
->seconds(2)
->send();
$this->capacitorInput = '';
return;
}
foreach ($this->invoiceData as &$row) {
if (($row['code'] ?? '') === $this->currentItemCode && ($row['serial_number'] ?? '') === $this->currentSerialNumber)
{
if (($row['code'] ?? '') === $this->currentItemCode && ($row['serial_number'] ?? '') === $this->currentSerialNumber) {
$row['panel_box_supplier'] = $supplier;
$row['panel_box_item_code'] = $itemCode;
$row['panel_box_serial_number'] = $serialNumber;
@@ -343,47 +318,41 @@ class InvoiceDataTable extends Component
$packCnt = 1;
$scanCnt = 1;
// if ($hadMotorQr === $hasMotorQr && $hadPumpQr === $hasPumpQr && $hadPumpSetQr === $hasPumpSetQr)
if ($hasMotorQr || $hasPumpQr || $hasPumpSetQr)
{
if ($hasMotorQr || $hasPumpQr || $hasPumpSetQr) {
$packCnt = $hasMotorQr ? $packCnt + 1 : $packCnt;
$packCnt = $hasPumpQr ? $packCnt + 1 : $packCnt;
$packCnt = $hasPumpSetQr ? $packCnt + 1 : $packCnt;
$scanCnt = $hadMotorQr ? $scanCnt + 1: $scanCnt;
$scanCnt = $hadPumpQr ? $scanCnt + 1: $scanCnt;
$scanCnt = $hadPumpSetQr ? $scanCnt + 1: $scanCnt;
$scanCnt = $hadMotorQr ? $scanCnt + 1 : $scanCnt;
$scanCnt = $hadPumpQr ? $scanCnt + 1 : $scanCnt;
$scanCnt = $hadPumpSetQr ? $scanCnt + 1 : $scanCnt;
if ($packCnt === $scanCnt)
{
if ($packCnt === $scanCnt) {
$matchingValidation->update([
'panel_box_supplier' => $supplier,
'panel_box_item_code' => $itemCode,
'panel_box_serial_number' => $serialNumber,
'capacitor_scanned_status' => 1,
'scanned_status' => 'Scanned',
'operator_id'=> $operatorName,
'operator_id' => $operatorName,
]);
}
else
{
} else {
$matchingValidation->update([
'panel_box_supplier' => $supplier,
'panel_box_item_code' => $itemCode,
'panel_box_serial_number' => $serialNumber,
'capacitor_scanned_status' => 1,
'operator_id'=> $operatorName,
'operator_id' => $operatorName,
]);
}
}
else
{
} else {
$matchingValidation->update([
'panel_box_supplier' => $supplier,
'panel_box_item_code' => $itemCode,
'panel_box_serial_number' => $serialNumber,
'capacitor_scanned_status' => 1,
'scanned_status' => 'Scanned',
'operator_id'=> $operatorName,
'operator_id' => $operatorName,
]);
}
@@ -398,15 +367,14 @@ class InvoiceDataTable extends Component
$totalQuantity = InvoiceValidation::where('invoice_number', $matchingValidation->invoice_number)->where('plant_id', $this->plantId)->count();
$scannedQuantity = InvoiceValidation::where('invoice_number', $matchingValidation->invoice_number)->where('plant_id', $this->plantId)->where('scanned_status', 'Scanned')->count();
// $this->form->fill([
// 'plant_id' => $matchingValidation->plant_id,
// 'invoice_number' => $matchingValidation->invoice_number,
// 'serial_number' => null,
// 'total_quantity' => $totalQuantity,
// 'scanned_quantity'=> $scannedQuantity,
// ]);
// 'plant_id' => $matchingValidation->plant_id,
// 'invoice_number' => $matchingValidation->invoice_number,
// 'serial_number' => null,
// 'total_quantity' => $totalQuantity,
// 'scanned_quantity'=> $scannedQuantity,
// ]);
if ($totalQuantity === $scannedQuantity)
{
if ($totalQuantity === $scannedQuantity) {
Notification::make()
->title('Completed: Serial Invoice')
->body("Serial invoice '$matchingValidation->invoice_number' completed the scanning process.<br>Scan the next 'Serial Invoice' to proceed!")
@@ -414,9 +382,7 @@ class InvoiceDataTable extends Component
->seconds(2)
->send();
$this->loadCompletedData($matchingValidation->invoice_number, $matchingValidation->plant_id, true);
}
else
{
} else {
$this->loadData($matchingValidation->invoice_number, $matchingValidation->plant_id, false);
}
}
@@ -427,7 +393,7 @@ class InvoiceDataTable extends Component
$this->showCapacitorInput = false;
$this->capacitorInput = '';
$this->dispatch('updateScannedQuantity');
//$this->loadData($this->invoiceNumber, $this->plantId);
// $this->loadData($this->invoiceNumber, $this->plantId);
$this->dispatch('focus-serial-number');
}
@@ -435,5 +401,4 @@ class InvoiceDataTable extends Component
{
return view('livewire.invoice-data-table');
}
}

View File

@@ -0,0 +1,55 @@
<?php
namespace App\Livewire;
use Livewire\Component;
use App\Models\StickerPrinting;
class StickerPrintData extends Component
{
public $plantId;
public $refNumber;
public $serialNumber;
public bool $materialInvoice = false;
public $records = [];
protected $listeners = [
'refreshEmptySticker' => 'loadStickerData',
'addStickerToList' => 'loadSticker'
];
public function loadStickerData($plantId, $refNumber)
{
$this->plantId = $plantId;
$this->refNumber = $refNumber;
$this->materialInvoice = true;
$this->records = StickerPrinting::where('plant_id', $plantId)
->where('reference_number', $refNumber)
->orderBy('created_at', 'asc')
->get(['serial_number', 'created_by']);
}
public function loadSticker($plantId, $refNumber, $serialNumber)
{
$this->plantId = $plantId;
$this->refNumber = $refNumber;
$this->materialInvoice = true;
$this->records = StickerPrinting::where('plant_id', $plantId)
->where('reference_number', $refNumber)
->orderBy('created_at', 'asc')
->get(['serial_number', 'created_by']);
}
public function render()
{
return view('livewire.sticker-print-data');
}
}

View File

@@ -2,13 +2,13 @@
namespace App\Mail;
use App\Models\InvoiceDataValidation;
use DateTime;
use Illuminate\Bus\Queueable;
use Illuminate\Contracts\Queue\ShouldQueue;
use Illuminate\Mail\Mailable;
use Illuminate\Mail\Mailables\Content;
use Illuminate\Mail\Mailables\Envelope;
use Illuminate\Queue\SerializesModels;
use DateTime;
class InvoiceDataMail extends Mailable
{
@@ -23,7 +23,7 @@ class InvoiceDataMail extends Mailable
/**
* Create a new message instance.
*/
public function __construct($scheduleType, $tableData = [], $mailSubject)
public function __construct($scheduleType, $tableData, $mailSubject)
{
$this->scheduleType = $scheduleType;
$this->tableData = $tableData ?? [];
@@ -48,17 +48,19 @@ class InvoiceDataMail extends Mailable
$greeting = 'Dear Sir/Madam,<br><br>We are sending here with list of "Despatch pending sale invoice & STO invoice as on date"';
if ($this->scheduleType == 'Daily') {
$firstRecord = \App\Models\InvoiceDataValidation::orderBy('document_date', 'asc')->first();
//$lastRecord = \App\Models\InvoiceDataValidation::orderBy('document_date', 'desc')->first();
$firstRecord = InvoiceDataValidation::orderBy('document_date', 'asc')->first(); // 'desc'
if ($firstRecord) {
$startDate = null;
if ($firstRecord && $firstRecord?->document_date != null && $firstRecord?->document_date != '') {
$startDate = \Carbon\Carbon::parse($firstRecord->document_date)->startOfDay();
//$endDate = \Carbon\Carbon::parse($lastRecord->document_date)->endOfDay();
// $endDate = \Carbon\Carbon::parse($lastRecord->document_date)->endOfDay();
} else {
$startDate = now()->subDay()->setTime(10, 0, 0);
}
$endDate = now()->setTime(10, 0, 0);
// $fromDate = (new DateTime('yesterday 10:00'))->format('d/m/Y H:i') . ':000';//08:00
// $toDate = (new DateTime('today 09:59'))->format('d/m/Y H:i') . ':999';//07:59
// $toDate = (new DateTime('today 09:59')) ->format('d/m/Y H:i') . ':999';//07:59
$reportPeriod = "from: $startDate to $endDate\".<br><br>Please arrange to despatch the same immediately.";
$greeting .= $reportPeriod;
}
@@ -74,17 +76,17 @@ class InvoiceDataMail extends Mailable
if ($this->scheduleType == 'Live') {
$now = now();
$fromMinute = $now->copy()->subMinute()->format('d/m/Y H:i:s');
$toMinute = $now->format('d/m/Y H:i:s');
$toMinute = $now->format('d/m/Y H:i:s');
$greeting .= "from: $fromMinute to $toMinute. <br><br>Please arrange to despatch the same immediately.";
}
return new Content(
view: 'mail.invoice_data_report',
with: [
'company' => "CRI Digital Manufacturing Solutions",
'company' => 'CRI Digital Manufacturing Solutions',
'greeting' => $greeting,
'tableData' => $this->tableData,
'wishes' => "Thanks & Regards,<br>CRI Digital Manufacturing Solutions"
'wishes' => 'Thanks & Regards,<br>CRI Digital Manufacturing Solutions',
],
);
}

View File

@@ -0,0 +1,29 @@
<?php
namespace App\Models;
use Illuminate\Database\Eloquent\Model;
use Illuminate\Database\Eloquent\Relations\BelongsTo;
use Illuminate\Database\Eloquent\SoftDeletes;
class StickerPrinting extends Model
{
//
use SoftDeletes;
protected $fillable = [
'plant_id',
'reference_number',
'serial_number',
'created_at',
'updated_at',
'created_by',
'updated_by',
];
public function plant(): BelongsTo
{
return $this->belongsTo(Plant::class);
}
}

View File

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

View File

@@ -2,19 +2,19 @@
namespace App\Providers;
use App\Models\AlertMailRule;
use App\Models\User;
use Filament\Facades\FilamentView;
use Illuminate\Support\Facades\Gate;
use Illuminate\Support\ServiceProvider;
use App\Policies\RolePolicy;
use App\Policies\PermissionPolicy;
use Spatie\Permission\Models\Role;
use Spatie\Permission\Models\Permission;
use Filament\Support\Facades\FilamentAsset;
use App\Policies\RolePolicy;
use Filament\Support\Assets\Js;
use Filament\Support\Facades\FilamentAsset;
use Illuminate\Console\Scheduling\Schedule;
use Illuminate\Support\Facades\Gate;
use Illuminate\Support\Facades\View;
use Illuminate\Support\Facades\Vite;
use Illuminate\Support\ServiceProvider;
use Spatie\Permission\Models\Permission;
use Spatie\Permission\Models\Role;
// use Doctrine\DBAL\Types\Type;
@@ -28,7 +28,6 @@ class AppServiceProvider extends ServiceProvider
//
}
/**
* Bootstrap any application services.
*/
@@ -42,21 +41,21 @@ class AppServiceProvider extends ServiceProvider
// });
Gate::before(function (User $user, string $ability) {
return $user->isSuperAdmin() ? true: null;
return $user->isSuperAdmin() ? true : null;
});
// FilamentAsset::register([
// Js::make('chart-js-plugins', Vite::asset('resources/js/filament-chart-js-plugins.js'))->module(),
// ]);
FilamentAsset::register([
Js::make('chart-js-plugins', Vite::asset('resources/js/filament-chart-js-plugins.js'))->module(),
Js::make('chart-js-plugins', Vite::asset('resources/js/filament-chart-js-plugins.js'))->module(),
]);
// if (env('APP_MODE') === 'admin') {
// FilamentAsset::register([
// Js::make('chart-js-plugins', Vite::asset('resources/js/filament-chart-js-plugins.js'))->module(),
// ]);
// }
// if (env('APP_MODE') === 'admin') {
// FilamentAsset::register([
// Js::make('chart-js-plugins', Vite::asset('resources/js/filament-chart-js-plugins.js'))->module(),
// ]);
// }
// URL::forceScheme('https');
@@ -70,5 +69,82 @@ class AppServiceProvider extends ServiceProvider
ini_set('max_execution_time', 300); // 300 seconds = 5 minutes
ini_set('memory_limit', '512M'); // 512MB
// $schedule = app(Schedule::class);
// $productionRules = AlertMailRule::where('module', 'ProductionQuantities')
// ->where('rule_name', 'ProductionMail')
// ->select('plant', 'schedule_type')
// ->distinct()
// ->get();
// foreach ($productionRules as $rule) {
// $type = $rule->schedule_type;
// $plantId = $rule->plant;
// $command = $schedule->command('send:production-report', [$type, $plantId]);
// // ->appendOutputTo(storage_path('logs/scheduler.log'));
// switch ($type) {
// case 'Live':
// $command->everyMinute();
// break;
// case 'Hourly':
// $command->hourly();
// break;
// case 'Daily':
// $command->dailyAt('07:59');
// break;
// }
// }
// // Invoice report scheduling
// $invoiceRules = AlertMailRule::where('module', 'InvoiceValidation')
// ->select('plant', 'schedule_type')
// ->distinct()
// ->get();
// foreach ($invoiceRules as $rule) {
// $type = $rule->schedule_type;
// $plantId = $rule->plant;
// $command = $schedule->command('send:invoice-report', [$type, $plantId]);
// switch ($type) {
// case 'Live':
// $command->everyMinute();
// break;
// case 'Hourly':
// $command->hourly();
// break;
// case 'Daily':
// $command->dailyAt('07:59');
// break;
// }
// }
// // Invoice Data Report Scheduling
// $invoiceDataRules = AlertMailRule::where('module', 'InvoiceDataReport')
// ->select('plant', 'schedule_type')
// ->distinct()
// ->get();
// foreach ($invoiceDataRules as $rule) {
// $type = $rule->schedule_type;
// $plantId = $rule->plant;
// $command = $schedule->command('send:invoice-data-report', [$type, $plantId]);
// switch ($type) {
// case 'Live':
// $command->everyMinute();
// break;
// case 'Hourly':
// $command->hourly();
// break;
// case 'Daily':
// $command->dailyAt('10:00');
// break;
// }
// }
}
}

View File

@@ -213,6 +213,8 @@ return [
'user_model' => \App\Models\User::class,
// 'user_model_class' => \App\Models\User::class,
'policies_namespace' => 'App\Policies',
],
];

View File

@@ -0,0 +1,40 @@
<?php
use Illuminate\Database\Migrations\Migration;
use Illuminate\Support\Facades\Schema;
return new class extends Migration
{
/**
* Run the migrations.
*/
public function up(): void
{
$sql = <<<'SQL'
CREATE TABLE sticker_printings (
id BIGINT GENERATED always AS IDENTITY PRIMARY KEY,
plant_id BIGINT NOT NULL,
reference_number TEXT DEFAULT NULL,
serial_number 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,
FOREIGN KEY (plant_id) REFERENCES plants (id)
);
SQL;
DB::statement($sql);
}
/**
* Reverse the migrations.
*/
public function down(): void
{
Schema::dropIfExists('sticker_printings');
}
};

View File

@@ -169,6 +169,7 @@ class PermissionSeeder extends Seeder
Permission::updateOrCreate(['name' => 'view import process order']);
Permission::updateOrCreate(['name' => 'view export process order']);
Permission::updateOrCreate(['name' => 'view import sticker printing']);
Permission::updateOrCreate(['name' => 'view export sticker printing']);
}
}

View File

@@ -0,0 +1,24 @@
<x-filament::page>
<form wire:submit.prevent="create" class="space-y-6">
{{-- Form Section --}}
<div class="filament-form space-y-6">
{{ $this->form }}
</div>
{{-- <livewire:notification-sound /> --}}
{{-- Livewire Component (Invoice Table) --}}
<div class="bg-white shadow rounded-xl p-4">
<livewire:sticker-print-data :ref-data="$ref_number" />
</div>
{{-- Actions --}}
<div class="filament-actions mt-6">
<x-filament::actions>
@foreach ($this->getFormActions() as $action)
{{ $action }}
@endforeach
</x-filament::actions>
</div>
</form>
</x-filament::page>

View File

@@ -0,0 +1,23 @@
{{-- <div class="flex flex-col items-start space-y-2">
<button
type="button"
wire:click="printSticker"
class="mt-15 px-2 py-1 border border-primary-500 text-primary-600 rounded hover:bg-primary-50 hover:border-primary-700 transition text-sm"
>
Print
</button>
</div> --}}
<div class="flex flex-col items-start space-y-2">
<button
type="button"
wire:click="printSticker"
class="px-2 py-1 border border-primary-500 text-primary-600 bg-white rounded hover:bg-primary-50 hover:border-primary-700 transition text-sm"
style="margin-top: 10mm;"
>
Print
</button>
</div>

View File

@@ -0,0 +1,81 @@
{{-- <div class="overflow-x-auto overflow-y-visible" style="height: 385px;">
<table class="table-auto w-full border-collapse border">
<thead class="bg-gray-100">
<tr>
<th class="border p-2">No</th>
<th class="border p-2">Reference No</th>
<th class="border p-2">Serial Number</th>
<th class="border p-2">Created By</th>
</tr>
</thead>
<tbody>
@forelse($records as $index => $record)
<tr>
<td class="border p-2 text-center">{{ $index + 1 }}</td>
<td class="border p-2 text-center">{{ $refNumber }}</td>
<td class="border p-2 text-center">{{ $record['serial_number'] }}</td>
<td class="border p-2 text-center">{{ $record->created_by }}</td>
</tr>
@empty
<tr>
<td class="border p-2 text-center" colspan="4">No serial numbers found.</td>
</tr>
@endforelse
</tbody>
</table>
</div> --}}
<div>
<h3 class="text-lg font-semibold mb-2">Sticker Printing Table</h3>
<div
wire:loading.remove
@if(!$materialInvoice) style="display:none" @endif
class="overflow-x-auto overflow-y-visible"
style="height: 385px;"
>
<table class="table-auto w-full border-collapse border">
{{-- <thead class="bg-gray-100"> --}}
<thead class="bg-gray-100 text-xs">
<tr>
<th class="border p-2">No</th>
<th class="border p-2">Reference No</th>
<th class="border p-2">Serial Number</th>
<th class="border p-2">Created By</th>
</tr>
</thead>
{{-- <tbody> --}}
<tbody class="text-xs">
@forelse($records as $index => $record)
<tr>
<td class="border p-2 text-center">{{ $index + 1 }}</td>
<td class="border p-2 text-center">{{ $refNumber }}</td>
<td class="border p-2 text-center">{{ $record['serial_number'] }}</td>
<td class="border p-2 text-center">{{ $record->created_by }}</td>
</tr>
@empty
<tr>
<td class="border p-2 text-center" colspan="4">No serial numbers found.</td>
</tr>
@endforelse
</tbody>
</table>
</div>
<script>
window.addEventListener('focus-serial-number', () => {
setTimeout(() => {
const container = document.getElementById('serial_number_input');
const input = container?.querySelector('input'); // gets the actual input inside
if (input) {
input.focus();
input.select();
}
}, 50);
});
</script>

View File

@@ -0,0 +1,92 @@
{{-- <!DOCTYPE html>
<html>
<head>
<style>
body { text-align: center; font-family: Arial, sans-serif; }
.qr-container { margin-top: 30px; }
</style>
</head>
<body>
<div class="qr-container">
<img src="data:image/png;base64,{{ $qrCode }}" width="250" height="250">
</div>
</body>
</html> --}}
{{-- <!DOCTYPE html>
<html>
<head>
<style>
@page {
margin: 0;
size: 100mm 100mm;
}
body {
margin: 0;
padding: 0;
width: 100mm;
height: 100mm;
display: flex;
justify-content: center;
align-items: center;
}
img {
width: 100mm;
height: 100mm;
}
</style>
</head>
<body>
<img src="data:image/png;base64,{{ $qrCode }}" />
</body>
</html> --}}
<!DOCTYPE html>
<html>
<head>
<style>
@page {
margin: 0;
size: 100mm 100mm;
}
body {
margin: 0;
padding: 0;
width: 100mm;
height: 100mm;
display: flex;
flex-direction: column;
justify-content: center;
align-items: center;
text-align: center;
font-size: 12px;
font-family: Arial, sans-serif;
}
img {
width: 90mm; /* QR CODE REDUCED TO FIT TEXT */
height: 90mm;
}
.ref-text {
margin-top: 3mm;
font-size: 16px; /* Increased Font Size */
font-weight: bold;
}
</style>
</head>
<body>
<div class="ref-text">
{{ $referenceNumber }}
</div>
<img src="data:image/png;base64,{{ $qrCode }}" />
</body>
</html>

View File

@@ -1,10 +1,11 @@
<?php
use App\Models\AlertMailRule;
use Illuminate\Console\Scheduling\Schedule;
use Illuminate\Foundation\Inspiring;
use Illuminate\Support\Facades\Artisan;
use Illuminate\Support\Facades\Schema;
use App\Models\AlertMailRule;
use Illuminate\Console\Scheduling\Schedule;
Artisan::command('inspire', function () {
$this->comment(Inspiring::quote());
@@ -17,9 +18,6 @@ app()->booted(function () {
$schedule = app(Schedule::class);
// $schedule->command('report:send-daily-production')->dailyAt('07:59');
if (Schema::hasTable('alert_mail_rules')) {
// Production report scheduling
$productionRules = AlertMailRule::where('module', 'ProductionQuantities')
->where('rule_name', 'ProductionMail')
@@ -96,5 +94,4 @@ app()->booted(function () {
break;
}
}
}
});