158 Commits

Author SHA1 Message Date
dhanabalan
95b5a8efbb changed directory path in sftp files
Some checks failed
Scan for leaked secrets using Kingfisher / kingfisher-secrets-scan (push) Successful in 16s
Gemini PR Review / Gemini PR Review (pull_request) Failing after 17s
Scan for leaked secrets using Kingfisher / kingfisher-secrets-scan (pull_request) Successful in 16s
Laravel Pint / pint (pull_request) Successful in 3m47s
Laravel Larastan / larastan (pull_request) Failing after 5m15s
2026-11-06 21:01:03 +05:30
dhanabalan
5b440368ca Changed logic in sftp process files
Some checks failed
Scan for leaked secrets using Kingfisher / kingfisher-secrets-scan (push) Successful in 15s
Gemini PR Review / Gemini PR Review (pull_request) Failing after 17s
Scan for leaked secrets using Kingfisher / kingfisher-secrets-scan (pull_request) Successful in 18s
Laravel Larastan / larastan (pull_request) Failing after 4m17s
Laravel Pint / pint (pull_request) Successful in 5m8s
2026-11-06 20:56:10 +05:30
dhanabalan
8d36ea1ca2 changed navigation group for production calendar
Some checks failed
Scan for leaked secrets using Kingfisher / kingfisher-secrets-scan (push) Successful in 16s
Gemini PR Review / Gemini PR Review (pull_request) Failing after 17s
Scan for leaked secrets using Kingfisher / kingfisher-secrets-scan (pull_request) Successful in 15s
Laravel Pint / pint (pull_request) Successful in 2m55s
Laravel Larastan / larastan (pull_request) Failing after 4m27s
2026-11-06 20:00:33 +05:30
dhanabalan
33d5d33405 Rounded the value in produciton target livewire page
Some checks failed
Scan for leaked secrets using Kingfisher / kingfisher-secrets-scan (push) Successful in 16s
Gemini PR Review / Gemini PR Review (pull_request) Failing after 17s
Scan for leaked secrets using Kingfisher / kingfisher-secrets-scan (pull_request) Successful in 16s
Laravel Pint / pint (pull_request) Successful in 3m51s
Laravel Larastan / larastan (pull_request) Failing after 5m21s
2026-11-06 19:54:05 +05:30
dhanabalan
b4a1dbe29c Added importer logic in courier inward
Some checks failed
Scan for leaked secrets using Kingfisher / kingfisher-secrets-scan (push) Successful in 17s
Gemini PR Review / Gemini PR Review (pull_request) Failing after 20s
Scan for leaked secrets using Kingfisher / kingfisher-secrets-scan (pull_request) Successful in 15s
Laravel Pint / pint (pull_request) Successful in 3m10s
Laravel Larastan / larastan (pull_request) Failing after 6m4s
2026-11-06 19:37:52 +05:30
dhanabalan
f78c2ea300 Updated routine_test_time default value in resource page and example value in importer page
Some checks failed
Scan for leaked secrets using Kingfisher / kingfisher-secrets-scan (push) Successful in 16s
Gemini PR Review / Gemini PR Review (pull_request) Failing after 18s
Scan for leaked secrets using Kingfisher / kingfisher-secrets-scan (pull_request) Successful in 18s
Laravel Pint / pint (pull_request) Successful in 2m40s
Laravel Larastan / larastan (pull_request) Failing after 5m13s
2026-11-06 17:57:58 +05:30
dhanabalan
931b0ca206 Updated navigation sort order from 5 to 6
All checks were successful
Scan for leaked secrets using Kingfisher / kingfisher-secrets-scan (push) Successful in 15s
2026-11-06 17:55:08 +05:30
dhanabalan
1a6076b32a Updated navigation sort order from 4 to 5
All checks were successful
Scan for leaked secrets using Kingfisher / kingfisher-secrets-scan (push) Successful in 16s
2026-11-06 17:54:16 +05:30
dhanabalan
9140e62df2 Added clear serial numbers in random serial number livewire
Some checks failed
Scan for leaked secrets using Kingfisher / kingfisher-secrets-scan (push) Successful in 16s
Gemini PR Review / Gemini PR Review (pull_request) Failing after 16s
Scan for leaked secrets using Kingfisher / kingfisher-secrets-scan (pull_request) Successful in 16s
Laravel Larastan / larastan (pull_request) Failing after 4m29s
Laravel Pint / pint (pull_request) Successful in 4m28s
2026-11-06 16:52:21 +05:30
dhanabalan
3f4bc4e013 Added panel box regex pattern in create invoice validation page
Some checks failed
Scan for leaked secrets using Kingfisher / kingfisher-secrets-scan (push) Has been cancelled
Gemini PR Review / Gemini PR Review (pull_request) Failing after 22s
Scan for leaked secrets using Kingfisher / kingfisher-secrets-scan (pull_request) Successful in 19s
Laravel Larastan / larastan (pull_request) Failing after 48s
Laravel Pint / pint (pull_request) Successful in 2m50s
2026-11-06 16:49:46 +05:30
dhanabalan
2f7dcaee24 changed labels in courier outward exporter
Some checks failed
Scan for leaked secrets using Kingfisher / kingfisher-secrets-scan (push) Has been cancelled
Gemini PR Review / Gemini PR Review (pull_request) Failing after 20s
Scan for leaked secrets using Kingfisher / kingfisher-secrets-scan (pull_request) Successful in 16s
Laravel Pint / pint (pull_request) Successful in 3m28s
Laravel Larastan / larastan (pull_request) Failing after 6m26s
2026-11-06 16:38:37 +05:30
dhanabalan
af7b60da26 Added courier outward importer and exporter page
Some checks failed
Scan for leaked secrets using Kingfisher / kingfisher-secrets-scan (push) Has been cancelled
Gemini PR Review / Gemini PR Review (pull_request) Failing after 1m19s
Scan for leaked secrets using Kingfisher / kingfisher-secrets-scan (pull_request) Successful in 19s
Laravel Pint / pint (pull_request) Successful in 2m31s
Laravel Larastan / larastan (pull_request) Failing after 6m8s
2026-11-06 16:33:48 +05:30
dhanabalan
be198c8b44 Added view import and export permission for courier outward in seeder
Some checks failed
Scan for leaked secrets using Kingfisher / kingfisher-secrets-scan (push) Has been cancelled
Gemini PR Review / Gemini PR Review (pull_request) Failing after 22s
Scan for leaked secrets using Kingfisher / kingfisher-secrets-scan (pull_request) Successful in 17s
Laravel Pint / pint (pull_request) Successful in 4m28s
Laravel Larastan / larastan (pull_request) Failing after 6m5s
2026-11-06 16:32:42 +05:30
dhanabalan
194c96d362 Added import and export in courier outward page
Some checks failed
Scan for leaked secrets using Kingfisher / kingfisher-secrets-scan (push) Has been cancelled
Gemini PR Review / Gemini PR Review (pull_request) Failing after 32s
Scan for leaked secrets using Kingfisher / kingfisher-secrets-scan (pull_request) Successful in 30s
Laravel Pint / pint (pull_request) Successful in 4m11s
Laravel Larastan / larastan (pull_request) Failing after 5m17s
2026-11-06 16:31:29 +05:30
dhanabalan
89d64afcfd Added options in courier outward page
Some checks failed
Scan for leaked secrets using Kingfisher / kingfisher-secrets-scan (push) Has been cancelled
Gemini PR Review / Gemini PR Review (pull_request) Failing after 21s
Scan for leaked secrets using Kingfisher / kingfisher-secrets-scan (pull_request) Successful in 17s
Laravel Pint / pint (pull_request) Successful in 5m33s
Laravel Larastan / larastan (pull_request) Failing after 7m39s
2026-11-06 16:25:13 +05:30
dhanabalan
999b8756da Added two more options in courier inward resource page
Some checks failed
Scan for leaked secrets using Kingfisher / kingfisher-secrets-scan (push) Has been cancelled
Gemini PR Review / Gemini PR Review (pull_request) Failing after 28s
Scan for leaked secrets using Kingfisher / kingfisher-secrets-scan (pull_request) Successful in 19s
Laravel Larastan / larastan (pull_request) Failing after 4m27s
Laravel Pint / pint (pull_request) Successful in 4m22s
2026-11-06 16:23:02 +05:30
dhanabalan
329e1cbb0c corrected the relation in plant model
Some checks failed
Scan for leaked secrets using Kingfisher / kingfisher-secrets-scan (push) Successful in 30s
Gemini PR Review / Gemini PR Review (pull_request) Failing after 37s
Scan for leaked secrets using Kingfisher / kingfisher-secrets-scan (pull_request) Successful in 19s
Laravel Pint / pint (pull_request) Successful in 4m18s
Laravel Larastan / larastan (pull_request) Failing after 5m17s
2026-11-06 16:19:25 +05:30
dhanabalan
d0ca92421f Added plant model
Some checks failed
Scan for leaked secrets using Kingfisher / kingfisher-secrets-scan (push) Successful in 25s
Gemini PR Review / Gemini PR Review (pull_request) Failing after 48s
Scan for leaked secrets using Kingfisher / kingfisher-secrets-scan (pull_request) Successful in 30s
Laravel Pint / pint (pull_request) Successful in 4m50s
Laravel Larastan / larastan (pull_request) Failing after 6m37s
2026-11-06 16:12:49 +05:30
dhanabalan
ab144f3f7c Added filter in courier inward page and added validation to show current date records
Some checks failed
Scan for leaked secrets using Kingfisher / kingfisher-secrets-scan (push) Successful in 17s
Gemini PR Review / Gemini PR Review (pull_request) Failing after 19s
Scan for leaked secrets using Kingfisher / kingfisher-secrets-scan (pull_request) Successful in 16s
Laravel Pint / pint (pull_request) Successful in 2m42s
Laravel Larastan / larastan (pull_request) Failing after 4m59s
2026-11-06 16:11:53 +05:30
dhanabalan
dc289d96ec Added validation gainst production order checking logic in panel box validation
Some checks failed
Scan for leaked secrets using Kingfisher / kingfisher-secrets-scan (push) Successful in 16s
Scan for leaked secrets using Kingfisher / kingfisher-secrets-scan (pull_request) Successful in 19s
Gemini PR Review / Gemini PR Review (pull_request) Failing after 21s
Laravel Pint / pint (pull_request) Successful in 4m57s
Laravel Larastan / larastan (pull_request) Failing after 5m13s
2026-11-06 15:43:17 +05:30
dhanabalan
fddb12267b Added logic checking document number in production order table
Some checks failed
Scan for leaked secrets using Kingfisher / kingfisher-secrets-scan (push) Successful in 17s
Gemini PR Review / Gemini PR Review (pull_request) Failing after 19s
Scan for leaked secrets using Kingfisher / kingfisher-secrets-scan (pull_request) Successful in 16s
Laravel Pint / pint (pull_request) Successful in 5m12s
Laravel Larastan / larastan (pull_request) Failing after 5m35s
2026-11-06 15:15:34 +05:30
dhanabalan
b4fede901b Restrict null and empty value in sale_order and job_order column
Some checks failed
Gemini PR Review / Gemini PR Review (pull_request) Failing after 20s
Scan for leaked secrets using Kingfisher / kingfisher-secrets-scan (pull_request) Successful in 19s
Scan for leaked secrets using Kingfisher / kingfisher-secrets-scan (push) Successful in 1m27s
Laravel Pint / pint (pull_request) Successful in 4m39s
Laravel Larastan / larastan (pull_request) Failing after 6m31s
2026-11-06 14:42:53 +05:30
dhanabalan
4c284291f6 Added migration (sale_order and job_order), and Updated model, policy, resource, importer, exporter, controller (Get API) with functionality for Testing Line Visualization
Some checks failed
Scan for leaked secrets using Kingfisher / kingfisher-secrets-scan (push) Successful in 17s
Scan for leaked secrets using Kingfisher / kingfisher-secrets-scan (pull_request) Successful in 20s
Gemini PR Review / Gemini PR Review (pull_request) Failing after 23s
Laravel Pint / pint (pull_request) Successful in 2m57s
Laravel Larastan / larastan (pull_request) Failing after 5m24s
2026-11-05 19:17:08 +05:30
dhanabalan
ea48d410bd Updated LeakTestValidation livewire with validations
Some checks failed
Scan for leaked secrets using Kingfisher / kingfisher-secrets-scan (push) Successful in 16s
Gemini PR Review / Gemini PR Review (pull_request) Failing after 18s
Scan for leaked secrets using Kingfisher / kingfisher-secrets-scan (pull_request) Successful in 18s
Laravel Pint / pint (pull_request) Successful in 6m27s
Laravel Larastan / larastan (pull_request) Failing after 7m22s
2026-11-03 17:09:56 +05:30
dhanabalan
67efeb1a89 Added day_1 to day_31 tables in production plan
Some checks failed
Scan for leaked secrets using Kingfisher / kingfisher-secrets-scan (push) Successful in 16s
Gemini PR Review / Gemini PR Review (pull_request) Failing after 10s
Scan for leaked secrets using Kingfisher / kingfisher-secrets-scan (pull_request) Successful in 17s
Laravel Larastan / larastan (pull_request) Failing after 48s
Laravel Pint / pint (pull_request) Successful in 4m49s
2026-11-03 17:02:19 +05:30
dhanabalan
af869e7059 Updated label for leak_test_qr in LeakTestValidation page
Some checks failed
Scan for leaked secrets using Kingfisher / kingfisher-secrets-scan (push) Successful in 15s
Gemini PR Review / Gemini PR Review (pull_request) Failing after 18s
Scan for leaked secrets using Kingfisher / kingfisher-secrets-scan (pull_request) Successful in 18s
Laravel Pint / pint (pull_request) Successful in 3m59s
Laravel Larastan / larastan (pull_request) Failing after 6m36s
2026-11-03 16:13:31 +05:30
dhanabalan
1685c4476d Added LeakTestValidation livewire page with validations
All checks were successful
Scan for leaked secrets using Kingfisher / kingfisher-secrets-scan (push) Successful in 16s
2026-11-03 16:10:45 +05:30
dhanabalan
8dd0fd597b Updated item code validation logic
All checks were successful
Scan for leaked secrets using Kingfisher / kingfisher-secrets-scan (push) Successful in 16s
2026-11-03 15:30:18 +05:30
dhanabalan
f3d1aab505 Added courier inward and outward in page
Some checks failed
Scan for leaked secrets using Kingfisher / kingfisher-secrets-scan (push) Successful in 15s
Gemini PR Review / Gemini PR Review (pull_request) Failing after 17s
Scan for leaked secrets using Kingfisher / kingfisher-secrets-scan (pull_request) Successful in 15s
Laravel Larastan / larastan (pull_request) Failing after 6m8s
Laravel Pint / pint (pull_request) Successful in 4m13s
2026-11-03 12:54:07 +05:30
dhanabalan
607e252aac Added courier inward importer and exporter
Some checks failed
Scan for leaked secrets using Kingfisher / kingfisher-secrets-scan (push) Has been cancelled
2026-11-03 12:53:11 +05:30
dhanabalan
93f88e840d Added permissions in seeder
Some checks failed
Scan for leaked secrets using Kingfisher / kingfisher-secrets-scan (push) Successful in 16s
Gemini PR Review / Gemini PR Review (pull_request) Failing after 8s
Scan for leaked secrets using Kingfisher / kingfisher-secrets-scan (pull_request) Successful in 16s
Laravel Pint / pint (pull_request) Successful in 2m43s
Laravel Larastan / larastan (pull_request) Failing after 6m41s
2026-11-03 12:51:47 +05:30
dhanabalan
38984c88d1 Added testing line visualizer api
Some checks failed
Scan for leaked secrets using Kingfisher / kingfisher-secrets-scan (push) Successful in 16s
Gemini PR Review / Gemini PR Review (pull_request) Failing after 18s
Scan for leaked secrets using Kingfisher / kingfisher-secrets-scan (pull_request) Successful in 15s
Laravel Larastan / larastan (pull_request) Failing after 4m5s
Laravel Pint / pint (pull_request) Successful in 3m1s
2026-11-03 11:52:44 +05:30
dhanabalan
30e7fe9a3f Added day plan target import page
Some checks failed
Scan for leaked secrets using Kingfisher / kingfisher-secrets-scan (push) Has been cancelled
Gemini PR Review / Gemini PR Review (pull_request) Failing after 15s
Scan for leaked secrets using Kingfisher / kingfisher-secrets-scan (pull_request) Successful in 15s
Laravel Larastan / larastan (pull_request) Failing after 4m13s
Laravel Pint / pint (pull_request) Successful in 4m17s
2026-11-03 11:50:29 +05:30
dhanabalan
00852010e3 Added day plan sample export page
Some checks failed
Scan for leaked secrets using Kingfisher / kingfisher-secrets-scan (push) Has been cancelled
Gemini PR Review / Gemini PR Review (pull_request) Failing after 16s
Scan for leaked secrets using Kingfisher / kingfisher-secrets-scan (pull_request) Successful in 24s
Laravel Pint / pint (pull_request) Successful in 2m48s
Laravel Larastan / larastan (pull_request) Failing after 7m14s
2026-11-03 11:49:20 +05:30
dhanabalan
254c1ea9d4 Added production plan target livewire pages
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 19s
Gemini PR Review / Gemini PR Review (pull_request) Failing after 21s
Laravel Pint / pint (pull_request) Successful in 3m51s
Laravel Larastan / larastan (pull_request) Failing after 6m5s
2026-11-03 11:45:30 +05:30
dhanabalan
f5c23e007c Added production plan target page
Some checks failed
Scan for leaked secrets using Kingfisher / kingfisher-secrets-scan (push) Has been cancelled
2026-11-03 11:44:41 +05:30
dhanabalan
944e62ff9e changed logic in production calendar
Some checks failed
Scan for leaked secrets using Kingfisher / kingfisher-secrets-scan (push) Has been cancelled
Gemini PR Review / Gemini PR Review (pull_request) Failing after 15s
Scan for leaked secrets using Kingfisher / kingfisher-secrets-scan (pull_request) Successful in 16s
Laravel Larastan / larastan (pull_request) Failing after 6m27s
Laravel Pint / pint (pull_request) Successful in 3m38s
2026-11-03 11:43:12 +05:30
dhanabalan
ece5b846bb Changed whole logic gainst based on week upload production plan import
Some checks failed
Scan for leaked secrets using Kingfisher / kingfisher-secrets-scan (push) Has been cancelled
Gemini PR Review / Gemini PR Review (pull_request) Failing after 20s
Scan for leaked secrets using Kingfisher / kingfisher-secrets-scan (pull_request) Successful in 18s
Laravel Larastan / larastan (pull_request) Failing after 40s
Laravel Pint / pint (pull_request) Successful in 3m56s
2026-11-03 11:41:26 +05:30
dhanabalan
ea1a30cc07 Added production calendar policy file
Some checks failed
Scan for leaked secrets using Kingfisher / kingfisher-secrets-scan (push) Successful in 17s
Gemini PR Review / Gemini PR Review (pull_request) Failing after 19s
Scan for leaked secrets using Kingfisher / kingfisher-secrets-scan (pull_request) Successful in 15s
Laravel Pint / pint (pull_request) Successful in 4m50s
Laravel Larastan / larastan (pull_request) Failing after 5m44s
2026-11-03 11:35:28 +05:30
dhanabalan
277a6b3758 Added production calendar resource page
Some checks failed
Scan for leaked secrets using Kingfisher / kingfisher-secrets-scan (push) Has been cancelled
2026-11-03 11:34:46 +05:30
dhanabalan
8d7067fe67 Added production calendar model file
Some checks failed
Scan for leaked secrets using Kingfisher / kingfisher-secrets-scan (push) Has been cancelled
2026-11-03 11:32:39 +05:30
dhanabalan
cc6ab2b331 Added production calendar migration file
Some checks failed
Scan for leaked secrets using Kingfisher / kingfisher-secrets-scan (push) Has been cancelled
2026-11-03 11:32:04 +05:30
dhanabalan
ce81bcbe1f Added day_1 to day_31 columns in production plan model file
Some checks failed
Scan for leaked secrets using Kingfisher / kingfisher-secrets-scan (push) Has been cancelled
Gemini PR Review / Gemini PR Review (pull_request) Failing after 16s
Scan for leaked secrets using Kingfisher / kingfisher-secrets-scan (pull_request) Successful in 15s
Laravel Larastan / larastan (pull_request) Failing after 6m58s
Laravel Pint / pint (pull_request) Successful in 5m1s
2026-11-03 11:30:44 +05:30
dhanabalan
07f6a6d1f0 Added day_1 to day_31 columns in production plan
Some checks failed
Scan for leaked secrets using Kingfisher / kingfisher-secrets-scan (push) Successful in 25s
Gemini PR Review / Gemini PR Review (pull_request) Failing after 18s
Scan for leaked secrets using Kingfisher / kingfisher-secrets-scan (pull_request) Successful in 16s
Laravel Pint / pint (pull_request) Successful in 2m44s
Laravel Larastan / larastan (pull_request) Failing after 6m55s
2026-11-03 11:28:57 +05:30
dhanabalan
a826dc4785 Updated get api validation and model for relations
Some checks failed
Scan for leaked secrets using Kingfisher / kingfisher-secrets-scan (push) Successful in 15s
Gemini PR Review / Gemini PR Review (pull_request) Failing after 19s
Scan for leaked secrets using Kingfisher / kingfisher-secrets-scan (pull_request) Successful in 18s
Laravel Pint / pint (pull_request) Successful in 2m46s
Laravel Larastan / larastan (pull_request) Failing after 6m45s
2026-11-03 11:22:36 +05:30
dhanabalan
5c0ed45f74 Added migration, model, policy, resource, importer, exporter, controller (Get API) with validation and functionality for Testing Line Visualization
All checks were successful
Scan for leaked secrets using Kingfisher / kingfisher-secrets-scan (push) Successful in 16s
2026-11-03 11:19:07 +05:30
dhanabalan
20e64ba356 Added validation in gr master importer
Some checks failed
Scan for leaked secrets using Kingfisher / kingfisher-secrets-scan (push) Successful in 17s
Gemini PR Review / Gemini PR Review (pull_request) Failing after 19s
Scan for leaked secrets using Kingfisher / kingfisher-secrets-scan (pull_request) Successful in 15s
Laravel Larastan / larastan (pull_request) Failing after 7m6s
Laravel Pint / pint (pull_request) Successful in 7m5s
2026-11-03 11:10:07 +05:30
dhanabalan
d4186d11c9 Added leak test line validation in plant controller
Some checks failed
Scan for leaked secrets using Kingfisher / kingfisher-secrets-scan (push) Successful in 16s
Gemini PR Review / Gemini PR Review (pull_request) Failing after 27s
Scan for leaked secrets using Kingfisher / kingfisher-secrets-scan (pull_request) Successful in 27s
Laravel Pint / pint (pull_request) Successful in 4m37s
Laravel Larastan / larastan (pull_request) Failing after 6m4s
2026-11-03 10:50:05 +05:30
dhanabalan
1db3adb305 Added leak test item line validation in api
Some checks failed
Scan for leaked secrets using Kingfisher / kingfisher-secrets-scan (push) Successful in 25s
Gemini PR Review / Gemini PR Review (pull_request) Failing after 29s
Scan for leaked secrets using Kingfisher / kingfisher-secrets-scan (pull_request) Successful in 25s
Laravel Pint / pint (pull_request) Successful in 2m37s
Laravel Larastan / larastan (pull_request) Failing after 5m32s
2026-11-03 10:46:51 +05:30
dhanabalan
b089647122 Added duplicate validation in gr master
Some checks failed
Scan for leaked secrets using Kingfisher / kingfisher-secrets-scan (push) Successful in 16s
Gemini PR Review / Gemini PR Review (pull_request) Failing after 19s
Scan for leaked secrets using Kingfisher / kingfisher-secrets-scan (pull_request) Successful in 17s
Laravel Pint / pint (pull_request) Successful in 4m31s
Laravel Larastan / larastan (pull_request) Failing after 6m38s
2026-11-03 10:43:27 +05:30
dhanabalan
9cb7eb5512 Added unique against plant an dgr number in migration file
Some checks failed
Scan for leaked secrets using Kingfisher / kingfisher-secrets-scan (push) Successful in 18s
Gemini PR Review / Gemini PR Review (pull_request) Failing after 22s
Scan for leaked secrets using Kingfisher / kingfisher-secrets-scan (pull_request) Successful in 16s
Laravel Pint / pint (pull_request) Successful in 3m12s
Laravel Larastan / larastan (pull_request) Failing after 4m48s
2026-11-03 10:37:46 +05:30
dhanabalan
b2a9649c2e Added winded_serial_number search funtionality in report filter list
Some checks failed
Scan for leaked secrets using Kingfisher / kingfisher-secrets-scan (push) Successful in 17s
Gemini PR Review / Gemini PR Review (pull_request) Failing after 20s
Scan for leaked secrets using Kingfisher / kingfisher-secrets-scan (pull_request) Successful in 19s
Laravel Pint / pint (pull_request) Successful in 4m23s
Laravel Larastan / larastan (pull_request) Failing after 5m49s
2026-11-02 19:11:53 +05:30
dhanabalan
90ff4a1620 Added created by column in courier inward resource page
Some checks failed
Scan for leaked secrets using Kingfisher / kingfisher-secrets-scan (push) Successful in 16s
Gemini PR Review / Gemini PR Review (pull_request) Failing after 18s
Scan for leaked secrets using Kingfisher / kingfisher-secrets-scan (pull_request) Successful in 15s
Laravel Pint / pint (pull_request) Successful in 3m47s
Laravel Larastan / larastan (pull_request) Failing after 3m59s
2026-11-02 14:55:16 +05:30
dhanabalan
81cc92eae3 Changed logic in courier outward resource page
Some checks failed
Scan for leaked secrets using Kingfisher / kingfisher-secrets-scan (push) Successful in 25s
Gemini PR Review / Gemini PR Review (pull_request) Failing after 27s
Scan for leaked secrets using Kingfisher / kingfisher-secrets-scan (pull_request) Successful in 24s
Laravel Larastan / larastan (pull_request) Failing after 11m1s
Laravel Pint / pint (pull_request) Successful in 16m17s
2026-11-02 12:07:21 +05:30
dhanabalan
951c6ee085 Changed logic in courier inward resource page
Some checks failed
Scan for leaked secrets using Kingfisher / kingfisher-secrets-scan (push) Successful in 16s
Gemini PR Review / Gemini PR Review (pull_request) Failing after 19s
Scan for leaked secrets using Kingfisher / kingfisher-secrets-scan (pull_request) Successful in 17s
Laravel Pint / pint (pull_request) Successful in 3m49s
Laravel Larastan / larastan (pull_request) Failing after 5m59s
2026-11-02 12:03:07 +05:30
dhanabalan
fd0f880473 Added courier outward policy file
Some checks failed
Gemini PR Review / Gemini PR Review (pull_request) Failing after 20s
Scan for leaked secrets using Kingfisher / kingfisher-secrets-scan (pull_request) Successful in 15s
Scan for leaked secrets using Kingfisher / kingfisher-secrets-scan (push) Failing after 3m10s
Laravel Larastan / larastan (pull_request) Failing after 5m18s
Laravel Pint / pint (pull_request) Successful in 3m4s
2026-11-02 11:21:27 +05:30
dhanabalan
c721f45720 Added courier outward resource page
All checks were successful
Scan for leaked secrets using Kingfisher / kingfisher-secrets-scan (push) Successful in 15s
2026-11-02 11:20:41 +05:30
dhanabalan
d371195023 Added courier outward model file
All checks were successful
Scan for leaked secrets using Kingfisher / kingfisher-secrets-scan (push) Successful in 15s
2026-11-02 11:19:24 +05:30
dhanabalan
d62bf6cd47 Added courier outward migration file
All checks were successful
Scan for leaked secrets using Kingfisher / kingfisher-secrets-scan (push) Successful in 15s
2026-11-02 11:18:44 +05:30
dhanabalan
8020c4bead Added courier inward policy file
Some checks failed
Scan for leaked secrets using Kingfisher / kingfisher-secrets-scan (push) Successful in 27s
Gemini PR Review / Gemini PR Review (pull_request) Failing after 34s
Scan for leaked secrets using Kingfisher / kingfisher-secrets-scan (pull_request) Successful in 18s
Laravel Pint / pint (pull_request) Successful in 4m17s
Laravel Larastan / larastan (pull_request) Failing after 4m57s
2026-11-02 10:48:23 +05:30
dhanabalan
6304acf578 Added courier inward resource pages
Some checks failed
Scan for leaked secrets using Kingfisher / kingfisher-secrets-scan (push) Has been cancelled
2026-11-02 10:47:18 +05:30
dhanabalan
4fd91ec11d Added courier inward model file
Some checks failed
Scan for leaked secrets using Kingfisher / kingfisher-secrets-scan (push) Has been cancelled
2026-11-02 10:44:59 +05:30
dhanabalan
67c4d5baeb Added courier inward migration file
Some checks failed
Scan for leaked secrets using Kingfisher / kingfisher-secrets-scan (push) Has been cancelled
2026-11-02 10:44:32 +05:30
dhanabalan
41b0b54428 Changed plant code to plant name in alert mail exporter
Some checks failed
Scan for leaked secrets using Kingfisher / kingfisher-secrets-scan (push) Successful in 18s
Gemini PR Review / Gemini PR Review (pull_request) Failing after 20s
Scan for leaked secrets using Kingfisher / kingfisher-secrets-scan (pull_request) Successful in 17s
Laravel Pint / pint (pull_request) Successful in 5m23s
Laravel Larastan / larastan (pull_request) Failing after 6m45s
2026-11-02 10:42:51 +05:30
dhanabalan
20cc46388b Changed date format in production target livewire page
Some checks failed
Scan for leaked secrets using Kingfisher / kingfisher-secrets-scan (push) Successful in 18s
Scan for leaked secrets using Kingfisher / kingfisher-secrets-scan (pull_request) Successful in 55s
Gemini PR Review / Gemini PR Review (pull_request) Failing after 1m9s
Laravel Pint / pint (pull_request) Successful in 7m41s
Laravel Larastan / larastan (pull_request) Failing after 9m18s
2026-11-02 09:47:15 +05:30
dhanabalan
abe07dbd7b Updated log message on get request characteristics api
All checks were successful
Scan for leaked secrets using Kingfisher / kingfisher-secrets-scan (push) Successful in 1m20s
2026-11-01 15:25:25 +05:30
dhanabalan
3cea3e8ed9 added validation in panel box validation
Some checks failed
Scan for leaked secrets using Kingfisher / kingfisher-secrets-scan (push) Successful in 23s
Gemini PR Review / Gemini PR Review (pull_request) Failing after 23s
Scan for leaked secrets using Kingfisher / kingfisher-secrets-scan (pull_request) Successful in 17s
Laravel Pint / pint (pull_request) Successful in 4m14s
Laravel Larastan / larastan (pull_request) Failing after 7m1s
2026-10-31 14:53:26 +05:30
dhanabalan
9b359527b9 Changed logic in production mail report for efficiency colour
Some checks failed
Scan for leaked secrets using Kingfisher / kingfisher-secrets-scan (push) Successful in 24s
Scan for leaked secrets using Kingfisher / kingfisher-secrets-scan (pull_request) Successful in 18s
Gemini PR Review / Gemini PR Review (pull_request) Failing after 53s
Laravel Pint / pint (pull_request) Successful in 25m21s
Laravel Larastan / larastan (pull_request) Failing after 27m14s
2026-10-29 17:34:20 +05:30
dhanabalan
74ae73918f changed logic in item overview final updation
Some checks failed
Scan for leaked secrets using Kingfisher / kingfisher-secrets-scan (push) Successful in 13s
Gemini PR Review / Gemini PR Review (pull_request) Failing after 9s
Scan for leaked secrets using Kingfisher / kingfisher-secrets-scan (pull_request) Successful in 13s
Laravel Pint / pint (pull_request) Successful in 3m14s
Laravel Larastan / larastan (pull_request) Failing after 5m29s
2026-10-29 12:48:24 +05:30
dhanabalan
4da6375db0 Changed logic in invoice data table
Some checks failed
Scan for leaked secrets using Kingfisher / kingfisher-secrets-scan (push) Successful in 13s
Gemini PR Review / Gemini PR Review (pull_request) Failing after 15s
Scan for leaked secrets using Kingfisher / kingfisher-secrets-scan (pull_request) Successful in 13s
Laravel Pint / pint (pull_request) Successful in 4m10s
Laravel Larastan / larastan (pull_request) Failing after 4m50s
2026-10-29 12:20:07 +05:30
dhanabalan
4a87dea26f Added logic in item overview for today filter seperated
Some checks failed
Scan for leaked secrets using Kingfisher / kingfisher-secrets-scan (push) Successful in 21s
Gemini PR Review / Gemini PR Review (pull_request) Failing after 23s
Scan for leaked secrets using Kingfisher / kingfisher-secrets-scan (pull_request) Successful in 20s
Laravel Pint / pint (pull_request) Successful in 3m50s
Laravel Larastan / larastan (pull_request) Failing after 6m42s
2026-10-29 11:59:37 +05:30
dhanabalan
294a96fa74 changed logic in item overview for verification
Some checks failed
Scan for leaked secrets using Kingfisher / kingfisher-secrets-scan (push) Has been cancelled
Gemini PR Review / Gemini PR Review (pull_request) Failing after 16s
Scan for leaked secrets using Kingfisher / kingfisher-secrets-scan (pull_request) Successful in 15s
Laravel Pint / pint (pull_request) Successful in 2m49s
Laravel Larastan / larastan (pull_request) Failing after 5m52s
2026-10-29 11:49:04 +05:30
dhanabalan
1799cd8d9d changed logic in item overview
Some checks failed
Scan for leaked secrets using Kingfisher / kingfisher-secrets-scan (push) Has been cancelled
Gemini PR Review / Gemini PR Review (pull_request) Failing after 17s
Scan for leaked secrets using Kingfisher / kingfisher-secrets-scan (pull_request) Successful in 13s
Laravel Larastan / larastan (pull_request) Failing after 6m39s
Laravel Pint / pint (pull_request) Successful in 4m26s
2026-10-29 11:44:35 +05:30
dhanabalan
1b576da90c changed logic in today and yesterday filter in hourly production
Some checks failed
Scan for leaked secrets using Kingfisher / kingfisher-secrets-scan (push) Has been cancelled
Gemini PR Review / Gemini PR Review (pull_request) Failing after 17s
Scan for leaked secrets using Kingfisher / kingfisher-secrets-scan (pull_request) Successful in 13s
Laravel Pint / pint (pull_request) Successful in 2m50s
Laravel Larastan / larastan (pull_request) Failing after 7m47s
2026-10-29 11:37:46 +05:30
dhanabalan
f95e73f665 changed logic in item overview for today filter
Some checks failed
Scan for leaked secrets using Kingfisher / kingfisher-secrets-scan (push) Has been cancelled
Gemini PR Review / Gemini PR Review (pull_request) Failing after 17s
Scan for leaked secrets using Kingfisher / kingfisher-secrets-scan (pull_request) Successful in 13s
Laravel Larastan / larastan (pull_request) Failing after 6m39s
Laravel Pint / pint (pull_request) Successful in 4m21s
2026-10-29 11:33:15 +05:30
dhanabalan
3677693121 changed logic in item overview bug solved
Some checks failed
Scan for leaked secrets using Kingfisher / kingfisher-secrets-scan (push) Has been cancelled
Gemini PR Review / Gemini PR Review (pull_request) Failing after 29s
Scan for leaked secrets using Kingfisher / kingfisher-secrets-scan (pull_request) Successful in 18s
Laravel Pint / pint (pull_request) Successful in 3m27s
Laravel Larastan / larastan (pull_request) Failing after 6m48s
2026-10-29 11:29:56 +05:30
dhanabalan
db901af048 changed logic in item overview for todaya nd yesterday filter
Some checks failed
Scan for leaked secrets using Kingfisher / kingfisher-secrets-scan (push) Has been cancelled
Gemini PR Review / Gemini PR Review (pull_request) Failing after 18s
Scan for leaked secrets using Kingfisher / kingfisher-secrets-scan (pull_request) Successful in 13s
Laravel Pint / pint (pull_request) Failing after 3m3s
Laravel Larastan / larastan (pull_request) Failing after 7m21s
2026-10-29 11:26:06 +05:30
dhanabalan
564c4646ca bug solved in item overview
Some checks failed
Scan for leaked secrets using Kingfisher / kingfisher-secrets-scan (push) Has been cancelled
Gemini PR Review / Gemini PR Review (pull_request) Failing after 30s
Scan for leaked secrets using Kingfisher / kingfisher-secrets-scan (pull_request) Successful in 13s
Laravel Pint / pint (pull_request) Successful in 3m28s
Laravel Larastan / larastan (pull_request) Failing after 7m16s
2026-10-29 11:22:36 +05:30
dhanabalan
120982dd0b changed logic in item overview
Some checks failed
Scan for leaked secrets using Kingfisher / kingfisher-secrets-scan (push) Has been cancelled
Gemini PR Review / Gemini PR Review (pull_request) Failing after 20s
Scan for leaked secrets using Kingfisher / kingfisher-secrets-scan (pull_request) Successful in 14s
Laravel Pint / pint (pull_request) Successful in 6m55s
Laravel Larastan / larastan (pull_request) Failing after 7m55s
2026-10-29 11:19:49 +05:30
dhanabalan
9f0ee1c29b changed logic for today and yesterday in item overview
Some checks failed
Scan for leaked secrets using Kingfisher / kingfisher-secrets-scan (push) Successful in 14s
Gemini PR Review / Gemini PR Review (pull_request) Failing after 19s
Scan for leaked secrets using Kingfisher / kingfisher-secrets-scan (pull_request) Successful in 19s
Laravel Larastan / larastan (pull_request) Failing after 5m27s
Laravel Pint / pint (pull_request) Successful in 3m58s
2026-10-29 11:18:34 +05:30
dhanabalan
fa657ffa35 solve dbug in query this week in item overview
Some checks failed
Scan for leaked secrets using Kingfisher / kingfisher-secrets-scan (push) Successful in 14s
Gemini PR Review / Gemini PR Review (pull_request) Failing after 18s
Scan for leaked secrets using Kingfisher / kingfisher-secrets-scan (pull_request) Successful in 13s
Laravel Pint / pint (pull_request) Successful in 3m49s
Laravel Larastan / larastan (pull_request) Failing after 6m43s
2026-10-29 11:08:01 +05:30
dhanabalan
17c0426dc4 changed logic in item overview
Some checks failed
Scan for leaked secrets using Kingfisher / kingfisher-secrets-scan (push) Has been cancelled
Gemini PR Review / Gemini PR Review (pull_request) Failing after 24s
Scan for leaked secrets using Kingfisher / kingfisher-secrets-scan (pull_request) Successful in 13s
Laravel Larastan / larastan (pull_request) Failing after 4m36s
Laravel Pint / pint (pull_request) Successful in 5m16s
2026-10-29 11:06:36 +05:30
dhanabalan
40a893fbe9 Changed logic in item overview page
Some checks failed
Scan for leaked secrets using Kingfisher / kingfisher-secrets-scan (push) Successful in 13s
Scan for leaked secrets using Kingfisher / kingfisher-secrets-scan (pull_request) Successful in 16s
Gemini PR Review / Gemini PR Review (pull_request) Failing after 19s
Laravel Pint / pint (pull_request) Successful in 5m12s
Laravel Larastan / larastan (pull_request) Failing after 6m11s
2026-10-29 11:03:01 +05:30
dhanabalan
92beb31874 Added this week plan data filter logic in production dashboard
Some checks failed
Scan for leaked secrets using Kingfisher / kingfisher-secrets-scan (push) Successful in 15s
Scan for leaked secrets using Kingfisher / kingfisher-secrets-scan (pull_request) Successful in 17s
Gemini PR Review / Gemini PR Review (pull_request) Failing after 20s
Laravel Pint / pint (pull_request) Successful in 4m33s
Laravel Larastan / larastan (pull_request) Failing after 5m12s
2026-10-29 10:37:57 +05:30
dhanabalan
8cf3516094 Changed logic in invoice data table
Some checks failed
Scan for leaked secrets using Kingfisher / kingfisher-secrets-scan (push) Successful in 14s
Scan for leaked secrets using Kingfisher / kingfisher-secrets-scan (pull_request) Successful in 16s
Gemini PR Review / Gemini PR Review (pull_request) Failing after 19s
Laravel Pint / pint (pull_request) Successful in 4m5s
Laravel Larastan / larastan (pull_request) Failing after 5m15s
2026-10-29 10:25:33 +05:30
dhanabalan
924337fa6c changed logic in production dashboard for hourly
Some checks failed
Scan for leaked secrets using Kingfisher / kingfisher-secrets-scan (push) Successful in 13s
Gemini PR Review / Gemini PR Review (pull_request) Failing after 24s
Scan for leaked secrets using Kingfisher / kingfisher-secrets-scan (pull_request) Successful in 20s
Laravel Larastan / larastan (pull_request) Failing after 5m41s
Laravel Pint / pint (pull_request) Successful in 5m45s
2026-10-29 09:43:44 +05:30
dhanabalan
a1457a1e76 changed logic in production dashboard
Some checks failed
Scan for leaked secrets using Kingfisher / kingfisher-secrets-scan (push) Successful in 14s
Scan for leaked secrets using Kingfisher / kingfisher-secrets-scan (pull_request) Successful in 15s
Gemini PR Review / Gemini PR Review (pull_request) Failing after 19s
Laravel Pint / pint (pull_request) Successful in 3m14s
Laravel Larastan / larastan (pull_request) Failing after 6m0s
2026-10-29 09:39:57 +05:30
dhanabalan
4cea958297 Added this month plan data logic in production dashboard
Some checks failed
Scan for leaked secrets using Kingfisher / kingfisher-secrets-scan (push) Successful in 14s
Scan for leaked secrets using Kingfisher / kingfisher-secrets-scan (pull_request) Successful in 15s
Gemini PR Review / Gemini PR Review (pull_request) Failing after 20s
Laravel Pint / pint (pull_request) Successful in 5m23s
Laravel Larastan / larastan (pull_request) Failing after 5m34s
2026-10-29 09:32:19 +05:30
dhanabalan
db71f869dd changed query logic in item page
Some checks failed
Scan for leaked secrets using Kingfisher / kingfisher-secrets-scan (push) Failing after 32s
Scan for leaked secrets using Kingfisher / kingfisher-secrets-scan (pull_request) Successful in 14s
Gemini PR Review / Gemini PR Review (pull_request) Failing after 22s
Laravel Pint / pint (pull_request) Successful in 4m13s
Laravel Larastan / larastan (pull_request) Failing after 7m1s
2026-10-28 17:22:43 +05:30
dhanabalan
1edf72b8e5 Changed filter logic in item resource page
Some checks failed
Scan for leaked secrets using Kingfisher / kingfisher-secrets-scan (push) Successful in 14s
Scan for leaked secrets using Kingfisher / kingfisher-secrets-scan (pull_request) Successful in 16s
Gemini PR Review / Gemini PR Review (pull_request) Failing after 20s
Laravel Pint / pint (pull_request) Successful in 4m55s
Laravel Larastan / larastan (pull_request) Failing after 5m59s
2026-10-28 17:14:34 +05:30
dhanabalan
f8e06965cf loaded options in tools and gadgets in visitor entry resource page
Some checks failed
Scan for leaked secrets using Kingfisher / kingfisher-secrets-scan (push) Successful in 14s
Scan for leaked secrets using Kingfisher / kingfisher-secrets-scan (pull_request) Successful in 16s
Gemini PR Review / Gemini PR Review (pull_request) Failing after 20s
Laravel Pint / pint (pull_request) Successful in 4m44s
Laravel Larastan / larastan (pull_request) Failing after 4m54s
2026-10-28 16:58:19 +05:30
dhanabalan
765d3e2c5b Added tool gadget in visitor arrival notification
Some checks failed
Scan for leaked secrets using Kingfisher / kingfisher-secrets-scan (push) Successful in 19s
Gemini PR Review / Gemini PR Review (pull_request) Failing after 31s
Scan for leaked secrets using Kingfisher / kingfisher-secrets-scan (pull_request) Successful in 18s
Laravel Pint / pint (pull_request) Successful in 4m31s
Laravel Larastan / larastan (pull_request) Failing after 6m16s
2026-10-28 15:36:14 +05:30
dhanabalan
53b64c11e0 Added tool gadgets and serial number in visitor entry resource page
Some checks failed
Scan for leaked secrets using Kingfisher / kingfisher-secrets-scan (push) Successful in 15s
Gemini PR Review / Gemini PR Review (pull_request) Failing after 20s
Scan for leaked secrets using Kingfisher / kingfisher-secrets-scan (pull_request) Successful in 14s
Laravel Pint / pint (pull_request) Successful in 3m49s
Laravel Larastan / larastan (pull_request) Failing after 5m7s
2026-10-28 15:32:37 +05:30
dhanabalan
7b6245c9fb Added tool gadget and serial number column in visitor entry model file
Some checks failed
Scan for leaked secrets using Kingfisher / kingfisher-secrets-scan (push) Successful in 13s
Scan for leaked secrets using Kingfisher / kingfisher-secrets-scan (pull_request) Successful in 16s
Gemini PR Review / Gemini PR Review (pull_request) Failing after 20s
Laravel Pint / pint (pull_request) Successful in 4m49s
Laravel Larastan / larastan (pull_request) Failing after 5m58s
2026-10-28 15:01:41 +05:30
dhanabalan
e290bd6955 Added tool gadget and serial number column in visitor entries
All checks were successful
Scan for leaked secrets using Kingfisher / kingfisher-secrets-scan (push) Successful in 14s
2026-10-28 15:00:18 +05:30
dhanabalan
00c3fa877f Added coil details in pdf controller
Some checks failed
Scan for leaked secrets using Kingfisher / kingfisher-secrets-scan (push) Successful in 13s
Scan for leaked secrets using Kingfisher / kingfisher-secrets-scan (pull_request) Successful in 15s
Gemini PR Review / Gemini PR Review (pull_request) Failing after 21s
Laravel Pint / pint (pull_request) Successful in 5m10s
Laravel Larastan / larastan (pull_request) Failing after 6m59s
2026-10-28 12:24:48 +05:30
dhanabalan
5fbfcd948d Added coil details api
All checks were successful
Scan for leaked secrets using Kingfisher / kingfisher-secrets-scan (push) Successful in 13s
2026-10-28 12:24:09 +05:30
dhanabalan
5785196043 Added logic in daily task report
Some checks failed
Scan for leaked secrets using Kingfisher / kingfisher-secrets-scan (push) Successful in 18s
Scan for leaked secrets using Kingfisher / kingfisher-secrets-scan (pull_request) Successful in 16s
Gemini PR Review / Gemini PR Review (pull_request) Failing after 21s
Laravel Pint / pint (pull_request) Successful in 9m48s
Laravel Larastan / larastan (pull_request) Failing after 11m15s
2026-10-28 08:44:03 +05:30
dhanabalan
bd3a0903f9 Added logic in random serial list
Some checks failed
Scan for leaked secrets using Kingfisher / kingfisher-secrets-scan (push) Successful in 13s
Gemini PR Review / Gemini PR Review (pull_request) Failing after 17s
Scan for leaked secrets using Kingfisher / kingfisher-secrets-scan (pull_request) Successful in 15s
Laravel Larastan / larastan (pull_request) Failing after 5m9s
Laravel Pint / pint (pull_request) Successful in 5m31s
2026-10-27 15:16:22 +05:30
dhanabalan
91a750acf1 Changed logic in bulk sticker printing page
All checks were successful
Scan for leaked secrets using Kingfisher / kingfisher-secrets-scan (push) Successful in 13s
2026-10-27 15:15:22 +05:30
dhanabalan
1e93321f52 Added duplicate validation in panel box validation
Some checks failed
Scan for leaked secrets using Kingfisher / kingfisher-secrets-scan (push) Successful in 16s
Gemini PR Review / Gemini PR Review (pull_request) Failing after 15s
Scan for leaked secrets using Kingfisher / kingfisher-secrets-scan (pull_request) Successful in 13s
Laravel Pint / pint (pull_request) Successful in 3m17s
Laravel Larastan / larastan (pull_request) Failing after 6m45s
2026-10-27 10:38:48 +05:30
dhanabalan
64d2d749d3 Changed seconds in notification
Some checks failed
Scan for leaked secrets using Kingfisher / kingfisher-secrets-scan (push) Has been cancelled
Gemini PR Review / Gemini PR Review (pull_request) Failing after 19s
Scan for leaked secrets using Kingfisher / kingfisher-secrets-scan (pull_request) Successful in 13s
Laravel Pint / pint (pull_request) Successful in 3m59s
Laravel Larastan / larastan (pull_request) Failing after 4m40s
2026-10-27 10:22:59 +05:30
dhanabalan
e48ab81581 added fill foem in inspection
Some checks failed
Scan for leaked secrets using Kingfisher / kingfisher-secrets-scan (push) Has been cancelled
Gemini PR Review / Gemini PR Review (pull_request) Failing after 20s
Scan for leaked secrets using Kingfisher / kingfisher-secrets-scan (pull_request) Successful in 14s
Laravel Larastan / larastan (pull_request) Failing after 5m22s
Laravel Pint / pint (pull_request) Successful in 5m32s
2026-10-27 10:21:43 +05:30
dhanabalan
2890c45f5d changed notidfication in panel box
Some checks failed
Scan for leaked secrets using Kingfisher / kingfisher-secrets-scan (push) Has been cancelled
Gemini PR Review / Gemini PR Review (pull_request) Failing after 17s
Scan for leaked secrets using Kingfisher / kingfisher-secrets-scan (pull_request) Successful in 13s
Laravel Larastan / larastan (pull_request) Failing after 5m6s
Laravel Pint / pint (pull_request) Successful in 3m51s
2026-10-27 10:19:58 +05:30
dhanabalan
83c270ef09 changed logic in panel box inspection stock
Some checks failed
Scan for leaked secrets using Kingfisher / kingfisher-secrets-scan (push) Has been cancelled
Gemini PR Review / Gemini PR Review (pull_request) Failing after 21s
Scan for leaked secrets using Kingfisher / kingfisher-secrets-scan (pull_request) Successful in 13s
Laravel Pint / pint (pull_request) Successful in 5m6s
Laravel Larastan / larastan (pull_request) Failing after 14m25s
2026-10-27 10:19:01 +05:30
dhanabalan
5b6c182df9 change dlogic in panel box inspection
Some checks failed
Scan for leaked secrets using Kingfisher / kingfisher-secrets-scan (push) Has been cancelled
Gemini PR Review / Gemini PR Review (pull_request) Failing after 16s
Scan for leaked secrets using Kingfisher / kingfisher-secrets-scan (pull_request) Successful in 13s
Laravel Pint / pint (pull_request) Successful in 5m21s
Laravel Larastan / larastan (pull_request) Failing after 6m1s
2026-10-27 10:13:28 +05:30
dhanabalan
c8a1f6d8f0 Changed notification in invoice validation
Some checks failed
Scan for leaked secrets using Kingfisher / kingfisher-secrets-scan (push) Successful in 14s
Gemini PR Review / Gemini PR Review (pull_request) Failing after 18s
Scan for leaked secrets using Kingfisher / kingfisher-secrets-scan (pull_request) Successful in 13s
Laravel Larastan / larastan (pull_request) Failing after 4m15s
Laravel Pint / pint (pull_request) Successful in 5m8s
2026-10-27 10:05:29 +05:30
dhanabalan
113cc8997f Changed notification messga ein pa nel box inspection message
Some checks failed
Scan for leaked secrets using Kingfisher / kingfisher-secrets-scan (push) Successful in 14s
Gemini PR Review / Gemini PR Review (pull_request) Failing after 19s
Scan for leaked secrets using Kingfisher / kingfisher-secrets-scan (pull_request) Successful in 13s
Laravel Larastan / larastan (pull_request) Failing after 4m38s
Laravel Pint / pint (pull_request) Successful in 5m22s
2026-10-27 09:59:49 +05:30
dhanabalan
584d54d3e8 Changed notification in panel box inspection stock
Some checks failed
Scan for leaked secrets using Kingfisher / kingfisher-secrets-scan (push) Successful in 15s
Gemini PR Review / Gemini PR Review (pull_request) Failing after 20s
Scan for leaked secrets using Kingfisher / kingfisher-secrets-scan (pull_request) Successful in 13s
Laravel Larastan / larastan (pull_request) Failing after 4m47s
Laravel Pint / pint (pull_request) Successful in 5m59s
2026-10-27 09:56:34 +05:30
dhanabalan
b7d7640cdb Added download button in upload daily report
Some checks failed
Scan for leaked secrets using Kingfisher / kingfisher-secrets-scan (push) Successful in 14s
Scan for leaked secrets using Kingfisher / kingfisher-secrets-scan (pull_request) Successful in 14s
Gemini PR Review / Gemini PR Review (pull_request) Failing after 20s
Laravel Pint / pint (pull_request) Successful in 3m8s
Laravel Larastan / larastan (pull_request) Failing after 4m27s
2026-10-27 09:06:59 +05:30
dhanabalan
7c123a2d1d Added validation in upload daily task report
Some checks failed
Scan for leaked secrets using Kingfisher / kingfisher-secrets-scan (push) Successful in 16s
Scan for leaked secrets using Kingfisher / kingfisher-secrets-scan (pull_request) Successful in 15s
Gemini PR Review / Gemini PR Review (pull_request) Failing after 21s
Laravel Pint / pint (pull_request) Successful in 3m38s
Laravel Larastan / larastan (pull_request) Failing after 4m57s
2026-10-27 08:57:00 +05:30
dhanabalan
e3c07011ba changed logic in invoice data table
Some checks failed
Scan for leaked secrets using Kingfisher / kingfisher-secrets-scan (push) Successful in 14s
Scan for leaked secrets using Kingfisher / kingfisher-secrets-scan (pull_request) Successful in 15s
Gemini PR Review / Gemini PR Review (pull_request) Failing after 18s
Laravel Pint / pint (pull_request) Successful in 2m38s
Laravel Larastan / larastan (pull_request) Failing after 5m19s
2026-10-26 19:05:58 +05:30
dhanabalan
e292fbbdcd Added danger in invoice notification
Some checks failed
Scan for leaked secrets using Kingfisher / kingfisher-secrets-scan (push) Successful in 14s
Scan for leaked secrets using Kingfisher / kingfisher-secrets-scan (pull_request) Successful in 13s
Gemini PR Review / Gemini PR Review (pull_request) Failing after 19s
Laravel Pint / pint (pull_request) Successful in 2m29s
Laravel Larastan / larastan (pull_request) Failing after 4m2s
2026-10-26 18:49:58 +05:30
dhanabalan
60d8460e5f Changed logic in panel box validation
Some checks failed
Scan for leaked secrets using Kingfisher / kingfisher-secrets-scan (push) Successful in 14s
Scan for leaked secrets using Kingfisher / kingfisher-secrets-scan (pull_request) Successful in 29s
Gemini PR Review / Gemini PR Review (pull_request) Failing after 39s
Laravel Larastan / larastan (pull_request) Failing after 4m58s
Laravel Pint / pint (pull_request) Successful in 5m9s
2026-10-26 18:44:22 +05:30
dhanabalan
58394901ac Added migration and Updated model, resource, importer, exporter to add test_finished_at column and Added test_finished_at column to Testing Panel Post Reading API in TestingPanelController
Some checks failed
Scan for leaked secrets using Kingfisher / kingfisher-secrets-scan (push) Successful in 18s
Scan for leaked secrets using Kingfisher / kingfisher-secrets-scan (pull_request) Successful in 38s
Gemini PR Review / Gemini PR Review (pull_request) Failing after 1m18s
Laravel Pint / pint (pull_request) Successful in 4m12s
Laravel Larastan / larastan (pull_request) Failing after 8m23s
2026-10-26 14:51:52 +05:30
dhanabalan
6233103b8b Changed notification in panel box inspection page
Some checks failed
Scan for leaked secrets using Kingfisher / kingfisher-secrets-scan (push) Successful in 13s
Gemini PR Review / Gemini PR Review (pull_request) Failing after 17s
Scan for leaked secrets using Kingfisher / kingfisher-secrets-scan (pull_request) Successful in 14s
Laravel Pint / pint (pull_request) Successful in 3m32s
Laravel Larastan / larastan (pull_request) Failing after 5m16s
2026-10-26 11:20:48 +05:30
dhanabalan
fcbe328833 Added audio in panel box inspection stock page
Some checks failed
Scan for leaked secrets using Kingfisher / kingfisher-secrets-scan (push) Successful in 13s
Scan for leaked secrets using Kingfisher / kingfisher-secrets-scan (pull_request) Successful in 14s
Gemini PR Review / Gemini PR Review (pull_request) Failing after 17s
Laravel Pint / pint (pull_request) Successful in 2m34s
Laravel Larastan / larastan (pull_request) Failing after 4m36s
2026-10-26 11:06:00 +05:30
dhanabalan
d1ca8b0ea9 Added filter in invoice page
Some checks failed
Scan for leaked secrets using Kingfisher / kingfisher-secrets-scan (push) Successful in 14s
Gemini PR Review / Gemini PR Review (pull_request) Failing after 17s
Scan for leaked secrets using Kingfisher / kingfisher-secrets-scan (pull_request) Successful in 14s
Laravel Pint / pint (pull_request) Successful in 3m57s
Laravel Larastan / larastan (pull_request) Failing after 6m23s
2026-10-26 09:44:10 +05:30
dhanabalan
229e6081eb commented panel box code in invoice validation
Some checks failed
Scan for leaked secrets using Kingfisher / kingfisher-secrets-scan (push) Successful in 14s
Gemini PR Review / Gemini PR Review (pull_request) Failing after 23s
Scan for leaked secrets using Kingfisher / kingfisher-secrets-scan (pull_request) Successful in 20s
Laravel Pint / pint (pull_request) Successful in 4m4s
Laravel Larastan / larastan (pull_request) Failing after 5m45s
2026-10-26 09:05:19 +05:30
dhanabalan
f9e486993c removed panel box duplicate logic in invoice
Some checks failed
Scan for leaked secrets using Kingfisher / kingfisher-secrets-scan (push) Successful in 1m25s
Scan for leaked secrets using Kingfisher / kingfisher-secrets-scan (pull_request) Successful in 50s
Gemini PR Review / Gemini PR Review (pull_request) Failing after 2m10s
Laravel Pint / pint (pull_request) Successful in 3m29s
Laravel Larastan / larastan (pull_request) Failing after 5m27s
2026-10-26 09:00:49 +05:30
dhanabalan
cd17021097 Added trigger create event logic in leak test reading
Some checks failed
Scan for leaked secrets using Kingfisher / kingfisher-secrets-scan (push) Successful in 13s
Scan for leaked secrets using Kingfisher / kingfisher-secrets-scan (pull_request) Successful in 15s
Gemini PR Review / Gemini PR Review (pull_request) Failing after 20s
Laravel Pint / pint (pull_request) Successful in 3m41s
Laravel Larastan / larastan (pull_request) Failing after 5m22s
2026-10-24 12:58:08 +05:30
dhanabalan
cf1d6a1c05 Changed logic in leak test readings scanning qr code
All checks were successful
Scan for leaked secrets using Kingfisher / kingfisher-secrets-scan (push) Successful in 13s
2026-10-24 12:57:34 +05:30
dhanabalan
534b6e9c1a removed uniqueness in plants table
Some checks failed
Scan for leaked secrets using Kingfisher / kingfisher-secrets-scan (push) Successful in 14s
Scan for leaked secrets using Kingfisher / kingfisher-secrets-scan (pull_request) Successful in 16s
Gemini PR Review / Gemini PR Review (pull_request) Failing after 21s
Laravel Pint / pint (pull_request) Successful in 3m38s
Laravel Larastan / larastan (pull_request) Failing after 5m41s
2026-10-24 10:42:54 +05:30
dhanabalan
323c396a40 Changed duplicate logic in invoice validation
Some checks failed
Scan for leaked secrets using Kingfisher / kingfisher-secrets-scan (push) Successful in 14s
Gemini PR Review / Gemini PR Review (pull_request) Failing after 20s
Scan for leaked secrets using Kingfisher / kingfisher-secrets-scan (pull_request) Successful in 13s
Laravel Pint / pint (pull_request) Successful in 2m46s
Laravel Larastan / larastan (pull_request) Failing after 5m16s
2026-10-24 08:29:56 +05:30
dhanabalan
baf41cfea1 changed regex pattern in panel box inspection page
Some checks failed
Scan for leaked secrets using Kingfisher / kingfisher-secrets-scan (push) Successful in 13s
Gemini PR Review / Gemini PR Review (pull_request) Failing after 15s
Scan for leaked secrets using Kingfisher / kingfisher-secrets-scan (pull_request) Successful in 13s
Laravel Pint / pint (pull_request) Successful in 4m23s
Laravel Larastan / larastan (pull_request) Failing after 6m0s
2026-10-23 17:24:16 +05:30
dhanabalan
92324e9f3b removed searchable in invoice validation
All checks were successful
Scan for leaked secrets using Kingfisher / kingfisher-secrets-scan (push) Successful in 12s
2026-10-23 17:23:20 +05:30
dhanabalan
683309c5cf Added logic in panel box validation changed regex pattern
Some checks failed
Scan for leaked secrets using Kingfisher / kingfisher-secrets-scan (push) Successful in 13s
Scan for leaked secrets using Kingfisher / kingfisher-secrets-scan (pull_request) Successful in 13s
Gemini PR Review / Gemini PR Review (pull_request) Failing after 18s
Laravel Pint / pint (pull_request) Successful in 3m37s
Laravel Larastan / larastan (pull_request) Failing after 5m20s
2026-10-23 17:13:49 +05:30
dhanabalan
3716741b3a removed logic in panel box inspection stock
Some checks failed
Scan for leaked secrets using Kingfisher / kingfisher-secrets-scan (push) Successful in 12s
Gemini PR Review / Gemini PR Review (pull_request) Failing after 18s
Scan for leaked secrets using Kingfisher / kingfisher-secrets-scan (pull_request) Successful in 12s
Laravel Larastan / larastan (pull_request) Failing after 4m41s
Laravel Pint / pint (pull_request) Successful in 3m48s
2026-10-23 16:52:17 +05:30
dhanabalan
8d213f563f changed regex logic in panel box valiation resource page
Some checks failed
Scan for leaked secrets using Kingfisher / kingfisher-secrets-scan (push) Successful in 13s
Gemini PR Review / Gemini PR Review (pull_request) Failing after 16s
Scan for leaked secrets using Kingfisher / kingfisher-secrets-scan (pull_request) Successful in 15s
Laravel Larastan / larastan (pull_request) Failing after 4m7s
Laravel Pint / pint (pull_request) Successful in 6m9s
2026-10-23 16:47:46 +05:30
dhanabalan
842eedbca2 Added seperate method for random serial generation
Some checks failed
Scan for leaked secrets using Kingfisher / kingfisher-secrets-scan (push) Successful in 13s
Scan for leaked secrets using Kingfisher / kingfisher-secrets-scan (pull_request) Successful in 15s
Gemini PR Review / Gemini PR Review (pull_request) Failing after 18s
Laravel Pint / pint (pull_request) Successful in 4m49s
Laravel Larastan / larastan (pull_request) Failing after 6m39s
2026-10-23 14:06:13 +05:30
dhanabalan
d7c386d053 Added random seral list in bulk sticker printing page
All checks were successful
Scan for leaked secrets using Kingfisher / kingfisher-secrets-scan (push) Successful in 13s
2026-10-23 14:02:45 +05:30
dhanabalan
4260c7b18a Added random serial number list livewire pages
All checks were successful
Scan for leaked secrets using Kingfisher / kingfisher-secrets-scan (push) Successful in 13s
2026-10-23 14:00:31 +05:30
dhanabalan
77456a5d8a removed required forinspection lot number in panel box validation
Some checks failed
Scan for leaked secrets using Kingfisher / kingfisher-secrets-scan (push) Successful in 13s
Gemini PR Review / Gemini PR Review (pull_request) Failing after 16s
Scan for leaked secrets using Kingfisher / kingfisher-secrets-scan (pull_request) Successful in 14s
Laravel Pint / pint (pull_request) Successful in 2m55s
Laravel Larastan / larastan (pull_request) Failing after 4m8s
2026-10-23 12:03:30 +05:30
dhanabalan
700c01eebc intialize variable in edit panel gr master
Some checks failed
Scan for leaked secrets using Kingfisher / kingfisher-secrets-scan (push) Successful in 14s
Scan for leaked secrets using Kingfisher / kingfisher-secrets-scan (pull_request) Successful in 26s
Gemini PR Review / Gemini PR Review (pull_request) Failing after 36s
Laravel Pint / pint (pull_request) Failing after 3s
Laravel Larastan / larastan (pull_request) Failing after 5m2s
2026-10-23 11:43:41 +05:30
dhanabalan
40222cb59e Added panel box serial number in invoice validation filter
Some checks failed
Scan for leaked secrets using Kingfisher / kingfisher-secrets-scan (push) Successful in 14s
Scan for leaked secrets using Kingfisher / kingfisher-secrets-scan (pull_request) Successful in 16s
Gemini PR Review / Gemini PR Review (pull_request) Failing after 20s
Laravel Pint / pint (pull_request) Successful in 3m44s
Laravel Larastan / larastan (pull_request) Failing after 4m39s
2026-10-23 11:24:56 +05:30
dhanabalan
3f964e7b88 Changed label name for production characteristic exporter
Some checks failed
Scan for leaked secrets using Kingfisher / kingfisher-secrets-scan (push) Successful in 14s
Scan for leaked secrets using Kingfisher / kingfisher-secrets-scan (pull_request) Successful in 14s
Gemini PR Review / Gemini PR Review (pull_request) Failing after 19s
Laravel Larastan / larastan (pull_request) Failing after 47s
Laravel Pint / pint (pull_request) Successful in 3m48s
2026-10-23 10:52:56 +05:30
dhanabalan
9cbb6a7877 Added filter panel box serial number in invoice validations
Some checks failed
Scan for leaked secrets using Kingfisher / kingfisher-secrets-scan (push) Successful in 13s
Scan for leaked secrets using Kingfisher / kingfisher-secrets-scan (pull_request) Successful in 15s
Gemini PR Review / Gemini PR Review (pull_request) Failing after 20s
Laravel Pint / pint (pull_request) Successful in 3m27s
Laravel Larastan / larastan (pull_request) Failing after 6m31s
2026-10-23 10:40:30 +05:30
dhanabalan
6e7da3cd7a Added tollfree and feed rule in sticker pdf service and multiple sticker method
Some checks failed
Scan for leaked secrets using Kingfisher / kingfisher-secrets-scan (push) Successful in 13s
Gemini PR Review / Gemini PR Review (pull_request) Failing after 19s
Scan for leaked secrets using Kingfisher / kingfisher-secrets-scan (pull_request) Successful in 13s
Laravel Larastan / larastan (pull_request) Failing after 7m42s
Laravel Pint / pint (pull_request) Successful in 6m37s
2026-10-22 16:51:06 +05:30
dhanabalan
8eb5a47226 Added tollfree and feedback in sticker detail page
Some checks failed
Scan for leaked secrets using Kingfisher / kingfisher-secrets-scan (push) Successful in 15s
Scan for leaked secrets using Kingfisher / kingfisher-secrets-scan (pull_request) Successful in 16s
Gemini PR Review / Gemini PR Review (pull_request) Failing after 21s
Laravel Pint / pint (pull_request) Successful in 2m32s
Laravel Larastan / larastan (pull_request) Failing after 7m34s
2026-10-22 16:48:40 +05:30
dhanabalan
35ed640660 Added tollfree in plant resource page
Some checks failed
Scan for leaked secrets using Kingfisher / kingfisher-secrets-scan (push) Successful in 13s
Scan for leaked secrets using Kingfisher / kingfisher-secrets-scan (pull_request) Successful in 17s
Gemini PR Review / Gemini PR Review (pull_request) Failing after 22s
Laravel Pint / pint (pull_request) Successful in 4m51s
Laravel Larastan / larastan (pull_request) Failing after 5m0s
2026-10-21 11:11:47 +05:30
dhanabalan
342e71bb87 Added tollfree in plants model file
All checks were successful
Scan for leaked secrets using Kingfisher / kingfisher-secrets-scan (push) Successful in 13s
2026-10-21 11:08:22 +05:30
dhanabalan
91771a1add Added tollfree column in plants
All checks were successful
Scan for leaked secrets using Kingfisher / kingfisher-secrets-scan (push) Successful in 14s
2026-10-21 11:07:27 +05:30
dhanabalan
7323a35e73 Changed logic in bulk sticker printing page against serial number its fetch job order
Some checks failed
Scan for leaked secrets using Kingfisher / kingfisher-secrets-scan (push) Successful in 13s
Gemini PR Review / Gemini PR Review (pull_request) Failing after 18s
Scan for leaked secrets using Kingfisher / kingfisher-secrets-scan (pull_request) Successful in 14s
Laravel Pint / pint (pull_request) Successful in 4m37s
Laravel Larastan / larastan (pull_request) Failing after 5m9s
2026-10-20 14:23:13 +05:30
dhanabalan
46f20c423c changed logic in sticker pdf service
Some checks failed
Scan for leaked secrets using Kingfisher / kingfisher-secrets-scan (push) Successful in 14s
Gemini PR Review / Gemini PR Review (pull_request) Failing after 18s
Scan for leaked secrets using Kingfisher / kingfisher-secrets-scan (pull_request) Successful in 14s
Laravel Larastan / larastan (pull_request) Failing after 6m21s
Laravel Pint / pint (pull_request) Successful in 7m39s
2026-10-20 11:59:41 +05:30
dhanabalan
31e7306a39 Added one more rule in sticker pdf service
Some checks failed
Scan for leaked secrets using Kingfisher / kingfisher-secrets-scan (push) Successful in 20s
Gemini PR Review / Gemini PR Review (pull_request) Failing after 28s
Scan for leaked secrets using Kingfisher / kingfisher-secrets-scan (pull_request) Successful in 19s
Laravel Pint / pint (pull_request) Successful in 2m56s
Laravel Larastan / larastan (pull_request) Failing after 6m24s
2026-10-20 11:47:04 +05:30
dhanabalan
4ea1d5470e Added company name rule in sticker detail
Some checks failed
Scan for leaked secrets using Kingfisher / kingfisher-secrets-scan (push) Successful in 14s
Gemini PR Review / Gemini PR Review (pull_request) Failing after 17s
Scan for leaked secrets using Kingfisher / kingfisher-secrets-scan (pull_request) Successful in 13s
Laravel Pint / pint (pull_request) Successful in 4m14s
Laravel Larastan / larastan (pull_request) Failing after 5m58s
2026-10-20 11:45:21 +05:30
dhanabalan
f41bfa0ee7 Changed logic in sticker order reprint
Some checks failed
Scan for leaked secrets using Kingfisher / kingfisher-secrets-scan (push) Successful in 15s
Gemini PR Review / Gemini PR Review (pull_request) Failing after 19s
Scan for leaked secrets using Kingfisher / kingfisher-secrets-scan (pull_request) Successful in 13s
Laravel Pint / pint (pull_request) Successful in 3m37s
Laravel Larastan / larastan (pull_request) Failing after 6m19s
2026-10-20 11:24:37 +05:30
dhanabalan
93092f45fe Added notification in sticker order reprint
Some checks failed
Scan for leaked secrets using Kingfisher / kingfisher-secrets-scan (push) Successful in 12s
Gemini PR Review / Gemini PR Review (pull_request) Failing after 14s
Scan for leaked secrets using Kingfisher / kingfisher-secrets-scan (pull_request) Successful in 12s
Laravel Larastan / larastan (pull_request) Failing after 4m43s
Laravel Pint / pint (pull_request) Successful in 3m16s
2026-10-20 11:21:17 +05:30
dhanabalan
ab6a3b7c5c changed logic in bulk sticker for machine bug
Some checks failed
Scan for leaked secrets using Kingfisher / kingfisher-secrets-scan (push) Successful in 14s
Scan for leaked secrets using Kingfisher / kingfisher-secrets-scan (pull_request) Successful in 15s
Gemini PR Review / Gemini PR Review (pull_request) Failing after 18s
Laravel Pint / pint (pull_request) Successful in 3m14s
Laravel Larastan / larastan (pull_request) Failing after 6m11s
2026-10-20 11:15:24 +05:30
dhanabalan
57b1ec5b82 Added notification in bulk sticker
Some checks failed
Scan for leaked secrets using Kingfisher / kingfisher-secrets-scan (push) Successful in 13s
Gemini PR Review / Gemini PR Review (pull_request) Failing after 15s
Scan for leaked secrets using Kingfisher / kingfisher-secrets-scan (pull_request) Successful in 12s
Laravel Larastan / larastan (pull_request) Failing after 5m59s
Laravel Pint / pint (pull_request) Successful in 4m10s
2026-10-20 11:09:36 +05:30
dhanabalan
6f9347011f changed logic in bulk sticker printing of machine issue
Some checks failed
Scan for leaked secrets using Kingfisher / kingfisher-secrets-scan (push) Successful in 15s
Gemini PR Review / Gemini PR Review (pull_request) Failing after 25s
Scan for leaked secrets using Kingfisher / kingfisher-secrets-scan (pull_request) Successful in 20s
Laravel Pint / pint (pull_request) Successful in 3m40s
Laravel Larastan / larastan (pull_request) Failing after 7m22s
2026-10-20 11:05:01 +05:30
dhanabalan
ab2c6c6e3f Added validation in sticker mapping master page
Some checks failed
Scan for leaked secrets using Kingfisher / kingfisher-secrets-scan (push) Successful in 13s
Scan for leaked secrets using Kingfisher / kingfisher-secrets-scan (pull_request) Successful in 14s
Gemini PR Review / Gemini PR Review (pull_request) Failing after 18s
Laravel Pint / pint (pull_request) Successful in 3m31s
Laravel Larastan / larastan (pull_request) Failing after 7m19s
2026-10-20 10:59:09 +05:30
dhanabalan
ad688fb3b1 Added notification in bulk sticker printing page
Some checks failed
Scan for leaked secrets using Kingfisher / kingfisher-secrets-scan (push) Successful in 13s
Scan for leaked secrets using Kingfisher / kingfisher-secrets-scan (pull_request) Successful in 15s
Gemini PR Review / Gemini PR Review (pull_request) Failing after 17s
Laravel Pint / pint (pull_request) Successful in 4m2s
Laravel Larastan / larastan (pull_request) Failing after 4m34s
2026-10-20 10:52:14 +05:30
dhanabalan
4f97cd607e Added logic in sticker pdf service
Some checks failed
Scan for leaked secrets using Kingfisher / kingfisher-secrets-scan (push) Successful in 13s
Gemini PR Review / Gemini PR Review (pull_request) Failing after 25s
Scan for leaked secrets using Kingfisher / kingfisher-secrets-scan (pull_request) Successful in 21s
Laravel Pint / pint (pull_request) Successful in 3m46s
Laravel Larastan / larastan (pull_request) Failing after 6m22s
2026-10-20 10:10:07 +05:30
dhanabalan
bb74a6c480 Added two more options in sticker detail resource page
Some checks failed
Scan for leaked secrets using Kingfisher / kingfisher-secrets-scan (push) Successful in 21s
Scan for leaked secrets using Kingfisher / kingfisher-secrets-scan (pull_request) Successful in 16s
Gemini PR Review / Gemini PR Review (pull_request) Failing after 19s
Laravel Pint / pint (pull_request) Successful in 2m25s
Laravel Larastan / larastan (pull_request) Failing after 6m34s
2026-10-20 10:02:41 +05:30
dhanabalan
9015095ecc Added feed back column in plant resource
Some checks failed
Scan for leaked secrets using Kingfisher / kingfisher-secrets-scan (push) Successful in 14s
Scan for leaked secrets using Kingfisher / kingfisher-secrets-scan (pull_request) Successful in 1m7s
Gemini PR Review / Gemini PR Review (pull_request) Failing after 1m15s
Laravel Pint / pint (pull_request) Successful in 3m3s
Laravel Larastan / larastan (pull_request) Failing after 5m56s
2026-10-20 09:56:16 +05:30
dhanabalan
43c474bb59 Added feed address in plant model file
All checks were successful
Scan for leaked secrets using Kingfisher / kingfisher-secrets-scan (push) Successful in 17s
2026-10-20 09:54:05 +05:30
dhanabalan
1db5e62e21 Added feed address column in plants table
Some checks failed
Scan for leaked secrets using Kingfisher / kingfisher-secrets-scan (push) Has been cancelled
2026-10-20 09:52:43 +05:30
109 changed files with 10085 additions and 512 deletions

View File

@@ -13,6 +13,7 @@ use Illuminate\Support\Facades\Log;
use Illuminate\Support\Facades\Mail;
use Illuminate\Support\Facades\Storage;
use Illuminate\Support\Facades\Schema;
use Illuminate\Support\Facades\File;
class ProcessSftpFiles extends Command
{
@@ -27,229 +28,562 @@ class ProcessSftpFiles extends Command
$this->sftpService = $sftpService;
}
// public function handle()
// {
// // $files = Storage::disk('ftp')->allFiles();
// $folders = Storage::disk('ftp')->directories();
// $allFiles = [];
// foreach ($folders as $folder) {
// Log::info("Checking folder: $folder");
// // Get files inside the current folder
// $files = Storage::disk('ftp')->files($folder);
// foreach ($files as $file) {
// $allFiles[] = $file;
// }
// }
// if (empty($allFiles)) {
// $this->info('No files to process.');
// return;
// }
// $logMessages = [];
// foreach ($allFiles as $file)
// {
// $this->info("Processing file: $file");
// $folderName = explode('/', $file)[0];
// $plant = Plant::where('code', $folderName)->first();
// if (!$plant) {
// $this->warn("No plant found for folder: $folderName. Skipping file.");
// $logMessages[] = $folderName;
// continue;
// }
// $plantId = $plant->id;
// $plantCode = $plant->code ?? null;
// $fileName = basename($file); // GMGLAS03-1818199-1.txt
// $workCenterCode = explode('-', $fileName)[0]; // GMGLAS03
// $machine = Machine::where('work_center', $workCenterCode)->first();
// if (!$machine) {
// $message = "Machine '$workCenterCode' not found and file name '$file'";
// $logMessages[] = $message;
// continue;
// }
// $machineAgaPlant = Machine::where('plant_id', $plantId)->where('work_center', $workCenterCode)->first();
// if (!$machineAgaPlant) {
// $message = "Machine '$workCenterCode' not found for plant code '$plantCode' and file name '$file'";
// $logMessages[] = $message;
// continue;
// }
// $machineId = $machineAgaPlant->id;
// $content = $this->sftpService->getFileContent($file);
// $lines = array_filter(preg_split("/\r\n|\n|\r/", $content));
// $headers = array_map(fn($header) => strtolower(trim($header)), str_getcsv(array_shift($lines)));
// $dbColumns = Schema::getColumnListing('production_temps');
// $missingColumns = array_diff($headers, $dbColumns);
// if (!empty($missingColumns)) {
// $message = "Skipping file: $file. The following columns do not exist in the database. Please add them to the database: " . implode(', ', $missingColumns);
// $logMessages[] = $message;
// $this->warn($message);
// continue;
// }
// $expectedColumns = count($headers);
// $isValidFile = true;
// $isserialNotEmptyFile = true;
// foreach ($lines as $lineNumber => $line) {
// $data = str_getcsv($line);
// if (!empty($data[0])) {
// if (count($data) != $expectedColumns) {
// $message = "Column mismatch in file: $file at line " . ($lineNumber + 2) .
// ". Expected $expectedColumns, got " . count($data);
// $logMessages[] = $message;
// $isValidFile = false;
// break;
// }
// }
// }
// if (!$isValidFile) {
// $message = "Skipping entire file due to invalid column mismatch: $file";
// $logMessages[] = $message;
// continue;
// }
// else if (!$isserialNotEmptyFile) {
// $message = "serial number not found in file name $file";
// $logMessages[] = $message;
// continue;
// }
// $rows = [];
// // foreach ($lines as $line) {
// // $data = str_getcsv($line);
// // if (!empty($data[0])) {
// // $row = [];
// // foreach ($headers as $index => $column) {
// // $row[$column] = isset($data[$index]) ? trim($data[$index]) : null;
// // }
// // $row['plant_id'] = $plantId;
// // $row['machine_id'] = $machineId;
// // $row['created_at'] = now();
// // $row['updated_at'] = now();
// // // $rows[] = $row;
// // if (!empty($row['gernr'])) {
// // $rows[] = $row;
// // }
// // }
// // }
// foreach ($lines as $line) {
// $data = str_getcsv($line);
// if (!empty($data[0])) {
// $row = [];
// foreach ($headers as $index => $column) {
// $row[$column] = isset($data[$index])
// ? trim($data[$index])
// : null;
// }
// $row['plant_id'] = $plantId;
// $row['machine_id'] = $machineId;
// $row['created_at'] = now();
// $row['updated_at'] = now();
// if (empty($row['gernr'])) {
// $message = "serial number not found in file name $file";
// $logMessages[] = $message;
// continue;
// }
// $gamng = (float) ($row['gamng'] ?? 0);
// $lmnga = (float) ($row['lmnga'] ?? 0);
// $existingRecords = ProductionTemp::where('plant_id', $plantId)
// ->where('aufnr', ($row['aufnr']))
// ->get();
// $existingRecord = $existingRecords->where('gernr', $row['gernr'])->first();
// $lastStatus = $existingRecords->max('pending_released_status');
// if ($gamng == $lmnga) {
// $row['pending_released_status'] = 0;
// $this->info("Production order {$row['aufnr']} completed. " ."Serial: {$row['gernr']}. " ."GAMNG: {$row['gamng']}, LMNGA: {$row['lmnga']}. " ."pending_released_status = 0" );
// } elseif ($existingRecord) {
// $row['pending_released_status'] = (int) $existingRecord->pending_released_status;
// $this->info("Same serial already exists. " ."Production order: {$row['aufnr']}. " ."Serial: {$row['gernr']}. " ."Keeping pending_released_status = {$row['pending_released_status']}");
// } else {
// if ($existingRecords->isEmpty()) {
// // First release
// $row['pending_released_status'] = 0;
// } else {
// $row['pending_released_status'] = ((int) $lastStatus) + 1;
// }
// $this->info("Production order {$row['aufnr']} pending. " ."New serial: {$row['gernr']}. " . "GAMNG: {$row['gamng']}, LMNGA: {$row['lmnga']}. " ."pending_released_status = {$row['pending_released_status']}");
// }
// $rows[] = $row;
// }
// }
// if (!empty($rows)) {
// ProductionTemp::upsert($rows, ['plant_id', 'gernr'], array_keys($rows[0])); //(update + insert)
// }
// }
// if (!empty($logMessages)) {
// $content = implode(PHP_EOL, $logMessages);
// Mail::raw('Please find attached machine error logs.', function ($message) use ($content) {
// $message->to(env('ERROR_LOG_MAIL'))
// ->subject('Machine Error Logs')
// ->attachData($content, 'machine_errors.txt', [
// 'mime' => 'text/plain',
// ]);
// });
// }
// }
public function handle()
{
$basePath = '/var/www/ftpdata';
$files = Storage::disk('ftp')->allFiles();
$folders = Storage::disk('ftp')->directories();
// $basePath = '/home/iot-dev/projects/pds/ftpdata';
$allFiles = [];
$logMessages = [];
foreach ($folders as $folder) {
// Check whether data2 exists
if (!File::isDirectory($basePath)) {
$this->error("Directory not found: {$basePath}");
return;
}
Log::info("Checking folder: $folder");
$folders = Plant::pluck('code');
// Get files inside the current folder
$files = Storage::disk('ftp')->files($folder);
foreach ($folders as $folderName) {
$folderPath = $basePath . '/' . $folderName;
if (!File::isDirectory($folderPath)) {
File::makeDirectory($folderPath, 0755, true);
// Set ownership
exec("chown www-data:www-data " . escapeshellarg($folderPath));
$this->info("Created missing folder: {$folderName}");
}
}
// Get plant folders: 1000, 1010, etc.
$folders = File::directories($basePath);
if (empty($folders)) {
$this->info('No plant folders found.');
return;
}
// Collect TXT files from each plant folder
foreach ($folders as $folderPath) {
$folderName = basename($folderPath);
Log::info("Checking plant folder: {$folderName}");
// Get files inside the plant folder
$files = File::files($folderPath);
foreach ($files as $file) {
$allFiles[] = $file;
if (strtolower($file->getExtension()) !== 'txt') {
continue;
}
$allFiles[] = [
'path' => $file->getPathname(),
'folder' => $folderName,
];
}
}
if (empty($allFiles)) {
$this->info('No files to process.');
$this->info('No TXT files to process.');
return;
}
$logMessages = [];
$dbColumns = Schema::getColumnListing('production_temps');
foreach ($allFiles as $file)
{
$this->info("Processing file: $file");
// Process each TXT file
foreach ($allFiles as $fileDetails) {
$folderName = explode('/', $file)[0];
$file = $fileDetails['path'];
$folderName = $fileDetails['folder'];
$this->info("Processing file: {$file}");
// Find plant using folder name
$plant = Plant::where('code', $folderName)->first();
if (!$plant) {
$this->warn("No plant found for folder: $folderName. Skipping file.");
$logMessages[] = $folderName;
$message = "No plant found for folder: {$folderName}. File: {$file}";
$this->warn($message);
$logMessages[] = $message;
continue;
}
$plantId = $plant->id;
$plantCode = $plant->code;
$plantCode = $plant->code ?? null;
// Get filename and work center
// Example: GMGLAS03-1818199-1.txt
$fileName = basename($file);
$fileName = basename($file); // GMGLAS03-1818199-1.txt
$workCenterCode = explode('-', $fileName)[0]; // GMGLAS03
$workCenterCode = explode('-', $fileName)[0];
// Find machine belonging to this plant
$machine = Machine::where('plant_id', $plantId)
->where('work_center', $workCenterCode)
->first();
$machine = Machine::where('work_center', $workCenterCode)->first();
if (!$machine) {
$message = "Machine '$workCenterCode' not found and file name '$file'";
$message = "Machine '{$workCenterCode}' not found for plant '{$plantCode}'. File: {$file}";
$this->warn($message);
$logMessages[] = $message;
continue;
}
$machineAgaPlant = Machine::where('plant_id', $plantId)->where('work_center', $workCenterCode)->first();
if (!$machineAgaPlant) {
$message = "Machine '$workCenterCode' not found for plant code '$plantCode' and file name '$file'";
$machineId = $machine->id;
// Read local TXT file
$content = File::get($file);
// Split file into lines
$lines = preg_split("/\r\n|\n|\r/", $content);
// Remove empty lines and reindex
$lines = array_values(array_filter($lines, fn($line) => trim($line) !== ''));
if (empty($lines)) {
$message = "File is empty: {$file}";
$this->warn($message);
$logMessages[] = $message;
continue;
}
$machineId = $machineAgaPlant->id;
// Read CSV headers
$headers = array_map(
fn($header) => strtolower(trim($header)),
str_getcsv(array_shift($lines))
);
$content = $this->sftpService->getFileContent($file);
if (empty($headers)) {
$lines = array_filter(preg_split("/\r\n|\n|\r/", $content));
$message = "Headers not found in file: {$file}";
$headers = array_map(fn($header) => strtolower(trim($header)), str_getcsv(array_shift($lines)));
$this->warn($message);
$logMessages[] = $message;
$dbColumns = Schema::getColumnListing('production_temps');
continue;
}
// Validate CSV columns against database columns
$missingColumns = array_diff($headers, $dbColumns);
if (!empty($missingColumns)) {
$message = "Skipping file: $file. The following columns do not exist in the database. Please add them to the database: " . implode(', ', $missingColumns);
$logMessages[] = $message;
$message = "Skipping file: {$file}. The following columns do not exist in the database: "
. implode(', ', $missingColumns);
$this->warn($message);
$logMessages[] = $message;
continue;
}
$expectedColumns = count($headers);
$isValidFile = true;
$isserialNotEmptyFile = true;
// Validate column count in every row
foreach ($lines as $lineNumber => $line) {
$data = str_getcsv($line);
if (!empty($data[0])) {
if (count($data) != $expectedColumns) {
$message = "Column mismatch in file: $file at line " . ($lineNumber + 2) .
". Expected $expectedColumns, got " . count($data);
if (!empty($data[0]) && count($data) != $expectedColumns) {
$logMessages[] = $message;
$message = "Column mismatch in file: {$file} at line "
. ($lineNumber + 2)
. ". Expected {$expectedColumns}, got "
. count($data);
$isValidFile = false;
break;
}
$logMessages[] = $message;
$this->warn($message);
$isValidFile = false;
break;
}
}
if (!$isValidFile) {
$message = "Skipping entire file due to invalid column mismatch: $file";
$logMessages[] = $message;
continue;
}
else if (!$isserialNotEmptyFile) {
$message = "serial number not found in file name $file";
$message = "Skipping entire file due to invalid column mismatch: {$file}";
$this->warn($message);
$logMessages[] = $message;
continue;
}
$rows = [];
// foreach ($lines as $line) {
// $data = str_getcsv($line);
// if (!empty($data[0])) {
// $row = [];
// foreach ($headers as $index => $column) {
// $row[$column] = isset($data[$index]) ? trim($data[$index]) : null;
// }
// $row['plant_id'] = $plantId;
// $row['machine_id'] = $machineId;
// $row['created_at'] = now();
// $row['updated_at'] = now();
// // $rows[] = $row;
// if (!empty($row['gernr'])) {
// $rows[] = $row;
// }
// }
// }
// Process each CSV row
foreach ($lines as $line) {
$data = str_getcsv($line);
if (!empty($data[0])) {
if (empty($data[0])) {
continue;
}
$row = [];
$row = [];
foreach ($headers as $index => $column) {
$row[$column] = isset($data[$index])
? trim($data[$index])
: null;
}
foreach ($headers as $index => $column) {
$row['plant_id'] = $plantId;
$row['machine_id'] = $machineId;
$row['created_at'] = now();
$row['updated_at'] = now();
$row[$column] = isset($data[$index])
? trim($data[$index])
: null;
}
if (empty($row['gernr'])) {
$message = "serial number not found in file name $file";
$logMessages[] = $message;
continue;
}
$row['plant_id'] = $plantId;
$row['machine_id'] = $machineId;
$row['created_at'] = now();
$row['updated_at'] = now();
$gamng = (float) ($row['gamng'] ?? 0);
$lmnga = (float) ($row['lmnga'] ?? 0);
// Validate serial number
if (empty($row['gernr'])) {
$existingRecords = ProductionTemp::where('plant_id', $plantId)
->where('aufnr', ($row['aufnr']))
->get();
$message = "Serial number not found in file {$file}";
$logMessages[] = $message;
$existingRecord = $existingRecords->where('gernr', $row['gernr'])->first();
continue;
}
$lastStatus = $existingRecords->max('pending_released_status');
$gamng = (float) ($row['gamng'] ?? 0);
$lmnga = (float) ($row['lmnga'] ?? 0);
if ($gamng == $lmnga) {
// Get existing production order records
$existingRecords = ProductionTemp::where('plant_id', $plantId)
->where('aufnr', $row['aufnr'] ?? null)
->get();
// Check whether this serial already exists
$existingRecord = $existingRecords
->where('gernr', $row['gernr'])
->first();
$lastStatus = $existingRecords->max('pending_released_status');
if ($gamng == $lmnga) {
// Production order completed
$row['pending_released_status'] = 0;
$this->info(
"Production order {$row['aufnr']} completed. "
. "Serial: {$row['gernr']}. "
. "GAMNG: {$gamng}, LMNGA: {$lmnga}. "
. "pending_released_status = 0"
);
} elseif ($existingRecord) {
// Keep existing serial status
$row['pending_released_status'] =
(int) $existingRecord->pending_released_status;
$this->info(
"Same serial already exists. "
. "Production order: {$row['aufnr']}. "
. "Serial: {$row['gernr']}. "
. "Keeping pending_released_status = {$row['pending_released_status']}"
);
} else {
if ($existingRecords->isEmpty()) {
// First release
$row['pending_released_status'] = 0;
$this->info("Production order {$row['aufnr']} completed. " ."Serial: {$row['gernr']}. " ."GAMNG: {$row['gamng']}, LMNGA: {$row['lmnga']}. " ."pending_released_status = 0" );
} elseif ($existingRecord) {
$row['pending_released_status'] = (int) $existingRecord->pending_released_status;
$this->info("Same serial already exists. " ."Production order: {$row['aufnr']}. " ."Serial: {$row['gernr']}. " ."Keeping pending_released_status = {$row['pending_released_status']}");
} else {
if ($existingRecords->isEmpty()) {
// First release
$row['pending_released_status'] = 0;
} else {
$row['pending_released_status'] = ((int) $lastStatus) + 1;
}
$this->info("Production order {$row['aufnr']} pending. " ."New serial: {$row['gernr']}. " . "GAMNG: {$row['gamng']}, LMNGA: {$row['lmnga']}. " ."pending_released_status = {$row['pending_released_status']}");
// Increment pending release status
$row['pending_released_status'] = ((int) $lastStatus) + 1;
}
$rows[] = $row;
$this->info(
"Production order {$row['aufnr']} pending. "
. "New serial: {$row['gernr']}. "
. "GAMNG: {$gamng}, LMNGA: {$lmnga}. "
. "pending_released_status = {$row['pending_released_status']}"
);
}
$rows[] = $row;
}
// Insert or update records
if (!empty($rows)) {
ProductionTemp::upsert($rows, ['plant_id', 'gernr'], array_keys($rows[0])); //(update + insert)
ProductionTemp::upsert(
$rows,
['plant_id', 'gernr'],
array_keys($rows[0])
);
$this->info(
count($rows) . " records inserted/updated from {$file}"
);
}
}
// Send error logs through email
if (!empty($logMessages)) {
$content = implode(PHP_EOL, $logMessages);
$emailContent = implode(PHP_EOL, $logMessages);
Mail::raw('Please find attached machine error logs.', function ($message) use ($emailContent) {
Mail::raw('Please find attached machine error logs.', function ($message) use ($content) {
$message->to(env('ERROR_LOG_MAIL'))
->subject('Machine Error Logs')
->attachData($content, 'machine_errors.txt', [
->attachData($emailContent, 'machine_errors.txt', [
'mime' => 'text/plain',
]);
});
}
$this->info('Production TXT file processing completed.');
}
}

View File

@@ -56,10 +56,10 @@ class SendDailyTaskReport extends Command
})
->values();
if ($pdfFiles->isEmpty()) {
$this->info('No PDF files found.');
return self::SUCCESS;
}
// if ($pdfFiles->isEmpty()) {
// $this->info('No PDF files found.');
// return self::SUCCESS;
// }
$parser = new Parser();
$attachments = [];
@@ -100,6 +100,37 @@ class SendDailyTaskReport extends Command
$this->info('Attached: ' . basename($file));
}
// Expected employees
$expectedEmployees = [
'Dhanabalan Saravanan',
'Ranjith',
'Srimathi Ramamoorthy',
];
$uploadedEmployees = array_map(
fn ($row) => strtolower(trim($row['name'])),
$rows
);
foreach ($expectedEmployees as $employeeName) {
if (! in_array(
strtolower(trim($employeeName)),
$uploadedEmployees,
true
)) {
$rows[] = [
'sno' => $sno++,
'name' => $employeeName,
'project-name' => 'Not uploaded',
'task' => 'PDF not received',
'status' => 'Missing',
'completed' => '-',
];
$this->warn("PDF not uploaded by: {$employeeName}");
}
}
$toEmails = [];
$ccEmails = [];

View File

@@ -0,0 +1,150 @@
<?php
namespace App\Exports;
use App\Models\ProductionPlan;
use App\Models\Plant;
use Carbon\Carbon;
use Maatwebsite\Excel\Concerns\FromArray;
class DayPlanSampleExport implements FromArray
{
protected $plantId;
protected $lineId;
protected $year;
protected $month;
protected $week;
public function __construct($plantId, $lineId, $year, $month, $week)
{
$this->plantId = $plantId;
$this->lineId = $lineId;
$this->year = $year;
$this->month = $month;
$this->week = strtolower($week);
}
public function array(): array
{
$weekMapping = [
'week_1' => 1,
'week_2' => 8,
'week_3' => 15,
'week_4' => 22,
'week_5' => 29,
];
$daysInMonth = Carbon::create(
$this->year,
$this->month,
1
)->daysInMonth;
if ($this->week === 'all_weeks') {
$startDay = 1;
$maxDays = $daysInMonth;
} else {
if (!isset($weekMapping[$this->week])) {
throw new \Exception('Please select a valid week.');
}
$startDay = $weekMapping[$this->week];
$daysInMonth = Carbon::create(
$this->year,
$this->month,
1
)->daysInMonth;
$maxDays = min(7, $daysInMonth - $startDay + 1);
if ($maxDays <= 0) {
throw new \Exception('Selected week has no dates in this month.');
}
}
// Plant Code
$plant = Plant::find($this->plantId);
if (!$plant) {
throw new \Exception('Plant not found.');
}
// Excel headings
$headings = [
'Plant Code',
'Item Code',
];
$selectedDates = [];
for ($i = 0; $i < $maxDays; $i++) {
$day = $startDay + $i;
$date = Carbon::create(
$this->year,
$this->month,
$day
);
$selectedDates[] = $date->format('Y-m-d');
$headings[] = $date->format('d-m-Y');
}
// Existing monthly production plans
$plans = ProductionPlan::where('plant_id', $this->plantId)
->where('line_id', $this->lineId)
->whereMonth('created_at', $this->month)
->whereYear('created_at', $this->year)
->with('item')
->get();
$excelRows = [];
foreach ($plans as $plan) {
$itemCode = $plan->item->code ?? '';
// Get leave dates
$leaveDates = $plan->leave_dates ?? [];
if (is_string($leaveDates)) {
$leaveDates = explode(',', $leaveDates);
}
$leaveDates = collect($leaveDates)
->map(fn ($date) => trim($date))
->filter()
->map(fn ($date) => Carbon::parse($date)->format('Y-m-d'))
->toArray();
$row = [
$plant->code,
$itemCode,
];
foreach ($selectedDates as $date) {
// Leave date quantity is 0
if (in_array($date, $leaveDates)) {
$row[] = 0;
} else {
// Sample default quantity
$row[] = 0;
}
}
$excelRows[] = $row;
}
return array_merge(
[$headings],
$excelRows
);
}
}

View File

@@ -27,11 +27,11 @@ class AlertMailRuleExporter extends Exporter
ExportColumn::make('rule_name')
->label('RULE NAME'),
ExportColumn::make('email')
->label('EMAIL'),
->label('TO EMAIL'),
ExportColumn::make('schedule_type')
->label('SCHEDULE TYPE'),
ExportColumn::make('plant')
->label('PLANT CODE')
->label('PLANT NAME')
->formatStateUsing(function ($state) {
// $state is the plant ID from the database
if ($state == 0) {
@@ -39,12 +39,12 @@ class AlertMailRuleExporter extends Exporter
}
$plant = Plant::find($state);
return $plant ? $plant->code : 'Unknown';
return $plant ? $plant->name : 'Unknown';
}),
ExportColumn::make('machine.work_center')
->label('WORK CENTER'),
ExportColumn::make('cc_emails')
->label('CC EMAILS'),
->label('CC EMAIL'),
ExportColumn::make('invoiceMaster.receiving_plant_name')
->label('RECEIVING PLANT NAME'),
ExportColumn::make('invoiceMaster.transport_name')

View File

@@ -0,0 +1,66 @@
<?php
namespace App\Filament\Exports;
use App\Models\CourierInward;
use Filament\Actions\Exports\ExportColumn;
use Filament\Actions\Exports\Exporter;
use Filament\Actions\Exports\Models\Export;
class CourierInwardExporter extends Exporter
{
protected static ?string $model = CourierInward::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('date')
->label('DATE'),
ExportColumn::make('from_address_name')
->label('FROM ADDRESS NAME'),
ExportColumn::make('cover_material')
->label('COVER/MATERIAL'),
ExportColumn::make('pod_number')
->label('POD NUMBER'),
ExportColumn::make('courier_name')
->label('COURIER NAME'),
ExportColumn::make('place')
->label('PLACE'),
ExportColumn::make('to_address_name')
->label('TO ADDRESS NAME'),
ExportColumn::make('return_to_other_unit')
->label('RETURN TO OTHER UNIT'),
ExportColumn::make('created_at')
->label('CREATED AT'),
ExportColumn::make('created_by')
->label('CREATED BY'),
ExportColumn::make('updated_at')
->label('UPDATED AT'),
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 courier inward 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,64 @@
<?php
namespace App\Filament\Exports;
use App\Models\CourierOutward;
use Filament\Actions\Exports\ExportColumn;
use Filament\Actions\Exports\Exporter;
use Filament\Actions\Exports\Models\Export;
class CourierOutwardExporter extends Exporter
{
protected static ?string $model = CourierOutward::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('date')
->label('DATE'),
ExportColumn::make('to_address')
->label('TO ADDRESS'),
ExportColumn::make('cover_material')
->label('COVER/MATERIAL'),
ExportColumn::make('name_of_sender')
->label('NAME OF SENDER'),
ExportColumn::make('place_pincode')
->label('PLACE OF PINCODE'),
ExportColumn::make('pod_number')
->label('POD NUMBER'),
ExportColumn::make('remark')
->label('REMARK'),
ExportColumn::make('created_at')
->label('CREATED AT'),
ExportColumn::make('created_by')
->label('CREATED BY'),
ExportColumn::make('updated_at')
->label('UPDATED AT'),
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 courier outward 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

@@ -30,7 +30,7 @@ class ProductionCharacteristicExporter extends Exporter
ExportColumn::make('machine.work_center')
->label('WORK CENTER'),
ExportColumn::make('production_order')
->label('PRODUCTION ORDER'),
->label('PRODUCTION ORDER / DOC NO'),
ExportColumn::make('serial_number')
->label('SERIAL NUMBER'),
ExportColumn::make('characteristic_name')

View File

@@ -0,0 +1,79 @@
<?php
namespace App\Filament\Exports;
use App\Models\TestingLineVisualization;
use Filament\Actions\Exports\ExportColumn;
use Filament\Actions\Exports\Exporter;
use Filament\Actions\Exports\Models\Export;
class TestingLineVisualizationExporter extends Exporter
{
protected static ?string $model = TestingLineVisualization::class;
public static function getColumns(): array
{
static $rowNumber = 0;
return [
// ExportColumn::make('id')
// ->label('ID'),
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('test_bed_group')
->label('TEST BED GROUP'),
ExportColumn::make('line_no')
->label('LINE NO'),
ExportColumn::make('sale_order')
->label('SALE ORDER'),
ExportColumn::make('job_order')
->label('JOB ORDER'),
ExportColumn::make('pump_model')
->label('PUMP MODEL'),
ExportColumn::make('pump_type')
->label('PUMP TYPE'),
ExportColumn::make('motor_details')
->label('MOTOR DETAILS'),
ExportColumn::make('test_type')
->label('TEST TYPE'),
ExportColumn::make('flow')
->label('FLOW'),
ExportColumn::make('head')
->label('HEAD'),
ExportColumn::make('run_time')
->label('RUN TIME'),
ExportColumn::make('live_status')
->label('STATUS'),
ExportColumn::make('observation_remarks')
->label('OBSERVATION / REMARKS'),
ExportColumn::make('created_at')
->label('CREATED AT'),
ExportColumn::make('created_by')
->label('CREATED BY'),
ExportColumn::make('updated_at')
->label('UPDATED AT'),
ExportColumn::make('updated_by')
->label('UPDATED BY'),
ExportColumn::make('deleted_at')
->enabledByDefault(false)
->label('DELETED AT'),
];
}
public static function getCompletedNotificationBody(Export $export): string
{
$body = 'Your testing line visualization 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

@@ -128,6 +128,8 @@ class TestingPanelReadingExporter extends Exporter
->label('TEST SEQUENCE FLAG'),
ExportColumn::make('test_started_at')
->label('TEST STARTED AT'),
ExportColumn::make('test_finished_at')
->label('TEST FINISHED AT'),
ExportColumn::make('rework_count')
->label('REWORK COUNT'),
ExportColumn::make('rework_winded')

View File

@@ -0,0 +1,171 @@
<?php
namespace App\Filament\Imports;
use App\Models\CourierInward;
use App\Models\Plant;
use Filament\Actions\Imports\ImportColumn;
use Filament\Actions\Imports\Importer;
use Filament\Actions\Imports\Models\Import;
use Filament\Facades\Filament;
use Illuminate\Support\Facades\Log;
use Illuminate\Support\Str;
use Filament\Actions\Imports\Exceptions\RowImportFailedException;
use Carbon\Carbon;
class CourierInwardImporter extends Importer
{
protected static ?string $model = CourierInward::class;
public static function getColumns(): array
{
return [
ImportColumn::make('plant')
->requiredMapping()
->exampleHeader('Plant Code')
->example('1000')
->label('Plant Code')
->relationship(resolveUsing: 'code') // Lookup Plant by code column
->rules(['required']),
ImportColumn::make('date')
->requiredMapping()
->exampleHeader('Date')
->example('06-11-2026')
->label('Date')
->rules(['required']),
ImportColumn::make('from_address_name')
->exampleHeader('From Address Name')
->example('G Tech Industrial Resource & Services')
->label('From Address Name')
->rules(['required']),
ImportColumn::make('cover_material')
->exampleHeader('Cover/Material')
->example('Cover')
->label('Cover/Material')
->rules(['required']),
ImportColumn::make('pod_number')
->exampleHeader('POD Number')
->example('ET563615242IN')
->label('POD Number')
->rules(['required']),
ImportColumn::make('courier_name')
->exampleHeader('Courier Name')
->example('Trackon')
->label('Courier Name')
->rules(['required']),
ImportColumn::make('place')
->exampleHeader('Place')
->example('Ahmedabad')
->label('Place')
->rules(['required']),
ImportColumn::make('to_address_name')
->exampleHeader('To Address Name')
->example('Padmini')
->label('To Address Name')
->rules(['required']),
ImportColumn::make('return_to_other_unit')
->exampleHeader('Return To Other Unit')
->example('')
->label('Return To Other Unit'),
];
}
public function resolveRecord(): ?CourierInward
{
$warnMsg = [];
$plantCod = $this->data['plant'];
$plant = null;
$date = trim($this->data['date']);
$fromAddName = trim($this->data['from_address_name']);
$coverMat = trim($this->data['cover_material']);
$podNo = trim($this->data['pod_number']);
$courierName = trim($this->data['courier_name']);
$place = trim($this->data['place']);
$toAddName = trim($this->data['to_address_name']);
$returnToOtherUnit = trim($this->data['return_to_other_unit']);
$userName = Filament::auth()->user()->name;
if (Str::length($plantCod) < 4 || ! is_numeric($plantCod) || ! preg_match('/^[1-9]\d{3,}$/', $plantCod)) {
$warnMsg[] = 'Invalid plant code found';
} else {
$plant = Plant::where('code', $plantCod)->first();
if (! $plant) {
$warnMsg[] = 'Plant not found'; // '" . $plantCod . "'
}
}
if (trim($date) == '' || trim($date) == null) {
$warnMsg[] = 'Date is required';
}
if (trim($fromAddName) == '' || trim($fromAddName) == null) {
$warnMsg[] = 'From Address Name is required';
}
if (trim($coverMat) == '' || trim($coverMat) == null) {
$warnMsg[] = 'Cover Material is required';
}
if (trim($podNo) == '' || trim($podNo) == null) {
$warnMsg[] = 'POD Number is required';
}
if (trim($courierName) == '' || trim($courierName) == null) {
$warnMsg[] = 'Courier Name is required';
}
if (trim($place) == '' || trim($place) == null) {
$warnMsg[] = 'Place is required';
}
if (trim($toAddName) == '' || trim($toAddName) == null) {
$warnMsg[] = 'To Address Name is required';
}
try {
$parsedDate = Carbon::createFromFormat('!d-m-Y', trim($date));
if ($parsedDate === false || $parsedDate->format('d-m-Y') !== trim($date)) {
throw new \Exception('Invalid date');
}
$date = $parsedDate->format('Y-m-d');
} catch (\Exception $e) {
$warnMsg[] = 'Invalid date format. Expected format: dd-mm-yyyy';
}
if (! empty($warnMsg)) {
throw new RowImportFailedException(implode(', ', $warnMsg));
}
$record = CourierInward::create([
'plant_id' => $plant->id,
'date' => $date,
'from_address_name' => $fromAddName,
'cover_material' => $coverMat,
'pod_number' => $podNo,
'courier_name' => $courierName,
'place' => $place,
'to_address_name' => $toAddName,
'return_to_other_unit' => $returnToOtherUnit,
'created_by' => $userName,
'updated_by' => $userName,
]);
return null;
// return new CourierInward();
}
public static function getCompletedNotificationBody(Import $import): string
{
$body = 'Your courier inward 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

@@ -0,0 +1,54 @@
<?php
namespace App\Filament\Imports;
use App\Models\CourierOutward;
use Filament\Actions\Imports\ImportColumn;
use Filament\Actions\Imports\Importer;
use Filament\Actions\Imports\Models\Import;
class CourierOutwardImporter extends Importer
{
protected static ?string $model = CourierOutward::class;
public static function getColumns(): array
{
return [
ImportColumn::make('plant')
->requiredMapping()
->relationship()
->rules(['required']),
ImportColumn::make('date')
->rules(['date']),
ImportColumn::make('to_address'),
ImportColumn::make('cover_material'),
ImportColumn::make('name_of_sender'),
ImportColumn::make('place_pincode'),
ImportColumn::make('pod_number'),
ImportColumn::make('remark'),
ImportColumn::make('created_by'),
ImportColumn::make('updated_by'),
];
}
public function resolveRecord(): ?CourierOutward
{
// return CourierOutward::firstOrNew([
// // Update existing records, matching them by `$this->data['column_name']`
// 'email' => $this->data['email'],
// ]);
return new CourierOutward();
}
public static function getCompletedNotificationBody(Import $import): string
{
$body = 'Your courier outward 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

@@ -10,6 +10,7 @@ use Filament\Actions\Imports\Exceptions\RowImportFailedException;
use Filament\Actions\Imports\ImportColumn;
use Filament\Actions\Imports\Importer;
use Filament\Actions\Imports\Models\Import;
use Filament\Facades\Filament;
use Str;
class GrMasterImporter extends Importer
@@ -67,6 +68,8 @@ class GrMasterImporter extends Importer
$plant = null;
$item = null;
$userName = Filament::auth()->user()?->name;
if (Str::length($plantCod) < 4 || ! is_numeric($plantCod) || ! preg_match('/^[1-9]\d{3,}$/', $plantCod)) {
$warnMsg[] = 'Invalid plant code found';
} else {
@@ -94,26 +97,38 @@ class GrMasterImporter extends Importer
$warnMsg[] = 'User not found';
}
if (! empty($warnMsg)) {
throw new RowImportFailedException(implode(', ', $warnMsg));
} else { // if (empty($warnMsg))
$grMaster = GrMaster::where('plant_id', $plant->id)
->where('serial_number', $this->data['serial_number'])
->latest()
->first();
$serialExists = GrMaster::where('plant_id', $plant->id)
->where('serial_number', $this->data['serial_number'])
->first();
if ($grMaster) {
throw new RowImportFailedException('Serial number already exist!');
}
if ($serialExists) {
$warnMsg[] = 'Serial number already exists for this plant!';
}
GrMaster::updateOrCreate([
'plant_id' => $plant->id,
'item_id' => $item->id,
'serial_number' => $this->data['serial_number'],
'gr_number' => $this->data['gr_number'] ?? null,
'created_by' => $this->data['created_by'],
]);
$grNumberExists = GrMaster::where('plant_id', $plant->id)
->where('gr_number', $this->data['gr_number'])
->first();
if ($grNumberExists) {
$warnMsg[] = 'GR Number already exists for this plant!';
}
if (! empty($warnMsg)) {
throw new RowImportFailedException(implode(', ', $warnMsg));
}
GrMaster::updateOrCreate(
[
'plant_id' => $plant->id,
'gr_number' => $this->data['gr_number'] ?? null,
'serial_number' => $this->data['serial_number'],
],
[
'item_id' => $item->id,
'created_by' => $userName,
'updated_by' => $userName,
]
);
return null;
// return new GrMaster();

View File

@@ -111,7 +111,7 @@ class MotorTestingMasterImporter extends Importer
->requiredMapping()
->exampleHeader('Routine Test Time')
->label('Routine Test Time')
->example(['00:40:00', '00:40:00', '00:40:00'])
->example(['00:30:00', '00:30:00', '00:30:00'])
->rules(['required']),
ImportColumn::make('res_ry_ll')
->requiredMapping()

View File

@@ -6,6 +6,7 @@ use App\Models\Block;
use App\Models\Item;
use App\Models\Line;
use App\Models\Plant;
use App\Models\ProductionCalendar;
use App\Models\ProductionPlan;
use App\Models\Shift;
use App\Models\User;
@@ -35,7 +36,7 @@ class ProductionPlanImporter extends Importer
ImportColumn::make('plant')
->requiredMapping()
->exampleHeader('Plant Code')
->example(['1000', '1000'])
->example(['1000'])
->label('Plant Code')
->relationship(resolveUsing: 'code')
->rules(['required']),
@@ -49,17 +50,37 @@ class ProductionPlanImporter extends Importer
ImportColumn::make('item')
->requiredMapping()
->exampleHeader('Item Code')
->example(['123456', '210987'])
->example(['123456'])
->label('Item Code')
->relationship(resolveUsing: 'code')
->rules(['required']),
ImportColumn::make('plan_quantity')
// ImportColumn::make('plan_quantity')
// ->requiredMapping()
// ->exampleHeader('Plan Quantity')
// ->example(['500', '450'])
// ->label('Plan Quantity')
// ->numeric()
// ->rules(['required', 'integer']),
ImportColumn::make('week_1')
->requiredMapping()
->exampleHeader('Plan Quantity')
->example(['500', '450'])
->label('Plan Quantity')
->numeric()
->rules(['required', 'integer']),
->exampleHeader('Week 1')
->label('Week 1'),
ImportColumn::make('week_2')
->requiredMapping()
->exampleHeader('Week 2')
->label('Week 2'),
ImportColumn::make('week_3')
->requiredMapping()
->exampleHeader('Week 3')
->label('Week 3'),
ImportColumn::make('week_4')
->requiredMapping()
->exampleHeader('Week 4')
->label('Week 4'),
ImportColumn::make('week_5')
->requiredMapping()
->exampleHeader('Week 5')
->label('Week 5'),
// ImportColumn::make('production_quantity')
// ->requiredMapping()
// ->exampleHeader('Production Quantity')
@@ -151,48 +172,332 @@ class ProductionPlanImporter extends Importer
}
}
if (! empty($warnMsg)) {
throw new RowImportFailedException(implode(', ', $warnMsg));
foreach (['week_1', 'week_2', 'week_3', 'week_4'] as $week) {
$value = $this->data[$week] ?? null;
if (filled($value) && (! is_numeric($value) || $value < 0)) {
$warnMsg[] = "Invalid {$week} value found";
}
}
$week5 = $this->data['week_5'] ?? null;
if (
filled($week5) &&
(! is_numeric($week5) || $week5 < 0)
) {
$warnMsg[] = 'Invalid week_5 value found';
}
$recordDate = now();
$month = $recordDate->month;
$year = $recordDate->year;
$previousRecord = ProductionPlan::where('plant_id', $plant->id)
$previousRecord = ProductionCalendar::where('plant_id', $plant->id)
->whereMonth('created_at', $month)
->whereYear('created_at', $year)
->first();
if(!$previousRecord){
$warnMsg[] = 'Update this month production calendar';
}
if (! empty($warnMsg)) {
throw new RowImportFailedException(implode(', ', $warnMsg));
}
$recordDate = now();
$month = $recordDate->month;
$year = $recordDate->year;
$totalDays = $recordDate->daysInMonth;
$previousRecord = ProductionCalendar::where('plant_id', $plant->id)
->whereMonth('created_at', $month)
->whereYear('created_at', $year)
->first();
$workingDays = $previousRecord?->working_days ?? null;
// Get leave dates
$leaveDates = array_filter(
array_map(
'trim',
explode(',', (string) ($previousRecord?->leave_dates ?? ''))
)
);
// Convert leave dates into day numbers
$leaveDayNumbers = [];
foreach ($leaveDates as $leaveDate) {
try {
$date = Carbon::parse($leaveDate);
if ($date->format('Y-m') === $recordDate->format('Y-m')) {
$leaveDayNumbers[] = (int) $date->format('d');
}
} catch (\Throwable $e) {
// Ignore invalid leave dates
}
}
// Get existing production plan for this item
$productionPlan1 = ProductionPlan::where('plant_id', $plant->id)
->where('item_id', $itemAgaPlant->id)
->whereYear('created_at', $recordDate->year)
->whereMonth('created_at', $recordDate->month)
->whereYear('created_at', $year)
->whereMonth('created_at', $month)
->first();
if ($productionPlan1) {
$productionPlan1->update([
'line_id' => $line,
'plan_quantity' => $this->data['plan_quantity'],
'working_days' => $workingDays,
'operator_id' => $operatorName,
'updated_at' => now(),
]);
} else {
ProductionPlan::create([
'plant_id' => $plant->id,
'line_id' => $line,
'item_id' => $itemAgaPlant->id,
'plan_quantity' => $this->data['plan_quantity'],
'working_days' => $workingDays,
'operator_id' => $operatorName,
'created_at' => now(),
'updated_at' => now(),
]);
// Initialize daily data
$dailyData = [];
for ($day = 1; $day <= 31; $day++) {
if ($day <= $totalDays) {
$dailyData['day_' . $day] =
(int) ($productionPlan1->{'day_' . $day} ?? 0);
} else {
// Invalid dates must always remain zero
$dailyData['day_' . $day] = 0;
}
}
// Weekly ranges
$weekRanges = [
'week_1' => [1, min(7, $totalDays)],
'week_2' => [8, min(14, $totalDays)],
'week_3' => [15, min(21, $totalDays)],
'week_4' => [22, min(28, $totalDays)],
'week_5' => [29, min(31, $totalDays)],
];
// Process weekly values
foreach ($weekRanges as $week => [$start, $end]) {
if ($start > $totalDays) {
continue;
}
$weeklyValue = $this->data[$week] ?? null;
// Empty Excel value: retain existing daily values
if ($weeklyValue === null || $weeklyValue === '') {
continue;
}
// Get working days excluding leave dates
$remainingDays = [];
for ($day = $start; $day <= $end; $day++) {
if (! in_array($day, $leaveDayNumbers, true)) {
$remainingDays[] = $day;
} else {
$dailyData['day_' . $day] = 0;
}
}
$daysCount = count($remainingDays);
if ($daysCount === 0) {
continue;
}
// Replace existing weekly quantity with Excel quantity
$weeklyTotal = (int) round((float) $weeklyValue);
$dailyValue = intdiv($weeklyTotal, $daysCount);
$remainder = $weeklyTotal % $daysCount;
foreach ($remainingDays as $index => $day) {
$dailyData['day_' . $day] =
$dailyValue + ($index < $remainder ? 1 : 0);
}
}
// Calculate final monthly plan quantity
$planQuantity = array_sum($dailyData);
// Prepare plan data
$planData = array_merge([
'line_id' => $line,
'plan_quantity' => $planQuantity,
'working_days' => $workingDays,
'operator_id' => $operatorName,
'updated_at' => now(),
], $dailyData);
// Update or create production plan
if ($productionPlan1) {
$productionPlan1->update($planData);
} else {
ProductionPlan::create(array_merge($planData, [
'plant_id' => $plant->id,
'item_id' => $itemAgaPlant->id,
'created_at' => now(),
]));
}
//..Working Logic
// $recordDate = now();
// $month = $recordDate->month;
// $year = $recordDate->year;
// $previousRecord = ProductionPlan::where('plant_id', $plant->id)
// ->whereMonth('created_at', $month)
// ->whereYear('created_at', $year)
// ->first();
// $workingDays = $previousRecord?->working_days ?? null;
// // Get leave dates from the existing production plan
// $leaveDates = array_filter(
// array_map('trim', explode(',', (string) ($previousRecord?->leave_dates ?? '')))
// );
// // Convert leave dates into day numbers for the current month
// $leaveDayNumbers = [];
// foreach ($leaveDates as $leaveDate) {
// $date = Carbon::parse($leaveDate);
// if ($date->format('Y-m') === $recordDate->format('Y-m')) {
// $leaveDayNumbers[] = (int) $date->format('d');
// }
// }
// $totalDays = $recordDate->daysInMonth;
// $dailyData = [];
// for ($day = 1; $day <= 31; $day++) {
// $dailyData['day_' . $day] = 0;
// }
// $planQuantity = 0;
// foreach (['week_1', 'week_2', 'week_3', 'week_4', 'week_5'] as $week) {
// $planQuantity += (float) ($this->data[$week] ?? 0);
// }
// $planQuantity = (int) $planQuantity;
// // Dynamic weekly ranges
// $weekRanges = [
// 'week_1' => [1, min(7, $totalDays)],
// 'week_2' => [8, min(14, $totalDays)],
// 'week_3' => [15, min(21, $totalDays)],
// 'week_4' => [22, min(28, $totalDays)],
// 'week_5' => [29, min(31, $totalDays)],
// ];
// foreach ($weekRanges as $week => [$start, $end]) {
// if ($start > $totalDays) {
// continue;
// }
// $weeklyValue = $this->data[$week] ?? null;
// if ($weeklyValue === null || $weeklyValue === '') {
// continue;
// }
// $remainingDays = [];
// for ($day = $start; $day <= $end; $day++) {
// if (! in_array($day, $leaveDayNumbers)) {
// $remainingDays[] = $day;
// }
// }
// $daysCount = count($remainingDays);
// if ($daysCount === 0) {
// continue;
// }
// $weeklyTotal = (int) round((float) $weeklyValue);
// $dailyValue = intdiv($weeklyTotal, $daysCount);
// $remainder = $weeklyTotal % $daysCount;
// foreach ($remainingDays as $index => $day) {
// $dailyData['day_' . $day] =
// $dailyValue + ($index < $remainder ? 1 : 0);
// }
// }
// $dailyTotal = array_sum($dailyData);
// $productionPlan1 = ProductionPlan::where('plant_id', $plant->id)
// ->where('item_id', $itemAgaPlant->id)
// ->whereYear('created_at', $recordDate->year)
// ->whereMonth('created_at', $recordDate->month)
// ->first();
// $planData = array_merge([
// 'line_id' => $line,
// 'plan_quantity' => $planQuantity,
// 'working_days' => $workingDays,
// 'operator_id' => $operatorName,
// 'updated_at' => now(),
// ], $dailyData);
// if ($productionPlan1) {
// $productionPlan1->update($planData);
// } else {
// ProductionPlan::create(array_merge($planData, [
// 'plant_id' => $plant->id,
// 'item_id' => $itemAgaPlant->id,
// 'created_at' => now(),
// ]));
// }
//..Old Logic
// $productionPlan1 = ProductionPlan::where('plant_id', $plant->id)
// ->where('item_id', $itemAgaPlant->id)
// ->whereYear('created_at', $recordDate->year)
// ->whereMonth('created_at', $recordDate->month)
// ->first();
// if ($productionPlan1) {
// $productionPlan1->update([
// 'line_id' => $line,
// 'plan_quantity' => $this->data['plan_quantity'],
// 'working_days' => $workingDays,
// 'operator_id' => $operatorName,
// 'updated_at' => now(),
// ]);
// } else {
// ProductionPlan::create([
// 'plant_id' => $plant->id,
// 'line_id' => $line,
// 'item_id' => $itemAgaPlant->id,
// 'plan_quantity' => $this->data['plan_quantity'],
// 'working_days' => $workingDays,
// 'operator_id' => $operatorName,
// 'created_at' => now(),
// 'updated_at' => now(),
// ]);
// }
return null;
}

View File

@@ -0,0 +1,255 @@
<?php
namespace App\Filament\Imports;
use App\Models\Plant;
use App\Models\TestingLineVisualization;
use Filament\Actions\Imports\Exceptions\RowImportFailedException;
use Filament\Actions\Imports\ImportColumn;
use Filament\Actions\Imports\Importer;
use Filament\Actions\Imports\Models\Import;
use Filament\Facades\Filament;
use Illuminate\Support\Str;
class TestingLineVisualizationImporter extends Importer
{
protected static ?string $model = TestingLineVisualization::class;
public static function getColumns(): array
{
return [
ImportColumn::make('plant')
->requiredMapping()
->label('PLANT CODE')
->exampleHeader('PLANT CODE')
->example(['1000'])
->relationship(resolveUsing: 'code')
->rules(['required']),
ImportColumn::make('test_bed_group')
->requiredMapping()
->label('TEST BED GROUP')
->exampleHeader('TEST BED GROUP')
->example(['Test Bed 1'])
->rules(['required']),
ImportColumn::make('line_no')
->requiredMapping()
->label('LINE NO')
->exampleHeader('LINE NO')
->example(['1'])
->rules(['required']),
ImportColumn::make('sale_order')
->requiredMapping()
->label('SALE ORDER')
->exampleHeader('SALE ORDER')
->example(['1RA0009024'])
->rules(['required']),
ImportColumn::make('job_order')
->requiredMapping()
->label('JOB ORDER')
->exampleHeader('JOB ORDER')
->example(['7000001'])
->rules(['required']),
ImportColumn::make('pump_model')
->requiredMapping()
->label('PUMP MODEL')
->exampleHeader('PUMP MODEL')
->example(['CRP-001'])
->rules(['required']),
ImportColumn::make('pump_type')
->requiredMapping()
->label('PUMP TYPE')
->exampleHeader('PUMP TYPE')
->example(['Vertical Turbine (VT)'])
->rules(['required']),
ImportColumn::make('motor_details')
->requiredMapping()
->label('MOTOR DETAILS')
->exampleHeader('MOTOR DETAILS')
->example(['200 kW / 2950 RPM'])
->rules(['required']),
ImportColumn::make('test_type')
->requiredMapping()
->label('TEST TYPE')
->exampleHeader('TEST TYPE')
->example(['Performance'])
->rules(['required']),
ImportColumn::make('flow')
->requiredMapping()
->label('FLOW')
->exampleHeader('FLOW')
->example(['220'])
->rules(['required']),
ImportColumn::make('head')
->requiredMapping()
->label('HEAD')
->exampleHeader('HEAD')
->example(['150'])
->rules(['required']),
ImportColumn::make('run_time')
->requiredMapping()
->label('RUN TIME')
->exampleHeader('RUN TIME')
->example(['2.5'])
->rules(['required']),
ImportColumn::make('live_status')
->requiredMapping()
->label('STATUS')
->exampleHeader('STATUS')
->example(['Running'])
->rules(['required']),
ImportColumn::make('observation_remarks')
->requiredMapping()
->label('OBSERVATION / REMARKS')
->exampleHeader('OBSERVATION / REMARKS')
->example(['Normal']),
// ImportColumn::make('created_by')
// ->requiredMapping()
// ->label('CREATED BY')
// ->exampleHeader('CREATED BY')
// ->example('RAW01234'),
// ImportColumn::make('updated_by')
// ->requiredMapping()
// ->label('UPDATED BY')
// ->exampleHeader('UPDATED BY')
// ->example('RAW01234'),
];
}
public function resolveRecord(): ?TestingLineVisualization
{
$warnMsg = [];
$plantCod = trim($this->data['plant']);
$plant = null;
$plantId = null;
$testBedGroup = trim($this->data['test_bed_group']);
$lineNo = trim($this->data['line_no']);
$saleOrder = trim($this->data['sale_order']);
$jobOrder = trim($this->data['job_order']);
$pumpModel = trim($this->data['pump_model']);
$pumpType = trim($this->data['pump_type']);
$motorDetails = trim($this->data['motor_details']);
$testType = trim($this->data['test_type']);
$flow = trim($this->data['flow']);
$head = trim($this->data['head']);
$runTime = trim($this->data['run_time']);
$status = trim($this->data['live_status']);
$remarks = trim($this->data['observation_remarks']);
$createdBy = Filament::auth()->user()->name;
$updatedBy = Filament::auth()->user()->name;
if ($plantCod == null || $plantCod == '') {
$warnMsg[] = "Plant code can't be empty!";
} elseif (! is_numeric($plantCod)) {
$warnMsg[] = 'Plant code should contain only numeric values!';
} elseif (Str::length($plantCod) < 4 || Str::length($plantCod) > 7) {
$warnMsg[] = 'Plant code must be between 4 and 7 digits only!';
} elseif (! preg_match('/^[1-9]\d{3,6}$/', $plantCod)) {
$warnMsg[] = 'Invalid plant code found!';
} else {
$plant = Plant::where('code', $plantCod)->first();
}
if (! $plant) {
$warnMsg[] = 'Plant not found!';
} else {
$plantId = $plant->id;
if ($testBedGroup == null || $testBedGroup == '') {
$warnMsg[] = "Test bed group can't be empty!";
}
if ($lineNo == null || $lineNo == '') {
$warnMsg[] = "Line no can't be empty!";
}
if ($saleOrder == null || $saleOrder == '') {
$warnMsg[] = "Sale order can't be empty!";
}
if ($jobOrder == null || $jobOrder == '') {
$warnMsg[] = "Job order can't be empty!";
}
if ($pumpModel == null || $pumpModel == '') {
$warnMsg[] = "Pump model can't be empty!";
}
if ($pumpType == null || $pumpType == '') {
$warnMsg[] = "Pump type can't be empty!";
}
if ($motorDetails == null || $motorDetails == '') {
$warnMsg[] = "Motor details can't be empty!";
}
if ($testType == null || $testType == '') {
$warnMsg[] = "Test type can't be empty!";
}
if ($flow == null || $flow == '') {
$flow = '0';
} elseif (! is_numeric($flow)) {
$warnMsg[] = 'Flow must be a numeric value!';
}
if ($head == null || $head == '') {
$head = '0';
} elseif (! is_numeric($head)) {
$warnMsg[] = 'Head must be a numeric value!';
}
if ($runTime == null || $runTime == '') {
$runTime = '0.0';
} elseif (! is_numeric($runTime)) {
$warnMsg[] = 'Run time must be a numeric value!';
}
if ($status == null || $status == '') {
$warnMsg[] = "Status can't be empty!";
} elseif ($status != 'Running' && $status != 'OFF' && $status != 'Aligning' && $status != 'MTN') {
$warnMsg[] = 'Invalid status value!';
}
}
if (! empty($warnMsg)) {
throw new RowImportFailedException(implode(', ', $warnMsg));
}
TestingLineVisualization::updateOrCreate([
'plant_id' => $plantId,
'test_bed_group' => $testBedGroup,
'line_no' => $lineNo,
'sale_order' => $saleOrder,
'job_order' => $jobOrder,
'pump_model' => $pumpModel,
'pump_type' => $pumpType,
'motor_details' => $motorDetails,
'test_type' => $testType,
'flow' => $flow,
'head' => $head,
'run_time' => $runTime,
'live_status' => $status,
'observation_remarks' => $remarks,
'created_by' => $createdBy,
'updated_by' => $updatedBy,
]);
return null;
// return TestingLineVisualization::firstOrNew([
// // Update existing records, matching them by `$this->data['column_name']`
// 'email' => $this->data['email'],
// ]);
// // return new TestingLineVisualization;
}
public static function getCompletedNotificationBody(Import $import): string
{
$body = 'Your testing line visualization 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

@@ -262,6 +262,11 @@ class TestingPanelReadingImporter extends Importer
->label('TEST STARTED AT')
->exampleHeader('TEST STARTED AT')
->example('01-01-2026 00:08:00'),
ImportColumn::make('test_finished_at')
->requiredMapping()
->label('TEST FINISHED AT')
->exampleHeader('TEST FINISHED AT')
->example('01-01-2026 00:08:00'),
ImportColumn::make('rework_count')
->requiredMapping()
->label('REWORK COUNT')

View File

@@ -25,6 +25,8 @@ use Filament\Forms\Components\Section;
use Filament\Forms\Components\Select;
use Filament\Forms\Components\TextInput;
use Illuminate\Support\Facades\Log;
use Livewire\Attributes\On;
use Filament\Forms\Set;
class BulkStickerPrinting extends Page implements HasForms
{
@@ -36,12 +38,19 @@ class BulkStickerPrinting extends Page implements HasForms
public array $filters = [];
public array $serialNumbers = [''];
public $serNo;
public $ref_number;
//public $workCenter;
public function mount(): void
{
$this->form->fill();
}
public function form(Form $form): Form
{
return $form
@@ -85,7 +94,6 @@ class BulkStickerPrinting extends Page implements HasForms
TextInput::make('production_order')
->label('Production Order')
->reactive()
->required()
->afterStateUpdated(function ($state, callable $set, $get) {
for ($i = 1; $i <= 8; $i++) {
@@ -171,10 +179,10 @@ class BulkStickerPrinting extends Page implements HasForms
->where('item_id', $item->id)
->get();
if (! $stickerMappings) {
if ($stickerMappings->isEmpty()) {
Notification::make()
->title('Sticker mapping not found')
->body("No sticker mapping found for this plant and class characteristic.")
->body("No sticker mapping found for item '$itemCode' and plant '$plantName'.")
->danger()
->send();
@@ -235,7 +243,19 @@ class BulkStickerPrinting extends Page implements HasForms
}
$set('sticker_options', $stickerOptions);
$serialNumbers = ClassCharacteristic::query()
->where('plant_id', $plantId)
->where('aufnr', $state)
->pluck('gernr')
->filter()
->values()
->all();
$this->dispatch('load-serial-numbers',serialNumbers: $serialNumbers);
}),
Select::make('sticker_id')
->label('Sticker ID')
->options(fn (callable $get) => $get('sticker_options') ?? [])
@@ -265,10 +285,189 @@ class BulkStickerPrinting extends Page implements HasForms
->default([]),
TextInput::make('from_serial_number')
->label('From Serial Number')
->reactive(),
->reactive()
->afterStateUpdated(function ($state, callable $set, callable $get) {
if (blank($state)) {
return;
}
$plantId = $get('plant_id');
$machineId = $get('machine_id');
$record = ClassCharacteristic::where('plant_id', $plantId)->where('machine_id', $machineId)->where('gernr', $state)->first();
if (! $record) {
$plantName = Plant::find($plantId)?->name;
$machineName = Machine::find($machineId)?->work_center;
Notification::make()
->title('Serial Number Not Found')
->body("Serial number '{$state}' was not found against work center '$machineName' and plant '$plantName'.")
->danger()
->send();
return;
}
$plantName = Plant::where('id', $plantId)->value('name');
$workCenter = Machine::where('id', $machineId)->value('work_center');
if (empty($machineId)) {
Notification::make()
->title('Work Center not selected')
->body('Please select a Work Center first.')
->warning()
->send();
return;
}
$productionOrder = ClassCharacteristic::where('plant_id', $plantId)->where('machine_id', $machineId)->where('gernr', $state)->first();
if (! $productionOrder) {
Notification::make()
->title('Production Order not found')
->body("Production Order '{$state}' was not found against machine '$workCenter', Serial Number '$state' and plant '$plantName'.")
->danger()
->send();
return;
}
$plantId = $productionOrder->plant_id;
$itemId = $productionOrder->item_id;
$item = Item::find($itemId);
if (! $item) {
Notification::make()
->title('Item not found')
->body("Item code '{$itemId}' was not found in item master.")
->danger()
->send();
return;
}
$itemCode = $item->code;
$item = Item::where('code', $itemCode)->where('plant_id', $plantId)->first();
if (! $item) {
Notification::make()
->title('Item not found')
->body("Item '{$itemCode}' was not found for the selected plant.")
->danger()
->send();
return;
}
$itemCharacteristic = ClassCharacteristic::where('plant_id', $plantId)->where('item_id', $item->id)->first();
if (! $itemCharacteristic) {
Notification::make()
->title('Class characteristic not found')
->body("No class characteristic found for item '{$itemCode}'.")
->danger()
->send();
return;
}
// $itemCharacteristicId = $itemCharacteristic->id;
$stickerMappings = StickerMappingMaster::where('plant_id', $plantId)
->where('item_id', $item->id)
->get();
if (! $stickerMappings) {
Notification::make()
->title('Sticker mapping not found')
->body("No sticker mapping found for this plant and class characteristic.")
->danger()
->send();
return;
}
$stickerOptions = [];
foreach ($stickerMappings as $stickerMapping) {
for ($i = 1; $i <= 8; $i++) {
$machineColumn = "sticker{$i}_machine_id";
$stickerMachineId = $stickerMapping->$machineColumn;
if ((string) $stickerMachineId != (string) $machineId) {
continue;
}
$structureColumn = "sticker_structure{$i}_id";
$stickerStructureId = $stickerMapping->$structureColumn;
if (empty($stickerStructureId)) {
continue;
}
$detail = StickerStructureDetail::find($stickerStructureId);
if ($detail && $detail->sticker_id) {
$stickerOptions[$detail->sticker_id] =
$detail->sticker_id;
}
$set("sticker_structure{$i}_id", $stickerStructureId);
}
}
$set('sticker_options', $stickerOptions);
$set('production_order', $record->aufnr);
}),
TextInput::make('to_serial_number')
->label('To Serial Number')
->reactive(),
->reactive()
->afterStateUpdated(function ($state, callable $set, callable $get) {
if (blank($state)) {
return;
}
$productionOrder = $get('production_order');
$plantId = $get('plant_id');
$machineId = $get('machine_id');
$toSerialRecord = ClassCharacteristic::where('plant_id', $plantId)->where('machine_id', $machineId)->where('gernr', $state)->first();
if (! $toSerialRecord) {
Notification::make()
->title('Serial Number Not Found')
->body("To Serial Number '{$state}' was not found.")
->danger()
->send();
$set('to_serial_number', null);
return;
}
if ((string) $toSerialRecord->aufnr != (string) $productionOrder) {
Notification::make()
->title('Production Order Mismatch')
->body("To Serial Number '{$state}' does not belong to Production Order '{$productionOrder}'.")
->danger()
->send();
$set('to_serial_number', null);
return;
}
}),
])
->columns(6),
]);
@@ -798,6 +997,7 @@ class BulkStickerPrinting extends Page implements HasForms
}
}
public function generateStickerId()
{
$state = $this->form->getState();
@@ -975,7 +1175,7 @@ class BulkStickerPrinting extends Page implements HasForms
//.New Logic
$stickerMappingMasterItems = StickerMappingMaster::where('plant_id', $plantId)->get();
$stickerMappingMasterItems = StickerMappingMaster::where('plant_id', $plantId)->where('item_id', $pOrderExist->item_id)->get();
if ($stickerMappingMasterItems->isEmpty()) {
Notification::make()
@@ -1077,54 +1277,69 @@ class BulkStickerPrinting extends Page implements HasForms
$matchedMachineId = null;
// for ($i = 1; $i <= 8; $i++) {
// $structureColumn = "sticker_structure{$i}_id";
// if (
// (string) $stickerMappingMasterItem->{$structureColumn}
// == (string) $structure->id
// ) {
// $machineColumn = "sticker{$i}_machine_id";
// $matchedMachineId = $stickerMappingMasterItem->{$machineColumn};
// break;
// }
// }
// if ($matchedMachineId == null || (string) $matchedMachineId != (string) $machineId)
// {
// Notification::make()
// ->danger()
// ->title('Machine Mapping Mismatch')
// ->body("Selected machine '{$machineId}' does not match the machine mapped to the selected sticker.")
// ->send();
// return;
// }
//..New
for ($i = 1; $i <= 8; $i++) {
$structureColumn = "sticker_structure{$i}_id";
$machineColumn = "sticker{$i}_machine_id";
$mappedStructureId = $stickerMappingMasterItem->{$structureColumn} ?? null;
if (
(string) $stickerMappingMasterItem->{$structureColumn}
== (string) $structure->id
$mappedStructureId !== null &&
(string) $mappedStructureId === (string) $structure->id
) {
$machineColumn = "sticker{$i}_machine_id";
$matchedMachineId = $stickerMappingMasterItem->{$machineColumn};
$matchedMachineId = $stickerMappingMasterItem->{$machineColumn} ?? null;
break;
}
}
if (
$matchedMachineId == null ||
(string) $matchedMachineId != (string) $machineId
) {
$selectedMachineId = trim((string) $machineId);
$mappedMachineId = trim((string) $matchedMachineId);
if ($mappedMachineId === '' || $mappedMachineId !== $selectedMachineId) {
Notification::make()
->danger()
->title('Machine Mapping Mismatch')
->body("Selected machine '{$machineId}' does not match the machine mapped to the selected sticker.")
->body("Selected machine '{$selectedMachineId}' does not match the mapped machine '{$mappedMachineId}'.")
->send();
return;
}
if ((string) $matchedMachineId != (string) $machineId) {
Notification::make()
->danger()
->title('Machine Not Found')
->body("Machine '{$machineId}' is not mapped for Item Code '{$itemCode}' against sticker '$stickerId' in sticker mapping master.")
->send();
return;
}
// $matchedMachineId = StickerMappingMaster::where('plant_id', $plantId)->where('item_id', $pOrderExist->item_id)->where('sticker_structure1_id', $structure->id)->where('sticker1_machine_id', $machineId)->first();
// if (!$matchedMachineId) {
// if ((string) $matchedMachineId != (string) $machineId) {
// Notification::make()
// ->danger()
// ->title('Machine Not Found')
// ->body("Machine '{$machineId}' is not mapped for Item Code '{$itemCode}' in sticker mapping master.")
// ->body("Machine '{$machineId}' is not mapped for Item Code '{$itemCode}' against sticker '$stickerId' in sticker mapping master.")
// ->send();
// return;
@@ -1236,6 +1451,378 @@ class BulkStickerPrinting extends Page implements HasForms
}
#[On('generate-sticker-id')]
public function generateStickerId2(string $serialNumbers)
{
$state = $this->form->getState();
$plantId = trim($state['plant_id'] ?? '');
$machineId = trim($state['machine_id'] ?? '');
$stickerId = $state['sticker_id'] ?? null;
$pOrder = $state['production_order'] ?? null;
$fromSno = trim($state['from_serial_number'] ?? '');
$toSno = trim($state['to_serial_number'] ?? '');
$serialNumbersArray = array_filter(array_map('trim', explode(',', $serialNumbers)));
if (count($serialNumbersArray) > 50) {
Notification::make()
->title('Too Many Serial Numbers')
->body('You can enter a maximum of 50 serial numbers.')
->danger()
->send();
return;
}
$plantName = Plant::where('id', $plantId)->value('name');
if (!$stickerId) {
Notification::make()
->danger()
->title('Sticker ID Not Selected')
->body('Please Choose a Sticker ID.')
->send();
return;
}
$pOrderExist = ClassCharacteristic::where('plant_id',$plantId)->where('aufnr', $pOrder)->first();
if(!$pOrderExist){
Notification::make()
->danger()
->title('Unknown Production Order')
->body("Production Order '$pOrder' not found.")
->send();
return;
}
if($pOrderExist){
$existingSerialNumbers = ClassCharacteristic::where('plant_id', $plantId)
->where('aufnr', $pOrder)
->whereIn('gernr', $serialNumbersArray)
->pluck('gernr')
->map(fn ($value) => trim((string) $value))
->unique()
->toArray();
$invalidSerialNumbers = array_values(
array_diff($serialNumbersArray, $existingSerialNumbers)
);
if (!empty($invalidSerialNumbers)) {
Notification::make()
->danger()
->title('Unknown Serial Numbers')
->body(
"The following serial numbers do not belong to Production Order '$pOrder' "
. "for plant '$plantName': "
. implode(', ', $invalidSerialNumbers)
)
->send();
return;
}
}
$existingStickers = StickerOrder::where('plant_id', $plantId)
->where('production_order', $pOrder)
->where('sticker_id', $stickerId)
->where('print_status', 'Printed')
->whereIn('serial_number', $serialNumbersArray)
->pluck('serial_number')
->unique()
->values()
->toArray();
if (!empty($existingStickers)) {
Notification::make()
->danger()
->title('Duplicate Sticker')
->body("The following serial numbers already exist in generated stickers for ". "Sticker '$stickerId', Production Order '$pOrder', and plant '$plantName': ". implode(', ', $existingStickers))
->send();
return;
}
$structure = StickerStructureDetail::where('sticker_id',$stickerId)->first();
if (!$structure) {
Notification::make()
->danger()
->title('Sticker Structure Not Found')
->body("No sticker structure found for sticker ID '{$stickerId}'.")
->send();
return;
}
//.New Logic
$stickerMappingMasterItems = StickerMappingMaster::where('plant_id', $plantId)->where('item_id', $pOrderExist->item_id)->get();
if ($stickerMappingMasterItems->isEmpty()) {
Notification::make()
->danger()
->title('Sticker Mapping Not Found')
->body("No sticker mapping found for plant ID '{$plantId}'.")
->send();
return;
}
$structureIds = $stickerMappingMasterItems
->flatMap(function ($mapping) {
$ids = [];
for ($i = 1; $i <= 8; $i++) {
$column = "sticker_structure{$i}_id";
if (!empty($mapping->{$column})) {
$ids[] = $mapping->{$column};
}
}
return $ids;
})
->unique()
->values();
$detailsById = StickerStructureDetail::whereIn('id', $structureIds)
->get()
->keyBy('id');
$structure = null;
$stickerMappingMasterItem = null;
foreach ($stickerMappingMasterItems as $mapping) {
for ($i = 1; $i <= 8; $i++) {
$column = "sticker_structure{$i}_id";
$structureId = $mapping->{$column};
if (empty($structureId)) {
continue;
}
$detail = $detailsById->get($structureId);
if (!$detail) {
continue;
}
if ((string) $detail->sticker_id === (string) $stickerId) {
$structure = $detail;
$stickerMappingMasterItem = $mapping;
break 2;
}
}
}
if (!$structure) {
Notification::make()
->danger()
->title('Sticker Mapping Not Found')
->body("No mapping found for sticker ID '{$stickerId}' and plant ID '{$plantId}'.")
->send();
return;
}
// $checkItem = StickerMappingMaster::where('plant_id', $plantId)->where('item_id', $pOrderExist->item_id)->where('sticker_structure1_id', $structure->id)->first();
$itemCode = Item::where('id', $pOrderExist->item_id)->value('code');
$plantCode = Plant::where('id', $plantId)->value('code');
// if (!$checkItem) {
// Notification::make()
// ->danger()
// ->title('Item Not Found')
// ->body("Item code '$itemCode' not found in sticker mapping master for selected sticker ID '{$stickerId}'.")
// ->send();
// return;
// }
$itemCharacteristic1 = ClassCharacteristic::where('plant_id', $plantId)->where('aufnr', $pOrder)->where('item_id', $pOrderExist->item_id)->first();
if (!$itemCharacteristic1) {
Notification::make()
->danger()
->title('Item Not Found')
->body("Item code '{$itemCode}' was not found against job number '$pOrder' in class characteristic.")
->send();
return;
}
$matchedMachineId = null;
for ($i = 1; $i <= 8; $i++) {
$structureColumn = "sticker_structure{$i}_id";
$machineColumn = "sticker{$i}_machine_id";
$mappedStructureId = $stickerMappingMasterItem->{$structureColumn} ?? null;
if (
$mappedStructureId !== null &&
(string) $mappedStructureId === (string) $structure->id
) {
$matchedMachineId = $stickerMappingMasterItem->{$machineColumn} ?? null;
break;
}
}
$selectedMachineId = trim((string) $machineId);
$mappedMachineId = trim((string) $matchedMachineId);
if ($mappedMachineId === '' || $mappedMachineId !== $selectedMachineId) {
Notification::make()
->danger()
->title('Machine Mapping Mismatch')
->body("Selected machine '{$selectedMachineId}' does not match the mapped machine '{$mappedMachineId}'.")
->send();
return;
}
$itemCharacteristic = ClassCharacteristic::where('plant_id', $plantId)
->where('item_id', $pOrderExist->item_id)
->where('machine_id', $machineId)
->where('aufnr', $pOrder)
->first();
if(!$itemCharacteristic){
Notification::make()
->danger()
->title('Record Not Found')
->body("Record not found in class characteristic against job '$pOrder', item '$itemCode' and plant '$plantCode'.")
->send();
return;
}
$elements = StickerDetail::where('sticker_structure_detail_id',$structure->id)->get();
if ($elements->isEmpty()) {
Notification::make()
->danger()
->title('Sticker Details Not Found')
->body('No sticker details configured for the selected sticker.')
->send();
return;
}
$stickerService = new StickerPdfService();
$template = $stickerService->generateTemplate(
$structure->sticker_id,
$elements,
$itemCharacteristic,
$itemCode,
$plantId,
$machineId
);
$pdfContent = $stickerService->generateMultipleBulkFromTemplate(
$template,
$serialNumbersArray,
$itemCode,
);
$fileName = 'bulk_sticker_'. '_'. uniqid(). '.pdf';
$tempPdfPath = storage_path('app/' . $fileName);
file_put_contents(
$tempPdfPath,
$pdfContent
);
$pdfUrl = route(
'sticker.preview',
[
'path' => $fileName,
]
);
$this->dispatch('open-sticker-pdf',urls: [$pdfUrl]);
$totalStickers = count($serialNumbersArray);
$item = Item::where('id', $pOrderExist->item_id)->where('plant_id', $plantId)->first();
foreach ($serialNumbersArray as $serialNumber) {
$serialNumber = trim($serialNumber);
$exists = StickerOrder::where('plant_id', $plantId)
->where('production_order', $pOrder)
->where('sticker_id', $stickerId)
->where('serial_number', $serialNumber)
->first();
if (!$exists) {
StickerOrder::create([
'plant_id' => $plantId,
'item_id' => $item->id,
'production_order' => $pOrder,
'serial_number' => $serialNumber,
'sticker_id' => $stickerId,
'print_status' => 'Printed',
]);
}
}
Notification::make()
->success()
->title('Sticker Generated')
->body("{$totalStickers} sticker(s) generated successfully.")
->seconds(3)
->send();
return;
}
#[On('production-order-updated')]
public function updateProductionOrder(string $productionOrder): void
{
$this->filters['production_order'] = $productionOrder;
}
#[On('sticker-options')]
public function stickerStructure(array $stickerOptions): void
{
$this->filters['sticker_options'] = $stickerOptions;
}
#[On('production-order-clear')]
public function updateProductionOrderClear(): void
{
$this->filters['production_order'] = null;
}
#[On('sticker-options-clear')]
public function stickerStructureClear(): void
{
$this->filters['sticker_options'] = null;
}
public static function canAccess(): bool
{
return Auth::check() && Auth::user()->can('view sticker bulk print page');

View File

@@ -0,0 +1,216 @@
<?php
namespace App\Filament\Pages;
use App\Models\LeakTestReading;
use App\Models\Plant;
use Filament\Facades\Filament;
use Filament\Forms\Components\Section;
use Filament\Forms\Components\Select;
use Filament\Forms\Components\TextInput;
use Filament\Forms\Concerns\InteractsWithForms;
use Filament\Forms\Form;
use Filament\Notifications\Notification;
use Filament\Pages\Page;
use Illuminate\Support\Facades\Auth;
class LeakTestValidation extends Page
{
protected static ?string $navigationIcon = 'heroicon-o-rectangle-stack';
protected static string $view = 'filament.pages.leak-test-validation';
protected static ?string $navigationGroup = 'Motor Testing Panel';
protected static ?int $navigationSort = 4;
use InteractsWithForms;
public $plantId;
// public $state = [];
public array $filters = [];
public $leakTestQr;
public function mount()
{
$this->form->fill([
'plant_id' => $this->plantId,
'leak_test_qr' => null,
]);
}
public function form(Form $form): Form
{
return $form
->statePath('filters')
->schema([
Section::make('')
->schema([
Select::make('plant_id')
->label('Plant')
->reactive()
// ->options(Plant::pluck('name', 'id'))
->options(function (callable $get) {
$userHas = Filament::auth()->user()->plant_id;
return ($userHas && strlen($userHas) > 0) ? Plant::where('id', $userHas)->pluck('name', 'id')->toArray() : Plant::pluck('name', 'id')->toArray();
})
->afterStateUpdated(function ($state, $set, callable $get, $livewire) {
$plantId = $get('plant_id');
$this->plantId = $plantId;
})
->required(),
TextInput::make('leak_test_qr')
->label('Serial Number')
->placeholder('Scan Serial Number')
->reactive()
->minLength(16)
->afterStateUpdated(function ($state, callable $get, callable $set) {
$this->plantId = $get('plant_id');
$this->leakTestQr = $state;
})
->required()
->extraAttributes([
'wire:keydown.enter' => 'processQr($event.target.value)',
]),
])
->columns(2),
]);
}
public function processQr($value)
{
$plantId = $this->plantId;
$this->leakTestQr = trim($value);
$parts = explode('|', trim($value));
$validQr = false;
if (! $plantId) {
Notification::make()
->title('Please select a plant first!')
->danger()
->duration(5000)
->send();
} elseif (! $value) {
Notification::make()
->title('Please scan the serial number!')
->danger()
->duration(5000)
->send();
} elseif (! preg_match('/^[^|]+\|[^|]+\|?$/', trim($value)) && count($parts) > 1) {
Notification::make()
->title('Invalid QR Format')
->body("Expected format: ItemCode|SerialNumber<br>Received Format '$value'")
->danger()
->duration(5000)
->send();
} elseif (count($parts) == 1) {
$sNumber = trim($value);
if (strlen($sNumber) < 9) {
Notification::make()
->title('Invalid Serial Number')
->body("Serial number '$sNumber' should contain minimum 9 digits!")
->danger()
->duration(5000)
->send();
} elseif (! ctype_alnum($sNumber)) {
Notification::make()
->title('Invalid Serial Number')
->body("Serial number '$sNumber' should contain only alpha numeric values!")
->danger()
->duration(5000)
->send();
} elseif (! preg_match('/^[1-9][a-zA-Z0-9]{8,}$/', $sNumber)) {
Notification::make()
->title('Invalid Serial Number')
->body("Serial number '{$sNumber}' should not begin with '0' or letter!")
->danger()
->duration(5000)
->send();
} else {
$validQr = true;
}
} else {
$iCode = trim($parts[0]);
$sNumber = isset($parts[1]) ? trim($parts[1]) : null;
if (strlen($iCode) < 6) {
Notification::make()
->title('Invalid Item Code')
->body("Item code '$iCode' should contain minimum 6 digits!")
->danger()
->duration(5000)
->send();
} elseif (! ctype_alnum($iCode)) {
Notification::make()
->title('Invalid Item Code')
->body("Item code '$iCode' should contain only alpha numeric values!")
->danger()
->duration(5000)
->send();
} elseif (! preg_match('/^[a-zA-Z1-9][a-zA-Z0-9]{5,}$/', $iCode)) {
Notification::make()
->title('Invalid Item Code')
->body("Item code '{$iCode}' should not begin with '0'!")
->danger()
->duration(5000)
->send();
} elseif (strlen($sNumber) < 9) {
Notification::make()
->title('Invalid Serial Number')
->body("Serial number '$sNumber' should contain minimum 9 digits!")
->danger()
->duration(5000)
->send();
} elseif (! ctype_alnum($sNumber)) {
Notification::make()
->title('Invalid Serial Number')
->body("Serial number '$sNumber' should contain only alpha numeric values!")
->danger()
->duration(5000)
->send();
} elseif (! preg_match('/^[1-9][a-zA-Z0-9]{8,}$/', $sNumber)) {
Notification::make()
->title('Invalid Serial Number')
->body("Serial number '{$sNumber}' should not begin with '0' or letter!")
->danger()
->duration(5000)
->send();
} else {
$validQr = true;
}
}
if ($validQr) {
$leakTestQrExists = LeakTestReading::where('plant_id', $plantId)->where('serial_number', $sNumber)->latest()->first();
if (! $leakTestQrExists) {
Notification::make()
->title('No leak test readings found!')
->danger()
->duration(5000)
->send();
} else {
$leakStat = ($leakTestQrExists->test_status == 'P') ? 'Pass' : 'Fail';
Notification::make()
->title('Leak Test Readings Found')
->body("Item Code : {$leakTestQrExists->item_code} <br> Serial Number : {$leakTestQrExists->serial_number} <br> Test Status : {$leakStat} <br> Created At : {$leakTestQrExists->created_at->format('d-m-Y H:i:s')}")
->success()
->duration(5000)
->send();
}
}
$this->leakTestQr = null;
$this->form->fill([
'plant_id' => $this->plantId,
'leak_test_qr' => null,
]);
}
public static function canAccess(): bool
{
return Auth::check() && Auth::user()->can('view leak test validation page');
}
}

View File

@@ -17,6 +17,7 @@ use Filament\Forms\Components\Select;
use Filament\Forms\Components\TextInput;
use Filament\Facades\Filament;
use Illuminate\Support\Facades\Auth;
use App\Models\InvoiceValidation;
class PanelBoxInspectionStock extends Page
{
@@ -288,11 +289,11 @@ class PanelBoxInspectionStock extends Page
{
$parts = explode('/', $itemId);
if (count($parts) < 3) {
if (!preg_match('/^\d+\/\d+\/\d{4}\/\d+$/', $itemId) || preg_match('/[a-zA-Z]/', $itemId)) {
Notification::make()
->title('Invalid QR Format')
->body('Expected format: plantcode/itemcode/yearmm/serialnumber (Or) plantcode/panelboxcode/serialnumber')
->body("Expected format: plantcode/itemcode/yearmm/serialnumber : Format Received : $itemId")
->danger()
->send();
$this->form->fill([
@@ -310,10 +311,10 @@ class PanelBoxInspectionStock extends Page
$itemCode = $panelBoxCode;
$serialNumber = $panelBoxSerialNo;
if (strlen($serialNumber) > 30) {
if (strlen($serialNumber) > 15) {
Notification::make()
->title('Invalid Serial Number')
->body("Serial number cannot be greater than 30 characters. Current length: " . strlen($panelBoxSerialNo))
->body("Serial number cannot be greater than 15 characters. Current length: " . strlen($panelBoxSerialNo))
->danger()
->send();
@@ -358,10 +359,11 @@ class PanelBoxInspectionStock extends Page
return;
}
}
else {
else
{
Notification::make()
->title('Invalid QR Format')
->body('Expected format: plantcode/itemcode/yearmm/serialnumber (Or) plantcode/panelboxcode/serialnumber')
->body('Expected format: plantcode/itemcode/yearmm/serialnumber')
->danger()
->send();
$this->form->fill([
@@ -444,22 +446,63 @@ class PanelBoxInspectionStock extends Page
}
}
$serialExists = PanelBoxValidation::where('plant_id', $plantId)->where('serial_number', $serialNumber)->where('panel_box_supplier', $supplier)->first();
$panelExistsInvoice = InvoiceValidation::where('plant_id', $plantId)
->where('panel_box_serial_number', $serialNumber)
->where('panel_box_supplier', $supplier)
->first();
if ($serialExists) {
if ($panelExistsInvoice) {
Notification::make()
->title('Duplicate Serial Number')
->body("Serial number already exists '$serialNumber' with supplier number '$supplier'.")
->title('Duplicate Panel Box Serial Number')
->body("Duplicate panel already exists.<br>Panel Box Code: $itemCode, Serial Number: $serialNumber, Supplier Number: $supplier against invoice Number: $panelExistsInvoice->invoice_number")
->danger()
->seconds(4)
->send();
$this->form->fill([
'plant_id' => $plantId,
'line_id' => $lineId,
'item_id' => null,
]);
return;
}
$serialExists = PanelBoxValidation::where('plant_id', $plantId)->where('serial_number', $serialNumber)->where('panel_box_supplier', $supplier)->first();
if ($serialExists) {
if($serialExists->inspection_lot_number != '' && $serialExists->production_order != ''){
Notification::make()
->title('Already Scanned In Testing')
->body("Serial number already scanned '$serialNumber' with supplier number '$supplier'.<br>Please scan this serial number in Invoice Validation.")
->success()
->send();
$this->dispatch('play-error-sound');
$this->form->fill([
'plant_id' => $plantId,
'line_id' => $lineId,
'item_id' => null,
]);
return;
}
else{
Notification::make()
->title('Already Scanned In Stock')
->body("Serial number already scanned '$serialNumber' with supplier number '$supplier'.<br>Please scan this serial number in Invoice Validation.")
->success()
->send();
$this->dispatch('play-error-sound');
$this->form->fill([
'plant_id' => $plantId,
'line_id' => $lineId,
'item_id' => null,
]);
return;
}
}
$item = Item::where('code', $itemCode)->where('plant_id', $plantId)->first();
if (! $item) {

View File

@@ -4,6 +4,7 @@ namespace App\Filament\Pages;
use App\Models\CustomerPoMaster;
use App\Models\Plant;
use App\Models\ProductionCalendar;
use App\Models\ProductionPlan;
use App\Models\WireMasterPacking;
use Filament\Facades\Filament;
@@ -139,27 +140,36 @@ class ProductionCalender extends Page
return;
}
$updated = ProductionPlan::where('plant_id', $plantId)
$updated = ProductionCalendar::where('plant_id', $plantId)
->whereMonth('created_at', $month)
->whereYear('created_at', $year)
->update([
'working_days' => $workingDays,
'leave_dates' => $dates,
'updated_at' => now(),
]);
->first();
if ($updated) {
$updated->update([
'working_days' => $workingDays,
'leave_dates' => $dates,
]);
Notification::make()
->title('Success')
->body("Working days updated successfully!")
->success()
->send();
return;
} else {
ProductionCalendar::create([
'plant_id' => $plantId,
'working_days' => $workingDays,
'leave_dates' => $dates,
]);
Notification::make()
->title('No Records Updated')
->body("No production plans found for this plant and month.")
->warning()
->title('Record Created Successfully')
->body("Production calendar plans created for this plant and month.")
->success()
->send();
return;
}
}

View File

@@ -0,0 +1,383 @@
<?php
namespace App\Filament\Pages;
use App\Exports\DayPlanSampleExport;
use Filament\Pages\Page;
use Illuminate\Support\Facades\Auth;
use Filament\Forms\Form;
use Filament\Forms\Components\Section;
use Filament\Forms\Components\Select;
use Filament\Forms\Components\TextInput;
use Filament\Notifications\Notification;
use Filament\Facades\Filament;
use App\Models\Plant;
use Filament\Actions\Action;
use Filament\Forms\Components\FileUpload;
use Maatwebsite\Excel\Facades\Excel;
use Illuminate\Support\Facades\Storage;
use App\Imports\DayPlanTargetImport;
class ProductionPlanTarget extends Page
{
protected static ?string $navigationIcon = 'heroicon-o-document-text';
protected static string $view = 'filament.pages.production-plan-target';
protected static ?string $navigationGroup = 'Production Report';
public array $filters = [];
public function form(Form $form): Form
{
return $form
->statePath('filters')
->schema([
Section::make('')
->schema([
Select::make('year')
->label('Year')
->reactive()
// ->searchable()
->options([
'2025' => '2025',
'2026' => '2026',
'2027' => '2027',
'2028' => '2028',
'2029' => '2029',
'2030' => '2030',
'2031' => '2031',
'2032' => '2032',
'2033' => '2033',
'2034' => '2034',
'2035' => '2035',
'2036' => '2036',
'2037' => '2037',
'2038' => '2038',
'2039' => '2039',
'2040' => '2040',
])
->required()
->afterStateUpdated(function ($state, callable $get, $set) {
$set('month', null);
$set('plant_id', null);
$set('line_id', null);
$set('category', null);
$plantId = $get('plant_id');
$lineId = $get('line_id');
// $this->dispatch('loadData',$plantId, $lineId, $state, '');
$this->dispatch('loadData',$state, '', '', '', '');
}),
Select::make('month')
->label('Month')
->reactive()
// ->searchable()
->options([
'01' => 'January',
'02' => 'February',
'03' => 'March',
'04' => 'April',
'05' => 'May',
'06' => 'June',
'07' => 'July',
'08' => 'August',
'09' => 'September',
'10' => 'October',
'11' => 'November',
'12' => 'December',
])
->required()
->afterStateUpdated(function ($state, callable $get, $set) {
$set('plant_id', null);
$set('line_id', null);
$set('category', null);
$year = $get('year');
$this->dispatch('loadData',$year, $state, '', '', '');
// $plantId = $get('plant_id');
// $lineId = $get('line_id');
// // $month = $get('month');
// $year = $get('year');
// $month = (int) $get('month');
// if (!$month) {
// return;
// }
// $this->dispatch('loadData', $plantId, $lineId, $month, $year);
}),
Select::make('plant_id')
->label('Plant')
->relationship('plant', 'name')
->reactive()
// ->searchable()
->options(function (callable $get) {
$userHas = Filament::auth()->user()->plant_id;
return ($userHas && strlen($userHas) > 0) ? Plant::where('id', $userHas)->pluck('name', 'id')->toArray() : Plant::pluck('name', 'id')->toArray();
})
->required()
->afterStateUpdated(function ($state, callable $get, $set) {
// dd($state);
$set('line_id', null);
$set('category', null);
$this->dispatch('loadData',$state, '', '', '', '');
}),
Select::make('line_id')
->label('Line')
->required()
// ->relationship('line', 'name')
// ->searchable()
->columnSpan(1)
->options(function (callable $get) {
if (!$get('plant_id')) {
return [];
}
return \App\Models\Line::where('plant_id', $get('plant_id'))
->pluck('name', 'id')
->toArray();
})
->reactive()
->afterStateUpdated(function ($state, callable $get, $set) {
$this->dispatch('loadData',$state, '', '', '', '');
}),
// ->afterStateUpdated(function ($state, callable $get, $set) {
// $plantId = $get('plant_id');
// $lineId = $state;
// // $month = $get('month');
// $year = $get('year');
// $month = (int) $get('month');
// $this->dispatch('loadData',$year, $month, $plantId, $lineId, '');
// }),
Select::make('week')
->label('Choose Week')
->reactive()
// ->searchable()
->options([
'all_weeks' => 'All Weeks',
'Week_1' => 'Week 1',
'Week_2' => 'Week 2',
'Week_3' => 'Week 3',
'Week_4' => 'Week 4',
'Week_5' => 'Week 5',
])
->required()
->afterStateUpdated(function ($state, callable $get, $set) {
$set('category', null);
$year = $get('year');
$this->dispatch('loadData',$year, $state, '', '', '');
// $plantId = $get('plant_id');
// $lineId = $get('line_id');
// // $month = $get('month');
// $year = $get('year');
// $month = (int) $get('month');
// if (!$month) {
// return;
// }
// $this->dispatch('loadData', $plantId, $lineId, $month, $year);
}),
TextInput::make('category')
->label('Category')
->reactive()
->afterStateUpdated(function ($state, callable $get, $set) {
$plantId = $get('plant_id');
$lineId = $get('line_id');
// $month = $get('month');
$year = $get('year');
$month = (int) $get('month');
$category = $get('category');
}),
])
->columns(6)
]);
}
public function export(){
$plantId = $this->filters['plant_id'] ?? null;
$lineId = $this->filters['line_id'] ?? null;
$year = $this->filters['year'] ?? null;
$month = $this->filters['month'] ?? null;
if (! $plantId) {
Notification::make()
->title('Plant')
->body("please select plant to export data..!")
->danger()
->send();
return;
}
else if (! $lineId) {
Notification::make()
->title('Line')
->body("please select line to export data..!")
->danger()
->send();
return;
}
else if (! $year) {
Notification::make()
->title('Year')
->body("please select year to export data..!")
->danger()
->send();
return;
}
else if (! $month) {
Notification::make()
->title('Month')
->body("please select month to export data..!")
->danger()
->send();
return;
}
$this->dispatch('loadData1' ,$plantId, $lineId, $year, $month);
// $this->dispatch('loadDataMonthly' ,$plantId, $lineId, $year, $month);
}
public function importDayPlan($filePath)
{
$plantId = $this->filters['plant_id'] ?? null;
$lineId = $this->filters['line_id'] ?? null;
$year = $this->filters['year'] ?? null;
$month = $this->filters['month'] ?? null;
$week = $this->filters['week'] ?? null;
if (!$plantId || !$lineId || !$year || !$month || !$week) {
Notification::make()
->title('Missing Filters')
->body('Please select Plant, Line, Year, Month and Week.')
->danger()
->send();
return;
}
try {
$fullPath = Storage::disk('local')->path($filePath);
Excel::import(
new DayPlanTargetImport(
$plantId,
$lineId,
$year,
$month,
$week
),
$fullPath
);
Notification::make()
->title('Import Successful')
->body('Selected week daily targets imported successfully.')
->success()
->send();
$this->dispatch('loadWeekData',$year, $month, $plantId, $lineId, $week);
} catch (\Throwable $e) {
Notification::make()
->title('Import Failed')
->body($e->getMessage())
->danger()
->persistent()
->send();
}
}
public function downloadSampleFormat()
{
$plantId = $this->filters['plant_id'] ?? null;
$lineId = $this->filters['line_id'] ?? null;
$year = $this->filters['year'] ?? null;
$month = $this->filters['month'] ?? null;
$week = $this->filters['week'] ?? null;
if (!$plantId || !$lineId || !$year || !$month || !$week) {
Notification::make()
->title('Missing Filters')
->body('Please select Plant, Line, Year, Month and Week.')
->danger()
->send();
return;
}
return Excel::download(
new DayPlanSampleExport(
$plantId,
$lineId,
$year,
$month,
$week
),
"Day_Plan_Sample_{$week}.xlsx"
);
}
public function generate(){
$plantId = $this->filters['plant_id'] ?? null;
$lineId = $this->filters['line_id'] ?? null;
$year = $this->filters['year'] ?? null;
$month = (int) $this->filters['month'] ?? null;
$week = $this->filters['week'] ?? null;
$category = $this->filters['category'] ?? null;
if($week != '' && $week != null){
$this->dispatch('loadWeekData',$year, $month, $plantId, $lineId, $week);
}
else if($category == '' || $category == null){
$this->dispatch('loadData',$year, $month, $plantId, $lineId, '');
}
else{
$this->dispatch('loadDataCategory',$year, $month, $plantId, $lineId, $category);
}
}
public function importDayPlanAction(): Action
{
return Action::make('importDayPlan')
->label('Import')
->form([
FileUpload::make('file')
->label('Choose Excel File')
->acceptedFileTypes([
'application/vnd.openxmlformats-officedocument.spreadsheetml.sheet',
])
->required()
->disk('local')
->directory('day-plan-imports'),
])
->action(function (array $data) {
$this->importDayPlan($data['file']);
});
}
public static function canAccess(): bool
{
return Auth::check() && Auth::user()->can('view production plan target page');
}
}

View File

@@ -277,15 +277,14 @@ class StickerOrderReprint extends Page implements HasForms
$plantId = $get('plant_id');
$machineId = $get('machine_id');
$record = ClassCharacteristic::where('plant_id', $plantId)
->where('machine_id', $machineId)
->where('gernr', $state)
->first();
$record = ClassCharacteristic::where('plant_id', $plantId)->where('machine_id', $machineId)->where('gernr', $state)->first();
if (! $record) {
$plantName = Plant::find($plantId)?->name;
$machineName = Machine::find($machineId)?->work_center;
Notification::make()
->title('Serial Number Not Found')
->body("Serial number '{$state}' was not found.")
->body("Serial number '{$state}' was not found against work center '$machineName' and plant '$plantName'.")
->danger()
->send();
@@ -1091,7 +1090,7 @@ class StickerOrderReprint extends Page implements HasForms
return;
}
$stickerMappingMasterItems = StickerMappingMaster::where('plant_id', $plantId)->get();
$stickerMappingMasterItems = StickerMappingMaster::where('plant_id', $plantId)->where('item_id', $pOrderExist->item_id)->get();
if ($stickerMappingMasterItems->isEmpty()) {
Notification::make()
@@ -1209,35 +1208,27 @@ class StickerOrderReprint extends Page implements HasForms
for ($i = 1; $i <= 8; $i++) {
$structureColumn = "sticker_structure{$i}_id";
$machineColumn = "sticker{$i}_machine_id";
$mappedStructureId = $stickerMappingMasterItem->{$structureColumn} ?? null;
if (
(string) $stickerMappingMasterItem->{$structureColumn}
== (string) $structure->id
$mappedStructureId !== null &&
(string) $mappedStructureId === (string) $structure->id
) {
$machineColumn = "sticker{$i}_machine_id";
$matchedMachineId = $stickerMappingMasterItem->{$machineColumn};
$matchedMachineId = $stickerMappingMasterItem->{$machineColumn} ?? null;
break;
}
}
if ($matchedMachineId == null || (string) $matchedMachineId != (string) $machineId)
{
$selectedMachineId = trim((string) $machineId);
$mappedMachineId = trim((string) $matchedMachineId);
if ($mappedMachineId === '' || $mappedMachineId !== $selectedMachineId) {
Notification::make()
->danger()
->title('Machine Mapping Mismatch')
->body("Selected machine '{$machineId}' does not match the machine mapped to the selected sticker.")
->send();
return;
}
if ((string) $matchedMachineId != (string) $machineId) {
Notification::make()
->danger()
->title('Machine Not Found')
->body("Machine '{$machineId}' is not mapped for Item Code '{$itemCode}' against sticker '$stickerId' in sticker mapping master.")
->body("Selected machine '{$selectedMachineId}' does not match the mapped machine '{$mappedMachineId}'.")
->send();
return;

View File

@@ -59,31 +59,47 @@ class UploadDailyReport extends Page implements HasForms
$path = 'task_updates/' . $filename;
// $duplicateExists = Storage::disk('local')->exists($path);
$expectedEmployees = [
'Dhanabalan Saravanan',
'Ranjith',
'Srimathi Ramamoorthy',
];
// if ($duplicateExists) {
// // Remove the just-uploaded file since it's a duplicate
// // Storage::disk('local')->delete($currentFile);
$filename = pathinfo(basename($currentFile), PATHINFO_FILENAME);
// Notification::make()
// ->title('File already exists')
// ->body("A file named \"{$filename}\" is already uploaded.")
// ->danger()
// ->send();
$isValid = collect($expectedEmployees)->contains(
fn ($name) => strcasecmp(trim($filename), $name) == 0
);
// $this->form->fill(['report_pdf' => null]);
// return;
// }
// else{
if (! $isValid) {
Notification::make()
->title('PDF uploaded successfully')
->success()
->send();
->title('Invalid PDF filename')
->body(
'Please upload a PDF with one of these names: '
. implode(', ', array_map(
fn ($name) => $name . '.pdf',
$expectedEmployees
))
)
->danger()
->send();
$this->form->fill(['report_pdf' => null]);
// }
return;
}
else{
Notification::make()
->title('PDF uploaded successfully')
->success()
->send();
$this->form->fill(['report_pdf' => null]);
}
}
public function removeTaskPdf(){
$fileName = $this->filters['file_name'] ?? null;
@@ -129,6 +145,55 @@ class UploadDailyReport extends Page implements HasForms
}
}
public function downloadTaskPdf(){
$fileName = $this->filters['file_name'] ?? null;
if (!$fileName) {
Notification::make()
->title('File Name Required')
->body('Please enter a file name before removing the PDF.')
->danger()
->send();
return;
}
$filePath = "task_updates/{$fileName}.pdf";
if (!Storage::disk('local')->exists($filePath)) {
Notification::make()
->title('PDF Not Found')
->body('The selected PDF does not exist.')
->danger()
->send();
$this->form->fill(['file_name' => null]);
return;
}
if (Storage::disk('local')->exists($filePath)) {
if($filePath){
$fullPath = Storage::disk('local')->path($filePath);
Notification::make()
->title('PDF Downloaded Successfully')
->body('The PDF was downloaded successfully.')
->success()
->send();
return response()->download($fullPath, "{$fileName}.pdf");
}
else{
Notification::make()
->title('PDF downloaded Failed')
->body('Unable to download the PDF. Please try again...')
->success()
->send();
return;
}
}
}
public static function canAccess(): bool
{
return Auth::check() && Auth::user()->can('view upload daily report page');

View File

@@ -37,7 +37,7 @@ class BeforeTestReadingResource extends Resource
protected static ?string $navigationGroup = 'Motor Testing Panel';
protected static ?int $navigationSort = 4;
protected static ?int $navigationSort = 5;
public static function form(Form $form): Form
{

View File

@@ -2719,8 +2719,11 @@ class ClassCharacteristicResource extends Resource
->minlength(7)
->maxlength(10),
TextInput::make('gernr')
->label('Serial Number')
->placeholder('Enter Serial Number'),
->label('FG Serial Number')
->placeholder('Enter FG Serial Number'),
TextInput::make('winded_serial_number')
->label('Winded Serial Number')
->placeholder('Enter Winded Serial Number'),
TextInput::make('zmm_heading')
->label('Heading')
->placeholder('Enter Heading'),
@@ -2793,7 +2796,7 @@ class ClassCharacteristicResource extends Resource
])
->query(function ($query, array $data) {
// Hide all records initially if no filters are applied
if (empty($data['Plant']) && empty($data['machine']) && empty($data['item_id']) && empty($data['aufnr']) && empty($data['gernr']) && empty($data['zmm_heading']) && empty($data['motor_marked_from']) && empty($data['motor_marked_to']) && empty($data['pump_marked_from']) && empty($data['pump_marked_to']) && empty($data['name_plate_marked_from']) && empty($data['name_plate_marked_to']) && empty($data['created_from']) && empty($data['created_to']) && empty($data['created_by']) && empty($data['updated_from']) && empty($data['updated_to']) && empty($data['updated_by'])) {
if (empty($data['Plant']) && empty($data['machine']) && empty($data['item_id']) && empty($data['aufnr']) && empty($data['gernr']) && empty($data['winded_serial_number']) && empty($data['zmm_heading']) && empty($data['motor_marked_from']) && empty($data['motor_marked_to']) && empty($data['pump_marked_from']) && empty($data['pump_marked_to']) && empty($data['name_plate_marked_from']) && empty($data['name_plate_marked_to']) && empty($data['created_from']) && empty($data['created_to']) && empty($data['created_by']) && empty($data['updated_from']) && empty($data['updated_to']) && empty($data['updated_by'])) {
return $query->whereRaw('1 = 0');
}
@@ -2823,6 +2826,10 @@ class ClassCharacteristicResource extends Resource
$query->where('gernr', 'like', '%'.$data['gernr'].'%');
}
if (! empty($data['winded_serial_number'])) {
$query->where('winded_serial_number', 'like', '%'.$data['winded_serial_number'].'%');
}
if (! empty($data['zmm_heading'])) {
$query->where('zmm_heading', 'like', '%'.$data['zmm_heading'].'%');
}
@@ -2901,7 +2908,11 @@ class ClassCharacteristicResource extends Resource
}
if (! empty($data['gernr'])) {
$indicators[] = 'Serial Number: '.$data['gernr'];
$indicators[] = 'FG Serial Number: '.$data['gernr'];
}
if (! empty($data['winded_serial_number'])) {
$indicators[] = 'Winded Serial Number: '.$data['winded_serial_number'];
}
if (! empty($data['zmm_heading'])) {
@@ -3343,6 +3354,34 @@ class ClassCharacteristicResource extends Resource
return;
}
// Skip header and empty rows
$dataRows = array_filter(
array_slice($rows, 1),
function ($row) {
return ! empty(array_filter($row, fn ($value) => trim((string) $value) != ''));
}
);
// Count actual data rows
$rowCount = count($dataRows);
$firstDataRow = reset($dataRows);
$orderQuantity = (int) $firstDataRow[4];
if ($rowCount != $orderQuantity) {
Notification::make()
->title('Order Quantity Mismatch')
->body("Excel row count ({$rowCount}) does not match Order Quantity ({$orderQuantity}).")
->danger()
->send();
if ($disk->exists($path)) {
$disk->delete($path);
}
return;
}
$invalidMplaCodes = [];
$invalidItemCodes = [];
$invalidWorkCenters = [];

View File

@@ -0,0 +1,407 @@
<?php
namespace App\Filament\Resources;
use App\Filament\Exports\CourierInwardExporter;
use App\Filament\Imports\CourierInwardImporter;
use App\Filament\Resources\CourierInwardResource\Pages;
use App\Filament\Resources\CourierInwardResource\RelationManagers;
use App\Models\CourierInward;
use App\Models\Plant;
use Filament\Facades\Filament;
use Filament\Forms;
use Filament\Forms\Form;
use Filament\Resources\Resource;
use Filament\Tables;
use Filament\Tables\Table;
use Illuminate\Database\Eloquent\Builder;
use Illuminate\Database\Eloquent\SoftDeletingScope;
use Filament\Tables\Actions\ExportAction;
use Filament\Tables\Actions\ImportAction;
use Filament\Tables\Filters\Filter;
use Filament\Forms\Components\DateTimePicker;
use Filament\Forms\Components\Select;
use Filament\Forms\Components\TextInput;
class CourierInwardResource extends Resource
{
protected static ?string $model = CourierInward::class;
protected static ?string $navigationIcon = 'heroicon-o-rectangle-stack';
protected static ?string $navigationGroup = 'Courier';
public static function form(Form $form): Form
{
return $form
->schema([
Forms\Components\Select::make('plant_id')
->label('Plant')
->relationship('plant', 'name')
->required()
->reactive()
->options(function (callable $get) {
$userHas = Filament::auth()->user()->plant_id;
return ($userHas && strlen($userHas) > 0) ? Plant::where('id', $userHas)->pluck('name', 'id')->toArray() : Plant::orderBy('code')->pluck('name', 'id')->toArray();
})
->afterStateUpdated(function ($state, callable $set, callable $get) {
$plantId = $get('plant_id');
if (! $plantId) {
$set('cPlantError', 'Please select a plant first.');
return;
} else {
$set('cPlantError', null);
}
})
->extraAttributes(fn ($get) => [
'class' => $get('cPlantError') ? 'border-red-500' : '',
])
->hint(fn ($get) => $get('cPlantError') ? $get('cPlantError') : null)
->hintColor('danger'),
Forms\Components\DatePicker::make('date')
->label('Choose Date')
->default(now())
->required(),
Forms\Components\TextInput::make('from_address_name')
->label('From Address Name')
->required(),
Forms\Components\Select::make('cover_material')
->label('Cover/Material')
->reactive()
->options([
'Cover' => 'Cover',
'Material' => 'Material',
'Gift Box 1No.' => 'Gift Box 1No.',
'Book' => 'Book',
'Others' => 'Others',
])
->dehydrateStateUsing(function ($state, callable $get) {
return $state == 'Others'
? $get('other_cover_material')
: $state;
}),
Forms\Components\TextInput::make('other_cover_material')
->label('Specify Other Cover/Material')
->reactive()
->visible(fn (callable $get) => $get('cover_material') == 'Others')
->required(fn (callable $get) => $get('cover_material') == 'Others')
->dehydrated(false),
Forms\Components\TextInput::make('pod_number')
->label('POD Number')
->required(),
Forms\Components\TextInput::make('courier_name')
->label('Courier Name')
->required(),
Forms\Components\TextInput::make('place')
->label('Place')
->required(),
Forms\Components\TextInput::make('to_address_name')
->label('To Address Name')
->required(),
Forms\Components\TextInput::make('return_to_other_unit')
->label('Return To Other Unit'),
Forms\Components\Hidden::make('created_by')
->label('Created By')
->default(Filament::auth()->user()?->name),
Forms\Components\Hidden::make('updated_by')
->label('Updated By')
->default(Filament::auth()->user()?->name),
]);
}
public static function table(Table $table): Table
{
return $table
->columns([
Tables\Columns\TextColumn::make('No.')
->label('No.')
->getStateUsing(function ($record, $livewire, $column, $rowLoop) {
$paginator = $livewire->getTableRecords();
$perPage = method_exists($paginator, 'perPage') ? $paginator->perPage() : 10;
$currentPage = method_exists($paginator, 'currentPage') ? $paginator->currentPage() : 1;
return ($currentPage - 1) * $perPage + $rowLoop->iteration;
}),
Tables\Columns\TextColumn::make('plant.name')
->label('Plant')
->alignCenter()
->searchable()
->sortable(),
Tables\Columns\TextColumn::make('date')
->label('Date')
->alignCenter()
->searchable()
->date()
->sortable(),
Tables\Columns\TextColumn::make('from_address_name')
->label('From Address Name')
->alignCenter()
->searchable()
->sortable(),
Tables\Columns\TextColumn::make('cover_material')
->label('Cover/Material')
->alignCenter()
->searchable()
->sortable(),
Tables\Columns\TextColumn::make('pod_number')
->label('POD Number')
->alignCenter()
->searchable()
->sortable(),
Tables\Columns\TextColumn::make('courier_name')
->label('Courier Name')
->alignCenter()
->searchable()
->sortable(),
Tables\Columns\TextColumn::make('place')
->label('Place')
->alignCenter()
->searchable()
->sortable(),
Tables\Columns\TextColumn::make('to_address_name')
->label('To Address Name')
->alignCenter()
->searchable()
->sortable(),
Tables\Columns\TextColumn::make('return_to_other_unit')
->label('Return To Other Unit')
->alignCenter()
->searchable()
->sortable(),
Tables\Columns\TextColumn::make('created_at')
->label('Created At')
->alignCenter()
->dateTime()
->sortable(),
Tables\Columns\TextColumn::make('created_by')
->label('Created By')
->alignCenter()
->searchable()
->sortable(),
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(),
Filter::make('advanced_filters')
->label('Advanced Filters')
->form([
Select::make('Plant')
->label('Search by Plant Name')
->nullable()
->options(function (callable $get) {
$userHas = Filament::auth()->user()->plant_id;
// return ($userHas && strlen($userHas) > 0) ? Plant::where('id', $userHas)->pluck('name', 'id')->toArray() : Plant::orderBy('code')->pluck('name', 'id')->toArray();
if ($userHas && strlen($userHas) > 0) {
return Plant::where('id', $userHas)->pluck('name', 'id')->toArray();
} else {
return Plant::whereHas('courierInwards', function ($query) {
$query->whereNotNull('id');
})->orderBy('code')->pluck('name', 'id')->toArray();
}
})
->searchable()
->reactive()
->afterStateUpdated(function ($state, callable $set, callable $get): void {
$set('cover_material', null);
}),
Select::make('cover_material')
->label('Cover/Material Type')
->reactive()
->options([
'Cover' => 'Cover',
'Material' => 'Material',
'Other' => 'Other',
])
->placeholder('Choose Type')
->afterStateUpdated(function ($state, callable $set, callable $get) {
$set('name', null);
}),
TextInput::make('other_type')
->label('Specify Type')
->placeholder('Enter Type')
->visible(fn (callable $get) => $get('type') == 'Other')
->required(fn (callable $get) => $get('type') == 'Other'),
TextInput::make('pod_number')
->label('POD Number')
->reactive()
->placeholder('Enter POD Number')
->afterStateUpdated(function ($state, callable $set, callable $get) {
$set('company', null);
}),
TextInput::make('courier_name')
->label('Courier Name')
->reactive()
->placeholder('Enter Courier Name')
->afterStateUpdated(function ($state, callable $set, callable $get) {
$set('place', null);
}),
TextInput::make('place')
->label('Place')
->reactive()
->placeholder('Enter Place'),
DateTimePicker::make('created_from')
->label('Created From')
->placeholder('Select From DateTime')
->reactive()
->native(false),
DateTimePicker::make('created_to')
->label('Created To')
->placeholder('Select To DateTime')
->reactive()
->native(false),
])
->query(function ($query, array $data) {
$hasAnyFilter = !empty($data['Plant'])
|| !empty($data['cover_material'])
|| !empty($data['pod_number'])
|| !empty($data['courier_name'])
|| !empty($data['place'])
|| !empty($data['created_from'])
|| !empty($data['created_to']);
if (!$hasAnyFilter) {
$query->whereDate('courier_inwards.created_at', today());
return;
}
if (! empty($data['Plant'])) {
$query->where('plant_id', $data['Plant']);
}
if (! empty($data['cover_material'])) {
if ($data['cover_material'] == 'Other') {
$query->where('cover_material', 'like', '%'.$data['other_type'].'%');
}
else{
$query->where('cover_material', $data['cover_material']);
}
}
if (! empty($data['pod_number'])) {
$query->whereRaw(
'LOWER(pod_number) LIKE ?',
['%' . strtolower($data['pod_number']) . '%']
);
}
if (! empty($data['courier_name'])) {
$query->where('courier_name', 'like', '%'.$data['courier_name'].'%');
}
if (! empty($data['place'])) {
$query->where('place', 'like', '%'.$data['place'].'%');
}
if (! empty($data['created_from'])) {
$query->where('created_at', '>=', $data['created_from']);
}
if (! empty($data['created_to'])) {
$query->where('created_at', '<=', $data['created_to']);
}
// $query->orderBy('created_at', 'asc');
})
->indicateUsing(function (array $data) {
$indicators = [];
if (! empty($data['Plant'])) {
$indicators[] = 'Plant: '.Plant::where('id', $data['Plant'])->value('name');
}
if (! empty($data['cover_material'])) {
$indicators[] = 'Cover/Material: '.$data['cover_material'];
}
if (! empty($data['other_type'])) {
$indicators[] = 'Specify Type: '.$data['other_type'];
}
if (! empty($data['pod_number'])) {
$indicators[] = 'POD Number: '.$data['pod_number'];
}
if (! empty($data['courier_name'])) {
$indicators[] = 'Courier Name: '.$data['courier_name'];
}
if (! empty($data['place'])) {
$indicators[] = 'Place: '.$data['place'];
}
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(),
])
->bulkActions([
Tables\Actions\BulkActionGroup::make([
Tables\Actions\DeleteBulkAction::make(),
Tables\Actions\ForceDeleteBulkAction::make(),
Tables\Actions\RestoreBulkAction::make(),
]),
])
->headerActions([
ImportAction::make()
->label('Import Courier Inward')
->color('warning')
->importer(CourierInwardImporter::class)
->visible(function () {
return Filament::auth()->user()->can('view import courier inward');
}),
ExportAction::make()
->label('Export Courier Inward')
->color('warning')
->exporter(CourierInwardExporter::class)
->visible(function () {
return Filament::auth()->user()->can('view export courier inward');
}),
]);
}
public static function getRelations(): array
{
return [
//
];
}
public static function getPages(): array
{
return [
'index' => Pages\ListCourierInwards::route('/'),
'create' => Pages\CreateCourierInward::route('/create'),
'view' => Pages\ViewCourierInward::route('/{record}'),
'edit' => Pages\EditCourierInward::route('/{record}/edit'),
];
}
public static function getEloquentQuery(): Builder
{
return parent::getEloquentQuery()
->withoutGlobalScopes([
SoftDeletingScope::class,
]);
}
}

View File

@@ -0,0 +1,12 @@
<?php
namespace App\Filament\Resources\CourierInwardResource\Pages;
use App\Filament\Resources\CourierInwardResource;
use Filament\Actions;
use Filament\Resources\Pages\CreateRecord;
class CreateCourierInward extends CreateRecord
{
protected static string $resource = CourierInwardResource::class;
}

View File

@@ -0,0 +1,22 @@
<?php
namespace App\Filament\Resources\CourierInwardResource\Pages;
use App\Filament\Resources\CourierInwardResource;
use Filament\Actions;
use Filament\Resources\Pages\EditRecord;
class EditCourierInward extends EditRecord
{
protected static string $resource = CourierInwardResource::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\CourierInwardResource\Pages;
use App\Filament\Resources\CourierInwardResource;
use Filament\Actions;
use Filament\Resources\Pages\ListRecords;
class ListCourierInwards extends ListRecords
{
protected static string $resource = CourierInwardResource::class;
protected function getHeaderActions(): array
{
return [
Actions\CreateAction::make(),
];
}
}

View File

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

View File

@@ -0,0 +1,243 @@
<?php
namespace App\Filament\Resources;
use App\Filament\Exports\CourierOutwardExporter;
use App\Filament\Imports\CourierOutwardImporter;
use App\Filament\Resources\CourierOutwardResource\Pages;
use App\Filament\Resources\CourierOutwardResource\RelationManagers;
use App\Models\CourierOutward;
use App\Models\Plant;
use Filament\Facades\Filament;
use Filament\Forms;
use Filament\Forms\Form;
use Filament\Resources\Resource;
use Filament\Tables;
use Filament\Tables\Table;
use Illuminate\Database\Eloquent\Builder;
use Illuminate\Database\Eloquent\SoftDeletingScope;
use Filament\Tables\Actions\ExportAction;
use Filament\Tables\Actions\ImportAction;
class CourierOutwardResource extends Resource
{
protected static ?string $model = CourierOutward::class;
protected static ?string $navigationIcon = 'heroicon-o-rectangle-stack';
protected static ?string $navigationGroup = 'Courier';
public static function form(Form $form): Form
{
return $form
->schema([
Forms\Components\Select::make('plant_id')
->label('Plant')
->relationship('plant', 'name')
->required()
->reactive()
->options(function (callable $get) {
$userHas = Filament::auth()->user()->plant_id;
return ($userHas && strlen($userHas) > 0) ? Plant::where('id', $userHas)->pluck('name', 'id')->toArray() : Plant::orderBy('code')->pluck('name', 'id')->toArray();
})
->afterStateUpdated(function ($state, callable $set, callable $get) {
$plantId = $get('plant_id');
if (! $plantId) {
$set('cPlantError', 'Please select a plant first.');
return;
} else {
$set('cPlantError', null);
}
})
->extraAttributes(fn ($get) => [
'class' => $get('cPlantError') ? 'border-red-500' : '',
])
->hint(fn ($get) => $get('cPlantError') ? $get('cPlantError') : null)
->hintColor('danger'),
Forms\Components\DatePicker::make('date')
->label('Choose Date')
->default(now())
->required(),
Forms\Components\TextInput::make('to_address')
->label('To Address')
->required(),
Forms\Components\Select::make('cover_material')
->label('Cover/Material')
->reactive()
->options([
'Cover' => 'Cover',
'Material' => 'Material',
'Gift Box 1No.' => 'Gift Box 1No.',
'Book' => 'Book',
'Others' => 'Others',
])
->dehydrateStateUsing(function ($state, callable $get) {
return $state == 'Others'
? $get('other_cover_material')
: $state;
}),
Forms\Components\TextInput::make('other_cover_material')
->label('Specify Other Cover/Material')
->reactive()
->visible(fn (callable $get) => $get('cover_material') == 'Others')
->required(fn (callable $get) => $get('cover_material') == 'Others')
->dehydrated(false),
Forms\Components\TextInput::make('name_of_sender')
->label('Name Of Sender')
->required(),
Forms\Components\TextInput::make('place_pincode')
->label('Which Place & PinCode')
->required(),
Forms\Components\TextInput::make('pod_number')
->label('POD Number')
->required(),
Forms\Components\TextInput::make('remark')
->label('Remark'),
Forms\Components\Hidden::make('created_by')
->label('Created By')
->default(Filament::auth()->user()?->name),
Forms\Components\Hidden::make('updated_by')
->label('Updated By')
->default(Filament::auth()->user()?->name),
]);
}
public static function table(Table $table): Table
{
return $table
->columns([
Tables\Columns\TextColumn::make('No.')
->label('No.')
->getStateUsing(function ($record, $livewire, $column, $rowLoop) {
$paginator = $livewire->getTableRecords();
$perPage = method_exists($paginator, 'perPage') ? $paginator->perPage() : 10;
$currentPage = method_exists($paginator, 'currentPage') ? $paginator->currentPage() : 1;
return ($currentPage - 1) * $perPage + $rowLoop->iteration;
}),
Tables\Columns\TextColumn::make('plant.name')
->label('Plant')
->alignCenter()
->searchable()
->sortable(),
Tables\Columns\TextColumn::make('date')
->label('Date')
->alignCenter()
->searchable()
->date()
->sortable(),
Tables\Columns\TextColumn::make('to_address')
->label('To Address')
->alignCenter()
->searchable()
->sortable(),
Tables\Columns\TextColumn::make('cover_material')
->label('Cover/Material')
->alignCenter()
->searchable()
->sortable(),
Tables\Columns\TextColumn::make('name_of_sender')
->label('Name Of Sender')
->alignCenter()
->searchable()
->sortable(),
Tables\Columns\TextColumn::make('place_pincode')
->label('Which Place Of PinCode')
->alignCenter()
->searchable()
->sortable(),
Tables\Columns\TextColumn::make('pod_number')
->label('POD Number')
->alignCenter()
->searchable()
->sortable(),
Tables\Columns\TextColumn::make('remark')
->label('Remark')
->alignCenter()
->searchable()
->sortable(),
Tables\Columns\TextColumn::make('created_at')
->label('Created At')
->dateTime()
->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')
->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')
->dateTime()
->sortable()
->toggleable(isToggledHiddenByDefault: true),
])
->filters([
Tables\Filters\TrashedFilter::make(),
])
->actions([
Tables\Actions\ViewAction::make(),
Tables\Actions\EditAction::make(),
])
->bulkActions([
Tables\Actions\BulkActionGroup::make([
Tables\Actions\DeleteBulkAction::make(),
Tables\Actions\ForceDeleteBulkAction::make(),
Tables\Actions\RestoreBulkAction::make(),
]),
])
->headerActions([
ImportAction::make()
->label('Import Courier Outward')
->color('warning')
->importer(CourierOutwardImporter::class)
->visible(function () {
return Filament::auth()->user()->can('view import courier outward');
}),
ExportAction::make()
->label('Export Courier Outward')
->color('warning')
->exporter(CourierOutwardExporter::class)
->visible(function () {
return Filament::auth()->user()->can('view export courier outward');
}),
]);
}
public static function getRelations(): array
{
return [
//
];
}
public static function getPages(): array
{
return [
'index' => Pages\ListCourierOutwards::route('/'),
'create' => Pages\CreateCourierOutward::route('/create'),
'view' => Pages\ViewCourierOutward::route('/{record}'),
'edit' => Pages\EditCourierOutward::route('/{record}/edit'),
];
}
public static function getEloquentQuery(): Builder
{
return parent::getEloquentQuery()
->withoutGlobalScopes([
SoftDeletingScope::class,
]);
}
}

View File

@@ -0,0 +1,12 @@
<?php
namespace App\Filament\Resources\CourierOutwardResource\Pages;
use App\Filament\Resources\CourierOutwardResource;
use Filament\Actions;
use Filament\Resources\Pages\CreateRecord;
class CreateCourierOutward extends CreateRecord
{
protected static string $resource = CourierOutwardResource::class;
}

View File

@@ -0,0 +1,22 @@
<?php
namespace App\Filament\Resources\CourierOutwardResource\Pages;
use App\Filament\Resources\CourierOutwardResource;
use Filament\Actions;
use Filament\Resources\Pages\EditRecord;
class EditCourierOutward extends EditRecord
{
protected static string $resource = CourierOutwardResource::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\CourierOutwardResource\Pages;
use App\Filament\Resources\CourierOutwardResource;
use Filament\Actions;
use Filament\Resources\Pages\ListRecords;
class ListCourierOutwards extends ListRecords
{
protected static string $resource = CourierOutwardResource::class;
protected function getHeaderActions(): array
{
return [
Actions\CreateAction::make(),
];
}
}

View File

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

View File

@@ -71,7 +71,12 @@ class GrMasterResource extends Resource
Forms\Components\TextInput::make('gr_number')
->label('GR Number')
->minLength(7)
->required(),
->required()
->rule(function (Get $get) {
return Rule::unique('gr_masters', 'gr_number')
->where('plant_id', $get('plant_id'))
->ignore($get('id'));
}),
Forms\Components\TextInput::make('serial_number')
->label('Serial Number')
->rule(function (callable $get) {

View File

@@ -1270,6 +1270,15 @@ class InvoiceValidationResource extends Resource
TextInput::make('serial_number')
->label('Serial Number')
->placeholder(placeholder: 'Enter Serial Number'),
TextInput::make('panel_box_serial_number')
->label('Panel Box Serial Number')
->placeholder(placeholder: 'Enter Panel Box Serial Number'),
TextInput::make('panel_box_supplier')
->label('Panel Box Supplier')
->placeholder(placeholder: 'Enter Panel Box Supplier'),
TextInput::make('panel_box_code')
->label('Panel Box Code')
->placeholder(placeholder: 'Enter Panel Box Code'),
Select::make('sticker_master_id')
->label('Search by Item Code')
->nullable()
@@ -1278,15 +1287,16 @@ class InvoiceValidationResource extends Resource
->options(function (callable $get) {
$pId = $get('Plant');
// if (empty($pId)) {
// return [];
// }
return Item::whereHas('stickerMasters', function ($query) use ($pId) {
if ($pId) {
$query->where('plant_id', $pId);
}
$query->whereHas('invoiceValidations');
})->pluck('code', 'id');
if (! $pId) {
return [];
} else {
return Item::whereHas('stickerMasters', function ($query) use ($pId) {
if ($pId) {
$query->where('plant_id', $pId);
}
$query->whereHas('invoiceValidations');
})->pluck('code', 'id');
}
}),
Select::make('scanned_status')
->label('Scanned Status')
@@ -1323,7 +1333,7 @@ class InvoiceValidationResource extends Resource
])
->query(function ($query, array $data) {
// Hide all records initially if no filters are applied
if (empty($data['invoice_type']) || (empty($data['Plant']) && empty($data['invoice_number']) && empty($data['serial_number']) && empty($data['created_from']) && empty($data['created_to']) && empty($data['operator_id']) && empty($data['scanned_status']) && empty($data['sticker_master_id']))) {
if (empty($data['invoice_type']) || (empty($data['Plant']) && empty($data['invoice_number']) && empty($data['serial_number']) && empty($data['panel_box_serial_number']) && empty($data['panel_box_supplier']) && empty($data['panel_box_code']) && empty($data['created_from']) && empty($data['created_to']) && empty($data['operator_id']) && empty($data['scanned_status']) && empty($data['sticker_master_id']))) {
if (empty($data['invoice_type'])) {
Notification::make()
->title('Please, choose invoice type to filter.')
@@ -1381,6 +1391,18 @@ class InvoiceValidationResource extends Resource
$query->where('serial_number', 'like', '%'.$data['serial_number'].'%');
}
if (! empty($data['panel_box_serial_number'])) {
$query->where('panel_box_serial_number', 'like', '%'.$data['panel_box_serial_number'].'%');
}
if (! empty($data['panel_box_supplier'])) {
$query->where('panel_box_supplier', 'like', '%'.$data['panel_box_supplier'].'%');
}
if (! empty($data['panel_box_code'])) {
$query->where('panel_box_code', 'like', '%'.$data['panel_box_code'].'%');
}
if (! empty($data['created_from'])) {
$query->where('created_at', '>=', $data['created_from']);
}
@@ -1393,8 +1415,9 @@ class InvoiceValidationResource extends Resource
$query->where('operator_id', $data['operator_id']);
}
if (! empty($data['sticker_master_id'])) {
if (! empty($data['sticker_master_id']) && ! empty($data['Plant'])) {
$stickerMasterIds = StickerMaster::where('item_id', $data['sticker_master_id'])
->where('plant_id', $data['Plant'])
->pluck('id')
->toArray();
@@ -1424,7 +1447,19 @@ class InvoiceValidationResource extends Resource
$indicators[] = 'Serial Number: '.$data['serial_number'];
}
if (! empty($data['sticker_master_id'])) {
if (! empty($data['panel_box_serial_number'])) {
$indicators[] = 'Panel Box Serial Number: '.$data['panel_box_serial_number'];
}
if (! empty($data['panel_box_supplier'])) {
$indicators[] = 'Panel Box Supplier: '.$data['panel_box_supplier'];
}
if (! empty($data['panel_box_code'])) {
$indicators[] = 'Panel Box Code: '.$data['panel_box_code'];
}
if (! empty($data['sticker_master_id']) && ! empty($data['Plant'])) {
$itemCode = Item::find($data['sticker_master_id'])->code ?? 'Unknown';
$indicators[] = 'Item Code: '.$itemCode;
}

View File

@@ -4030,7 +4030,136 @@ class CreateInvoiceValidation extends CreateRecord
// TN01/BOX22/SERIAL999 >> PANEL BOX QR
// /^([a-zA-Z0-9]{6,})\|([1-9][a-zA-Z0-9]{8,})(?:\/[MmPpCc])?\|?$/
if (! preg_match('/^([a-zA-Z0-9]{6,})\|([1-9][a-zA-Z0-9]{8,})(?:\/[MmPpCc])?\|?$/', $serNo, $matches)) {
if (preg_match('/^(\d+)\/(\d+)\/(\d+)\/(\d+)$/', $serNo, $matches)) {
$itemCode = $matches[2];
$serialNumber = $matches[1] . $matches[3] . $matches[4];
$supplierNo = $matches[1];
$supplierSNo = implode('/', array_slice($matches, 3));
$panelBoxCode = $matches[2];
$record = InvoiceValidation::where('serial_number', $serialNumber)->where('plant_id', $plantId)->first();
if (! $record) {
Notification::make()
->title('<b><span style="color:red;">Serial Number Not Found<br>Serial \''.$serialNumber.'\' not found in database for choosed plant.</span></b>')
// ->body("Serial '$serialNumber' not found in database for choosed plant.")..........
->danger()
->seconds(3)
->send();
$this->dispatch('play-warn-sound');
$this->form->fill([
'plant_id' => $plantId,
'invoice_number' => $invoiceNumber,
'serial_number' => null,
'total_quantity' => $totQuan,
'update_invoice' => false,
'scanned_quantity' => $scanSQuan,
]);
return;
}
$record1 = InvoiceValidation::where('serial_number', $serialNumber)
->where('plant_id', $plantId)
->whereHas('stickerMasterRelation.item', function ($query) use ($itemCode) {
$query->where('plant_id', $this->plantId)->where('code', $itemCode);
})
->first();
if (! $record1) {
Notification::make()
->title('Unknown: Item Code')
->body("Item code '$itemCode' with serial number '$serialNumber' not found.")
->danger()
->seconds(3)
->send();
$this->dispatch('playWarnSound');
$this->form->fill([
'plant_id' => $plantId,
'invoice_number' => $invoiceNumber,
'serial_number' => null,
'total_quantity' => $totQuan,
'update_invoice' => false,
'scanned_quantity' => $scanSQuan,
]);
return;
}
$invoiceUpdate = InvoiceValidation::where('plant_id', $plantId)
->where('invoice_number', $invoiceNumber)
->where('sticker_master_id', $record1->sticker_master_id)
->where('serial_number', $serialNumber)
->update([
'scanned_status' => 'Scanned',
'panel_box_supplier' => $supplierNo,
'panel_box_serial_number' => $supplierSNo,
'panel_box_code' => $panelBoxCode,
]);
$scannedQuantity = InvoiceValidation::where('invoice_number', $invoiceNumber)->where('scanned_status', 'Scanned')->where('plant_id', $plantId)->count();
if($totQuan == $scannedQuantity){
Notification::make()
->title('Completed: Panel Box Invoice')
->body("Panel Box invoice '$invoiceNumber' completed the scanning process.<br>Scan the next 'Panel Box Invoice' to proceed!")
->warning()
->seconds(3)
->send();
$this->dispatch('playNotificationSound');
$filename = $invoiceNumber.'.xlsx';
$directory = "uploads/temp/{$plantCode}";
$disk = Storage::disk('local');
$filePath = $directory.'/'.$filename;
// $fullPath = null;
if ($disk->exists($filePath)) {
// $fullPath = $disk->path($filePath);
$disk->delete($filePath);
}
$this->form->fill([
'plant_id' => $plantId,
'invoice_number' => null,
'serial_number' => null,
'total_quantity' => 0,
'update_invoice' => false,
'scanned_quantity' => 0,
]);
$this->dispatch('refreshCompletedInvoice', invoiceNumber: $invoiceNumber, plantId: $plantId, isSerial: true);
return;
}
if($invoiceUpdate){
Notification::make()
->title("Panel Box Success")
->body("Panel Box Serial '$serialNumber' updated successfully.")
->success()
->seconds(3)
->send();
$this->form->fill([
'plant_id' => $plantId,
'invoice_number' => $invoiceNumber,
'serial_number' => null,
'total_quantity' => $totQuan,
'update_invoice' => false,
'scanned_quantity' => $scannedQuantity,
]);
return;
}
}
else if (! preg_match('/^([a-zA-Z0-9]{6,})\|([1-9][a-zA-Z0-9]{8,})(?:\/[MmPpCc])?\|?$/', $serNo, $matches)) {
Notification::make()
->danger()
->title('Invalid Serial QR Format')

View File

@@ -338,12 +338,15 @@ class ItemResource extends Resource
->reactive(),
TextInput::make('description')
->label('Search by Description')
->reactive()
->placeholder(placeholder: 'Enter Description'),
TextInput::make('category')
->label('Search by Category')
->reactive()
->placeholder(placeholder: 'Enter Category'),
TextInput::make('uom')
->label('Search by UOM')
->reactive()
->placeholder(placeholder: 'Enter UOM'),
DateTimePicker::make(name: 'created_from')
->label('Created From')
@@ -387,27 +390,15 @@ class ItemResource extends Resource
}
if (! empty($data['description'])) {
$query->where('description', '%'.$data['description'].'%');
$query->where('description', 'like', '%'.$data['description'].'%');
}
if (! empty($data['uom'])) {
if ($data['uom'] == 'empty') {
$query->where(function ($q) {
$q->where('uom', '')->orWhereNull('uom');
});
} else {
$query->where('uom', 'like', '%'.$data['uom'].'%');
}
$query->where('uom', 'like', '%'.$data['uom'].'%');
}
if (! empty($data['category'])) {
if ($data['category'] == 'empty') {
$query->where(function ($q) {
$q->where('category', '')->orWhereNull('category');
});
} else {
$query->where('category', '%'.$data['category'].'%');
}
$query->where('category', 'like', '%'.$data['category'].'%');
}
if (! empty($data['created_from'])) {

View File

@@ -14,6 +14,8 @@ use Filament\Forms\Components\Select;
use Filament\Forms\Components\TextInput;
use Filament\Forms\Form;
use Filament\Forms\Get;
use Filament\Forms\Set;
use Filament\Notifications\Notification;
use Filament\Resources\Resource;
use Filament\Tables;
use Filament\Tables\Actions\ExportAction;
@@ -76,37 +78,58 @@ class LeakTestReadingResource extends Resource
->hintColor('danger'),
Forms\Components\TextInput::make('item_code')
->required()
->label('Item Code')
->placeholder('Scan the valid item code')
->label('Scan QR Code')
->placeholder('Scan the valid QR Code')
->autofocus(true)
->alphaNum()
->minLength(6)
// ->alphaNum()
// ->minLength(6)
->reactive()
->disabled(fn (Get $get) => ! empty($get('id')) && ! Filament::auth()->user()->hasRole('Super Admin'))
->afterStateUpdated(function ($state, callable $set, callable $get) {
$code = $get('item_code');
$set('lsrCodeError', null);
if (! $code) {
$set('lsrCodeError', 'Scan the valid item code.');
->afterStateUpdated(function ($state, Set $set, Get $get, $livewire) {
if (blank($state)) {
$set('item_code', null);
$set('serial_number', null);
return;
}
$parts = explode('|', trim($state));
if (! preg_match('/^[^|]+\|[^|]+\|?$/', trim($state))) {
Notification::make()
->title('Invalid QR Format')
->body("Expected format: ItemCode|SerialNumber<br>Received Format '$state'")
->danger()
->send();
$set('item_code', null);
return;
} else {
if (strlen($code) < 6) {
$set('lsrCodeError', 'Item code must be at least 6 digits.');
$iCode = $parts[0];
if (strlen($parts[0]) < 6) {
return;
} elseif (! ctype_alnum($code)) {
Notification::make()
->title('Invalid Item Code')
->body("Item code '$iCode' should contain minimum 6 digits!")
->danger()
->send();
$set('item_code', null);
$set('lsrCodeError', 'Item code must contain only alpha-numeric characters!');
return;
} elseif (! preg_match('/^[a-zA-Z1-9][a-zA-Z0-9]{5,}$/', $code)) {
} elseif (! preg_match('/^[a-zA-Z0-9]+$/', $iCode)) {
Notification::make()
->title('Invalid Item Code')
->body("Item code '$iCode' should contain alpha numeric values!")
->danger()
->send();
$set('item_code', null);
$set('lsrCodeError', "Item code should not begin with '0' or letter!");
return;
} else {
$set('item_code', trim($parts[0]));
$set('serial_number', isset($parts[1]) ? trim($parts[1]) : null);
$livewire->dispatch('submit-leak-test-form');
}
$set('lsrCodeError', null);
}
})
->extraAttributes(fn ($get) => [
@@ -158,13 +181,14 @@ class LeakTestReadingResource extends Resource
->label('Test Status')
->searchable()
->reactive()
->default('P')
// ->disabled(fn (Get $get) => ! empty($get('id')))
->options(function (callable $set, callable $get) {
$plantId = $get('plant_id');
$itemCode = $get('item_code');
$serialNumber = $get('serial_number');
// $itemCode = $get('item_code');
// $serialNumber = $get('serial_number');
if (! $plantId || ! $itemCode || ! $serialNumber) {
if (! $plantId) { // || ! $itemCode || ! $serialNumber
$set('test_status', null);
return [];

View File

@@ -4,9 +4,55 @@ namespace App\Filament\Resources\LeakTestReadingResource\Pages;
use App\Filament\Resources\LeakTestReadingResource;
use Filament\Actions;
use Filament\Notifications\Notification;
use Filament\Resources\Pages\CreateRecord;
use Livewire\Attributes\On;
class CreateLeakTestReading extends CreateRecord
{
protected static string $resource = LeakTestReadingResource::class;
public function processQR($value){
$qrCode = $value;
$parts = explode('|', $qrCode);
$plantId = $this->form->getState()['plant_id'];
if (! preg_match('/^[^|]+(?:\|[^|]+)?$/', $value)) {
Notification::make()
->title('Invalid QR Format')
->body('Expected format: ItemCode|SerialNumber')
->danger()
->send();
return;
}
$itemCode = $parts[0] ?? null;
$serialNumber = $parts[1] ?? null;
$this->form->fill([
'plant_id' => $plantId,
'item_code' => $itemCode,
'serial_number' => $serialNumber,
'test_status' => 'PASS'
]);
}
#[On('submit-leak-test-form')]
public function submitLeakTestForm(): void
{
$this->create();
}
protected function getRedirectUrl(): string
{
//return $this->getResource()::getUrl('create'); // Stay on Create Page after savin
return $this->getResource()::getUrl('create', [
'plant_id' => $this->data['plant_id'] ?? null,
]);
}
}

View File

@@ -81,7 +81,7 @@ class MotorTestingMasterResource extends Resource
->hintColor('danger'),
Forms\Components\TimePicker::make('routine_test_time')
->label('Routine Test Time')
->default('00:40:00')
->default('00:30:00')
->columnSpan(1)
->required()
->afterStateUpdated(function (callable $set, callable $get, ?string $state) {

View File

@@ -19,6 +19,8 @@ use App\Models\Item;
use App\Models\Line;
use App\Models\Plant;
use App\Models\StickerMaster;
use App\Models\InvoiceValidation;
use App\Models\ProductionOrder;
use App\Models\PanelGrMaster;
use Filament\Notifications\Notification;
use Filament\Forms\Components\DateTimePicker;
@@ -210,8 +212,7 @@ class PanelBoxValidationResource extends Resource
'class' => $get('inspecOrdError') ? 'border-red-500' : '',
])
->hint(fn ($get) => $get('inspecOrdError') ? $get('inspecOrdError') : null)
->hintColor('danger')
->required(),
->hintColor('danger'),
Forms\Components\Hidden::make('inspection')
->default(fn () => session('last_selected_inspection'))
->afterStateHydrated(function ($state, $set) {
@@ -558,15 +559,15 @@ class PanelBoxValidationResource extends Resource
}
}
elseif (str_contains($state, '/'))
if (str_contains($state, '/'))
{
$parts = explode('/', $state);
if (count($parts) < 3) {
if (!preg_match('/^\d+\/\d+\/\d{4}\/\d+$/', $state) || preg_match('/[a-zA-Z]/', $state)) {
Notification::make()
->title('Invalid QR Format')
->body('Expected format: plantcode/itemcode/yearmm/serialnumber (Or) plantcode/panelboxcode/serialnumber')
->body("Expected format: plantcode/itemcode/yearmm/serialnumber Format Received : $state")
->danger()
->send();
$set('item_id', null);
@@ -581,10 +582,10 @@ class PanelBoxValidationResource extends Resource
$itemCode = $panelBoxCode;
$serialNumber = $panelBoxSerialNo;
if (strlen($serialNumber) > 30) {
if (strlen($serialNumber) > 15) {
Notification::make()
->title('Invalid Serial Number')
->body("Serial number cannot be greater than 30 characters. Current length: " . strlen($panelBoxSerialNo))
->body("Serial number cannot be greater than 15 characters. Current length: " . strlen($panelBoxSerialNo))
->danger()
->send();
@@ -596,122 +597,258 @@ class PanelBoxValidationResource extends Resource
$existInMasterPo = PanelGrMaster::where('document_number', $pOrder)->where('plant_id', $plantId)->first();
if(!$existInMasterPo){
Notification::make()
->title('Panel GR Record')
->body("Production Order (Or) Doc No'{$pOrder}' not found against plant code '{$plaCode}' in Panel Gr master.")
->danger()
->send();
$set('item_id', null);
$set('serial_exists', false);
return;
}
// if(!$existInMasterPo){
// Notification::make()
// ->title('Panel GR Record')
// ->body("Production Order (Or) Doc No'{$pOrder}' not found against plant code '{$plaCode}' in Panel Gr master.")
// ->danger()
// ->send();
// $set('item_id', null);
// $set('serial_exists', false);
// return;
// }
$iId = Item::where('code', $itemCode)->where('plant_id', $plantId)->first();
if($existInMasterPo){
if(!$iId){
Notification::make()
->title('Item not found')
->body("Item code'{$itemCode}' not found against plant code '{$plaCode}' in item master.")
->danger()
->send();
$set('item_id', null);
$set('serial_exists', false);
return;
}
$iId = Item::where('code', $itemCode)->where('plant_id', $plantId)->first();
$sticker = StickerMaster::where('plant_id', $plantId)->where('item_id', $iId->id)->first();
if(!$iId){
Notification::make()
->title('Item not found')
->body("Item code'{$itemCode}' not found against plant code '{$plaCode}' in item master.")
->danger()
->send();
$set('item_id', null);
$set('serial_exists', false);
return;
}
if(!$sticker){
Notification::make()
->title('Unknown Item Code')
->body("Item code not found '{$iId->code}' in sticker master.")
->danger()
->send();
$set('item_id', null);
$set('serial_exists', false);
return;
}
$sticker = StickerMaster::where('plant_id', $plantId)->where('item_id', $iId->id)->first();
$existInMaster = PanelGrMaster::where('document_number', $pOrder)->where('inspection_lot_number', $inspecLotNo)->where('item_id', $iId->id)->where('plant_id', $plantId)->first();
if(!$sticker){
Notification::make()
->title('Unknown Item Code')
->body("Item code not found '{$iId->code}' in sticker master.")
->danger()
->send();
$set('item_id', null);
$set('serial_exists', false);
return;
}
if(!$existInMaster){
Notification::make()
->title('Panel GR Record Not Found')
->body("No Panel GR record found for Production Order (Or) Doc No'{$pOrder}' , inspection lot number '{$inspecLotNo}' and for Item '{$itemCode}'.")
->danger()
->send();
$set('item_id', null);
$set('serial_exists', false);
return;
}
else if($existInMaster->supplier_number == '' || $existInMaster->supplier_number == null){
Notification::make()
->title('Panel GR Found')
->body("Supplier Number cannot be empty Panel GR record found for Production Order '{$pOrder}' and Item '{$itemCode}'.")
->danger()
->send();
$set('item_id', null);
$set('serial_exists', false);
return;
}
else if($existInMaster->supplier_number != $supplier){
Notification::make()
->title('Panel GR Found')
->body("Supplier code not match for Production Order (Or) Doc No'{$pOrder}' and Item '{$itemCode}'.")
->danger()
->send();
$set('item_id', null);
$set('serial_exists', false);
return;
}
else if($existInMaster->inspection_lot_number != $inspecLotNo){
Notification::make()
->title('Panel GR Found')
->body("Inspection Lot Number code not match for Production Order (Or) Doc No'{$pOrder}' and Item '{$itemCode}'.")
->danger()
->send();
$set('item_id', null);
$set('serial_exists', false);
return;
}
else if($existInMaster->quantity == '' || $existInMaster->quantity == null){
Notification::make()
->title('Panel GR Found')
->body("Quantity cannot be empty Panel GR record found for Production Order '{$pOrder}' and Item '{$itemCode}'.")
->danger()
->send();
$set('item_id', null);
$set('serial_exists', false);
return;
}
else if($existInMaster->invoice_number == '' || $existInMaster->invoice_number == null){
Notification::make()
->title('Panel GR Found')
->body("Invoice Number cannot be empty Panel GR record found for Production Order '{$pOrder}' and Item '{$itemCode}'.")
->danger()
->send();
$set('item_id', null);
$set('serial_exists', false);
return;
}
$panelExistsInvoice = InvoiceValidation::where('plant_id', $plantId)
->where('panel_box_serial_number', $serialNumber)
->where('panel_box_supplier', $supplier)
->first();
$existQuanInPanel = PanelBoxValidation::where('plant_id', $plantId)->where('production_order', $pOrder)->where('inspection_lot_number', $inspecLotNo)->where('sticker_master_id', $sticker->id)->count();
if ($panelExistsInvoice) {
Notification::make()
->title('Duplicate Panel Box Serial Number')
->body("Duplicate panel already exists.<br>Panel Box Code: $itemCode, Serial Number: $serialNumber, Supplier Number: $supplier against invoice Number: $panelExistsInvoice->invoice_number")
->danger()
->seconds(4)
->send();
if ($existQuanInPanel >= (int) $existInMaster->quantity) {
Notification::make()
->title('Quantity Completed')
->body("Panel box quantity '{$existQuanInPanel}' exceeds the available quantity '{$existInMaster->quantity}' in Panel GR Master for Production Order '{$pOrder}' and Item '{$itemCode}'.")
->danger()
->send();
$set('item_id', null);
$set('serial_exists', false);
return;
$set('item_id', null);
$set('serial_exists', false);
return;
}
$existInMaster = PanelGrMaster::where('document_number', $pOrder)->where('inspection_lot_number', $inspecLotNo)->where('item_id', $iId->id)->where('plant_id', $plantId)->first();
if(!$existInMaster){
Notification::make()
->title('Panel GR Record Not Found')
->body("No Panel GR record found for Production Order (Or) Doc No'{$pOrder}' , inspection lot number '{$inspecLotNo}' and for Item '{$itemCode}'.")
->danger()
->send();
$set('item_id', null);
$set('serial_exists', false);
return;
}
else if($existInMaster->supplier_number == '' || $existInMaster->supplier_number == null){
Notification::make()
->title('Panel GR Found')
->body("Supplier Number cannot be empty Panel GR record found for Production Order '{$pOrder}' and Item '{$itemCode}'.")
->danger()
->send();
$set('item_id', null);
$set('serial_exists', false);
return;
}
else if($existInMaster->supplier_number != $supplier){
Notification::make()
->title('Panel GR Found')
->body("Supplier code not match for Production Order (Or) Doc No'{$pOrder}' and Item '{$itemCode}'.")
->danger()
->send();
$set('item_id', null);
$set('serial_exists', false);
return;
}
else if($existInMaster->inspection_lot_number != $inspecLotNo){
Notification::make()
->title('Panel GR Found')
->body("Inspection Lot Number code not match for Production Order (Or) Doc No'{$pOrder}' and Item '{$itemCode}'.")
->danger()
->send();
$set('item_id', null);
$set('serial_exists', false);
return;
}
else if($existInMaster->quantity == '' || $existInMaster->quantity == null){
Notification::make()
->title('Panel GR Found')
->body("Quantity cannot be empty Panel GR record found for Production Order '{$pOrder}' and Item '{$itemCode}'.")
->danger()
->send();
$set('item_id', null);
$set('serial_exists', false);
return;
}
else if($existInMaster->invoice_number == '' || $existInMaster->invoice_number == null){
Notification::make()
->title('Panel GR Found')
->body("Invoice Number cannot be empty Panel GR record found for Production Order '{$pOrder}' and Item '{$itemCode}'.")
->danger()
->send();
$set('item_id', null);
$set('serial_exists', false);
return;
}
$existQuanInPanel = PanelBoxValidation::where('plant_id', $plantId)->where('production_order', $pOrder)->where('inspection_lot_number', $inspecLotNo)->where('sticker_master_id', $sticker->id)->count();
if ($existQuanInPanel >= (int) $existInMaster->quantity) {
Notification::make()
->title('Quantity Completed')
->body("Panel box quantity '{$existQuanInPanel}' exceeds the available quantity '{$existInMaster->quantity}' in Panel GR Master for Production Order '{$pOrder}' and Item '{$itemCode}'.")
->danger()
->send();
$set('item_id', null);
$set('serial_exists', false);
return;
}
$set('panel_box_supplier', $supplier);
$set('panel_box_serial_number', $panelBoxSerialNo);
$set('panel_box_code', $panelBoxCode);
}
else{
$existInMasterProdOrder = ProductionOrder::where('production_order', $pOrder)->where('plant_id', $plantId)->first();
$set('panel_box_supplier', $supplier);
$set('panel_box_serial_number', $panelBoxSerialNo);
$set('panel_box_code', $panelBoxCode);
if(!$existInMasterProdOrder && !$existInMasterPo){
Notification::make()
->title('Production Order Not Found')
->body("Production Order (Or) Doc No'{$pOrder}' not found against plant code '{$plaCode}' in both production order and Panel Gr master.")
->danger()
->send();
$set('item_id', null);
$set('serial_exists', false);
return;
}
$iId = Item::where('code', $itemCode)->where('plant_id', $plantId)->first();
if(!$iId){
Notification::make()
->title('Item not found')
->body("Item code'{$itemCode}' not found against plant code '{$plaCode}' in item master.")
->danger()
->send();
$set('item_id', null);
$set('serial_exists', false);
return;
}
$sticker = StickerMaster::where('plant_id', $plantId)->where('item_id', $iId->id)->first();
if(!$sticker){
Notification::make()
->title('Unknown Item Code')
->body("Item code not found '{$iId->code}' in sticker master.")
->danger()
->send();
$set('item_id', null);
$set('serial_exists', false);
return;
}
$panelExistsInvoice = InvoiceValidation::where('plant_id', $plantId)
->where('panel_box_serial_number', $serialNumber)
->where('panel_box_supplier', $supplier)
->first();
if ($panelExistsInvoice) {
Notification::make()
->title('Duplicate Panel Box Serial Number')
->body("Duplicate panel already exists.<br>Panel Box Code: $itemCode, Serial Number: $serialNumber, Supplier Number: $supplier against invoice Number: $panelExistsInvoice->invoice_number")
->danger()
->seconds(4)
->send();
$set('item_id', null);
$set('serial_exists', false);
return;
}
$plantCode = Plant::where('id', $plantId)->value('code');
if($plantCode != $supplier){
Notification::make()
->title('Supplier Mismatch')
->body("Supplier code '$supplier' mismatch with selected plant code '$plantCode'.")
->danger()
->send();
$set('item_id', null);
$set('serial_exists', false);
return;
}
if($existInMasterProdOrder->item_id != $iId){
$itemCodePOrd = Item::where('id', $existInMasterProdOrder->item_id)->value('code');
Notification::make()
->title('Panel Box Code Mismatch')
->body("Scanned Panel Box Code '$itemCode' not matched with produciton order item code '$itemCodePOrd'.")
->danger()
->send();
$set('item_id', null);
$set('serial_exists', false);
return;
}
if($existInMasterProdOrder->quantity == '' || $existInMasterProdOrder->quantity == null){
Notification::make()
->title('Production Order Found')
->body("Quantity cannot be empty in production order '{$pOrder}' and Item '{$itemCode}'.")
->danger()
->send();
$set('item_id', null);
$set('serial_exists', false);
return;
}
$existQuanInPanel = PanelBoxValidation::where('plant_id', $plantId)->where('production_order', $pOrder)->where('sticker_master_id', $sticker->id)->count();
if ($existQuanInPanel >= (int) $existInMasterProdOrder->quantity) {
Notification::make()
->title('Quantity Completed')
->body("Panel box quantity '{$existQuanInPanel}' exceeds the available quantity '{$existInMasterProdOrder->quantity}' for Production Order '{$pOrder}' and Item '{$itemCode}' in production order table.")
->danger()
->send();
$set('item_id', null);
$set('serial_exists', false);
return;
}
$set('panel_box_supplier', $supplier);
$set('panel_box_serial_number', $panelBoxSerialNo);
$set('panel_box_code', $panelBoxCode);
}
}
else {
@@ -825,7 +962,7 @@ class PanelBoxValidationResource extends Resource
}
}
$serialExists = PanelBoxValidation::where('serial_number', $serialNumber)->where('plant_id', $plantId)->where('panel_box_supplier', $supplier)->first();
$serialExists = PanelBoxValidation::where('serial_number', $serialNumber)->where('plant_id', $plantId)->where('panel_box_supplier', $supplier)->where('status', '!=', '')->whereNotNull('status')->where('status', 'NotOk')->first();
if ($serialExists) {
$set('serial_exists', true);
@@ -833,6 +970,20 @@ class PanelBoxValidationResource extends Resource
$set('serial_exists', false);
}
$serialExistsPanel = PanelBoxValidation::where('serial_number', $serialNumber)->where('plant_id', $plantId)->where('panel_box_supplier', $supplier)->where('status', '!=', '')->whereNotNull('status')->where('status', 'Ok')->first();
if($serialExistsPanel){
Notification::make()
->title('Panel Box Already Validated')
->body("Serial number '$serialNumber' for supplier '$supplier' has already been tested and marked as 'OK'")
->success()
->send();
$set('item_id', null);
$set('serial_exists', false);
$set('validationError', null);
return;
}
// if ($serialExists && ! $get('id')) {
// $set('validationError', 'Serial number already exists in panel box validation.');
// $set('sticker_master_id', null);

View File

@@ -18,6 +18,8 @@ class EditPanelGrMaster extends EditRecord
{
$record = $this->record;
$scannedQuantity = 0;
$sticker = StickerMaster::where('plant_id', $record->plant_id)->where('item_id', $record->item_id)->first();
if($sticker)

View File

@@ -185,15 +185,13 @@ class PlantResource extends Resource
->hint(fn ($get) => $get('pAddressError') ? $get('pAddressError') : null)
->hintColor('danger'),
Forms\Components\Textarea::make('reg_address')
->required()
->label('Reg Address')
->label('Regd Address')
->placeholder('Scan the valid Regd address')
->unique(ignoreRecord: true)
->columnSpanFull()
->reactive()
->minLength(5)
->afterStateUpdated(function ($state, callable $set, callable $get) {
$nameId = $get('address');
$nameId = $get('reg_address');
// Ensure `linestop_id` is not cleared
if (! $nameId) {
$set('pRegAddressError', 'Scan the valid reg address.');
@@ -208,6 +206,50 @@ class PlantResource extends Resource
])
->hint(fn ($get) => $get('pRegAddressError') ? $get('pRegAddressError') : null)
->hintColor('danger'),
Forms\Components\Textarea::make('feed_address')
->label('Feed Address')
->placeholder('Scan the valid Feed address')
->columnSpanFull()
->reactive()
->minLength(5)
->afterStateUpdated(function ($state, callable $set, callable $get) {
$nameId = $get('feed_address');
// Ensure `linestop_id` is not cleared
if (! $nameId) {
$set('pFeedAddressError', 'Scan the valid feed back address.');
return;
} else {
$set('pFeedAddressError', null);
}
})
->extraAttributes(fn ($get) => [
'class' => $get('pFeedAddressError') ? 'border-red-500' : '',
])
->hint(fn ($get) => $get('pFeedAddressError') ? $get('pRegAddressError') : null)
->hintColor('danger'),
Forms\Components\Textarea::make('tollfree')
->label('Tollfree')
->placeholder('Scan the valid Tollfree')
->columnSpanFull()
->reactive()
->minLength(5)
->afterStateUpdated(function ($state, callable $set, callable $get) {
$nameId = $get('tollfree');
// Ensure `linestop_id` is not cleared
if (! $nameId) {
$set('pTollfreeError', 'Scan the valid tollfree.');
return;
} else {
$set('pTollfreeError', null);
}
})
->extraAttributes(fn ($get) => [
'class' => $get('pTollfreeError') ? 'border-red-500' : '',
])
->hint(fn ($get) => $get('pTollfreeError') ? $get('pTollfreeError') : null)
->hintColor('danger'),
Forms\Components\TextInput::make('id')
->hidden()
->readOnly(),
@@ -262,6 +304,16 @@ class PlantResource extends Resource
->alignCenter()
->sortable()
->searchable(),
Tables\Columns\TextColumn::make('feed_address')
->label('FeedBack')
->alignCenter()
->sortable()
->searchable(),
Tables\Columns\TextColumn::make('tollfree')
->label('Tollfree')
->alignCenter()
->sortable()
->searchable(),
Tables\Columns\TextColumn::make('company.name')
->label('Company')
->alignCenter()

View File

@@ -0,0 +1,131 @@
<?php
namespace App\Filament\Resources;
use App\Filament\Resources\ProductionCalendarResource\Pages;
use App\Filament\Resources\ProductionCalendarResource\RelationManagers;
use App\Models\Plant;
use App\Models\ProductionCalendar;
use Filament\Facades\Filament;
use Filament\Forms;
use Filament\Forms\Form;
use Filament\Resources\Resource;
use Filament\Tables;
use Filament\Tables\Table;
use Illuminate\Database\Eloquent\Builder;
use Illuminate\Database\Eloquent\SoftDeletingScope;
class ProductionCalendarResource extends Resource
{
protected static ?string $model = ProductionCalendar::class;
protected static ?string $navigationIcon = 'heroicon-o-rectangle-stack';
protected static ?string $navigationGroup = 'Production Report';
public static function form(Form $form): Form
{
return $form
->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::orderBy('code')->pluck('name', 'id')->toArray();
})
->required(),
Forms\Components\TextInput::make('working_days')
->label('Working Days'),
Forms\Components\TextInput::make('leave_dates')
->label('Leave Dates'),
Forms\Components\Hidden::make('created_by')
->label('Created By')
->default(Filament::auth()->user()?->name),
Forms\Components\Hidden::make('updated_by')
->label('Updated By')
->default(Filament::auth()->user()?->name),
]);
}
public static function table(Table $table): Table
{
return $table
->columns([
Tables\Columns\TextColumn::make('No.')
->label('No.')
->getStateUsing(function ($record, $livewire, $column, $rowLoop) {
$paginator = $livewire->getTableRecords();
$perPage = method_exists($paginator, 'perPage') ? $paginator->perPage() : 10;
$currentPage = method_exists($paginator, 'currentPage') ? $paginator->currentPage() : 1;
return ($currentPage - 1) * $perPage + $rowLoop->iteration;
}),
Tables\Columns\TextColumn::make('plant.name')
->label('Plant')
->alignCenter()
->sortable(),
Tables\Columns\TextColumn::make('working_days')
->label('Working Days')
->alignCenter()
->sortable(),
Tables\Columns\TextColumn::make('leave_dates')
->label('Leave Dates')
->alignCenter()
->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(),
]),
]);
}
public static function getRelations(): array
{
return [
//
];
}
public static function getPages(): array
{
return [
'index' => Pages\ListProductionCalendars::route('/'),
'create' => Pages\CreateProductionCalendar::route('/create'),
'view' => Pages\ViewProductionCalendar::route('/{record}'),
'edit' => Pages\EditProductionCalendar::route('/{record}/edit'),
];
}
public static function getEloquentQuery(): Builder
{
return parent::getEloquentQuery()
->withoutGlobalScopes([
SoftDeletingScope::class,
]);
}
}

View File

@@ -0,0 +1,12 @@
<?php
namespace App\Filament\Resources\ProductionCalendarResource\Pages;
use App\Filament\Resources\ProductionCalendarResource;
use Filament\Actions;
use Filament\Resources\Pages\CreateRecord;
class CreateProductionCalendar extends CreateRecord
{
protected static string $resource = ProductionCalendarResource::class;
}

View File

@@ -0,0 +1,22 @@
<?php
namespace App\Filament\Resources\ProductionCalendarResource\Pages;
use App\Filament\Resources\ProductionCalendarResource;
use Filament\Actions;
use Filament\Resources\Pages\EditRecord;
class EditProductionCalendar extends EditRecord
{
protected static string $resource = ProductionCalendarResource::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\ProductionCalendarResource\Pages;
use App\Filament\Resources\ProductionCalendarResource;
use Filament\Actions;
use Filament\Resources\Pages\ListRecords;
class ListProductionCalendars extends ListRecords
{
protected static string $resource = ProductionCalendarResource::class;
protected function getHeaderActions(): array
{
return [
Actions\CreateAction::make(),
];
}
}

View File

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

View File

@@ -478,7 +478,161 @@ class ProductionPlanResource extends Resource
// ->label('Shift')
// ->alignCenter()
// ->sortable(), // ->searchable(),
Tables\Columns\TextColumn::make('day_1')
->label('Day 1')
->alignCenter()
->sortable()
->searchable(),
Tables\Columns\TextColumn::make('day_2')
->label('Day 2')
->alignCenter()
->sortable()
->searchable(),
Tables\Columns\TextColumn::make('day_3')
->label('Day 3')
->alignCenter()
->sortable()
->searchable(),
Tables\Columns\TextColumn::make('day_4')
->label('Day 4')
->alignCenter()
->sortable()
->searchable(),
Tables\Columns\TextColumn::make('day_5')
->label('Day 5')
->alignCenter()
->sortable()
->searchable(),
Tables\Columns\TextColumn::make('day_6')
->label('Day 6')
->alignCenter()
->sortable()
->searchable(),
Tables\Columns\TextColumn::make('day_7')
->label('Day 7')
->alignCenter()
->sortable()
->searchable(),
Tables\Columns\TextColumn::make('day_8')
->label('Day 8')
->alignCenter()
->sortable()
->searchable(),
Tables\Columns\TextColumn::make('day_9')
->label('Day 9')
->alignCenter()
->sortable()
->searchable(),
Tables\Columns\TextColumn::make('day_10')
->label('Day 10')
->alignCenter()
->sortable()
->searchable(),
Tables\Columns\TextColumn::make('day_11')
->label('Day 11')
->alignCenter()
->sortable()
->searchable(),
Tables\Columns\TextColumn::make('day_12')
->label('Day 12')
->alignCenter()
->sortable()
->searchable(),
Tables\Columns\TextColumn::make('day_13')
->label('Day 13')
->alignCenter()
->sortable()
->searchable(),
Tables\Columns\TextColumn::make('day_14')
->label('Day 14')
->alignCenter()
->sortable()
->searchable(),
Tables\Columns\TextColumn::make('day_15')
->label('Day 15')
->alignCenter()
->sortable()
->searchable(),
Tables\Columns\TextColumn::make('day_16')
->label('Day 16')
->alignCenter()
->sortable()
->searchable(),
Tables\Columns\TextColumn::make('day_17')
->label('Day 17')
->alignCenter()
->sortable()
->searchable(),
Tables\Columns\TextColumn::make('day_18')
->label('Day 18')
->alignCenter()
->sortable()
->searchable(),
Tables\Columns\TextColumn::make('day_19')
->label('Day 19')
->alignCenter()
->sortable()
->searchable(),
Tables\Columns\TextColumn::make('day_20')
->label('Day 20')
->alignCenter()
->sortable()
->searchable(),
Tables\Columns\TextColumn::make('day_21')
->label('Day 21')
->alignCenter()
->sortable()
->searchable(),
Tables\Columns\TextColumn::make('day_22')
->label('Day 22')
->alignCenter()
->sortable()
->searchable(),
Tables\Columns\TextColumn::make('day_23')
->label('Day 23')
->alignCenter()
->sortable()
->searchable(),
Tables\Columns\TextColumn::make('day_24')
->label('Day 24')
->alignCenter()
->sortable()
->searchable(),
Tables\Columns\TextColumn::make('day_25')
->label('Day 25')
->alignCenter()
->sortable()
->searchable(),
Tables\Columns\TextColumn::make('day_26')
->label('Day 26')
->alignCenter()
->sortable()
->searchable(),
Tables\Columns\TextColumn::make('day_27')
->label('Day 27')
->alignCenter()
->sortable()
->searchable(),
Tables\Columns\TextColumn::make('day_28')
->label('Day 28')
->alignCenter()
->sortable()
->searchable(),
Tables\Columns\TextColumn::make('day_29')
->label('Day 29')
->alignCenter()
->sortable()
->searchable(),
Tables\Columns\TextColumn::make('day_30')
->label('Day 30')
->alignCenter()
->sortable()
->searchable(),
Tables\Columns\TextColumn::make('day_31')
->label('Day 31')
->alignCenter()
->sortable()
->searchable(),
Tables\Columns\TextColumn::make('created_at')
->label('Created At')
->dateTime()

View File

@@ -116,6 +116,11 @@ class StickerDetailResource extends Resource
->prepend('Serial Number', 'serial_number')
->prepend('Plant Name', 'plant_name')
->prepend('Plant Address', 'plant_address')
->prepend('Regd Address', 'regd_address')
->prepend('Regd Unit', 'regd_unit')
->prepend('Feed Address', 'feed_address')
->prepend('Tollfree', 'tollfree')
->prepend('Company Name', 'company_name')
->prepend('Current Date', 'current_date')
->prepend('Tested By', 'tested_by')
->prepend('Verified By', 'verified_by')

View File

@@ -89,7 +89,26 @@ class StickerMappingMasterResource extends Resource
})
->searchable()
->required(),
->required()
->rules([
function (callable $get, $record) {
return function (string $attribute, $value, $fail) use ($get, $record) {
$plantId = $get('plant_id');
$query = StickerMappingMaster::where('plant_id', $plantId)
->where('item_id', $value);
// Ignore the current record when editing
if ($record) {
$query->where('id', '!=', $record->id);
}
if ($query->exists()) {
$fail('Item Code already exist to the selected plant.');
}
};
},
]),
])
->columns(2),

View File

@@ -1889,8 +1889,11 @@ class TempClassCharacteristicResource extends Resource
->minlength(7)
->maxlength(10),
TextInput::make('gernr')
->label('Serial Number')
->placeholder('Enter Serial Number'),
->label('FG Serial Number')
->placeholder('Enter FG Serial Number'),
TextInput::make('winded_serial_number')
->label('Winded Serial Number')
->placeholder('Enter Winded Serial Number'),
TextInput::make('zmm_heading')
->label('Heading')
->placeholder('Enter Heading'),
@@ -1918,7 +1921,7 @@ class TempClassCharacteristicResource extends Resource
])
->query(function ($query, array $data) {
// Hide all records initially if no filters are applied
if (empty($data['Plant']) && empty($data['machine']) && empty($data['item_id']) && empty($data['aufnr']) && empty($data['gernr']) && empty($data['zmm_heading']) && empty($data['model_type']) && empty($data['created_from']) && empty($data['created_to'])) {
if (empty($data['Plant']) && empty($data['machine']) && empty($data['item_id']) && empty($data['aufnr']) && empty($data['gernr']) && empty($data['winded_serial_number']) && empty($data['zmm_heading']) && empty($data['model_type']) && empty($data['created_from']) && empty($data['created_to'])) {
return $query->whereRaw('1 = 0');
}
@@ -1948,6 +1951,10 @@ class TempClassCharacteristicResource extends Resource
$query->where('gernr', 'like', '%'.$data['gernr'].'%');
}
if (! empty($data['winded_serial_number'])) {
$query->where('winded_serial_number', 'like', '%'.$data['winded_serial_number'].'%');
}
if (! empty($data['zmm_heading'])) {
$query->where('zmm_heading', 'like', '%'.$data['zmm_heading'].'%');
}
@@ -1994,7 +2001,11 @@ class TempClassCharacteristicResource extends Resource
}
if (! empty($data['gernr'])) {
$indicators[] = 'Serial Number: '.$data['gernr'];
$indicators[] = 'FG Serial Number: '.$data['gernr'];
}
if (! empty($data['winded_serial_number'])) {
$indicators[] = 'Winded Serial Number: '.$data['winded_serial_number'];
}
if (! empty($data['zmm_heading'])) {

View File

@@ -0,0 +1,794 @@
<?php
namespace App\Filament\Resources;
use App\Filament\Exports\TestingLineVisualizationExporter;
use App\Filament\Imports\TestingLineVisualizationImporter;
use App\Filament\Resources\TestingLineVisualizationResource\Pages;
use App\Models\Configuration;
use App\Models\Plant;
use App\Models\TestingLineVisualization;
use Filament\Facades\Filament;
use Filament\Forms;
use Filament\Forms\Components\DateTimePicker;
use Filament\Forms\Components\Section;
use Filament\Forms\Components\Select;
use Filament\Forms\Components\TextInput;
use Filament\Forms\Form;
use Filament\Forms\Get;
use Filament\Resources\Resource;
use Filament\Tables;
use Filament\Tables\Actions\ExportAction;
use Filament\Tables\Actions\ImportAction;
use Filament\Tables\Filters\Filter;
use Filament\Tables\Table;
use Illuminate\Database\Eloquent\Builder;
use Illuminate\Database\Eloquent\SoftDeletingScope;
use Illuminate\Support\Str;
class TestingLineVisualizationResource extends Resource
{
protected static ?string $model = TestingLineVisualization::class;
protected static ?string $navigationIcon = 'heroicon-o-rectangle-stack';
protected static ?string $navigationGroup = 'Pump Testing Panel';
protected static ?int $navigationSort = 4;
public static function form(Form $form): Form
{
return $form
->schema([
Section::make('')
->schema([
Forms\Components\Select::make('plant_id')
->label('Plant Name')
->relationship('plant', 'name')
->reactive()
->searchable()
->options(function (callable $get) {
$userHas = Filament::auth()->user()->plant_id;
return ($userHas && strlen($userHas) > 0) ? Plant::where('id', $userHas)->pluck('name', 'id')->toArray() : Plant::orderBy('code')->pluck('name', 'id')->toArray();
})
->required()
->default(function () {
$userHas = Filament::auth()->user()->plant_id;
return ($userHas && strlen($userHas) > 0) ? null : optional(TestingLineVisualization::latest()->first())->plant_id ?? null;
})
->afterStateUpdated(function ($state, callable $set, callable $get) {
$set('updated_by', Filament::auth()->user()?->name);
})
->disabled(fn (Get $get) => ! empty($get('id'))),
Forms\Components\TextInput::make('test_bed_group')
->label('Test Bed Group')
->placeholder('Enter Test Bed Group')
->reactive()
->default(function () {
$userHas = Filament::auth()->user()->plant_id;
return ($userHas && strlen($userHas) > 0) ? null : optional(TestingLineVisualization::latest()->first())->test_bed_group ?? null;
})
->afterStateUpdated(function ($state, callable $set, callable $get) {
$set('updated_by', Filament::auth()->user()?->name);
})
->required(),
Forms\Components\TextInput::make('line_no')
->label('Line Number')
->placeholder('Enter Line Number')
->reactive()
->default(function () {
$userHas = Filament::auth()->user()->plant_id;
return ($userHas && strlen($userHas) > 0) ? null : optional(TestingLineVisualization::latest()->first())->line_no ?? null;
})
->afterStateUpdated(function ($state, callable $set, callable $get) {
$set('updated_by', Filament::auth()->user()?->name);
})
->required(),
Forms\Components\TextInput::make('sale_order')
->label('Sale Order')
->placeholder('Enter Sale Order')
->reactive()
->default(function () {
$userHas = Filament::auth()->user()->plant_id;
return ($userHas && strlen($userHas) > 0) ? null : optional(TestingLineVisualization::latest()->first())->sale_order ?? null;
})
->afterStateUpdated(function ($state, callable $set, callable $get) {
$set('updated_by', Filament::auth()->user()?->name);
})
->required(),
Forms\Components\TextInput::make('job_order')
->label('Job Order')
->placeholder('Enter Job Order')
->reactive()
->default(function () {
$userHas = Filament::auth()->user()->plant_id;
return ($userHas && strlen($userHas) > 0) ? null : optional(TestingLineVisualization::latest()->first())->job_order ?? null;
})
->afterStateUpdated(function ($state, callable $set, callable $get) {
$set('updated_by', Filament::auth()->user()?->name);
})
->required(),
Forms\Components\TextInput::make('pump_model')
->label('Pump Model')
->placeholder('Enter Pump Model')
->reactive()
->default(function () {
$userHas = Filament::auth()->user()->plant_id;
return ($userHas && strlen($userHas) > 0) ? null : optional(TestingLineVisualization::latest()->first())->pump_model ?? null;
})
->afterStateUpdated(function ($state, callable $set, callable $get) {
$set('updated_by', Filament::auth()->user()?->name);
})
->required(),
Forms\Components\TextInput::make('pump_type')
->label('Pump Type')
->placeholder('Enter Pump Type')
->reactive()
->default(function () {
$userHas = Filament::auth()->user()->plant_id;
return ($userHas && strlen($userHas) > 0) ? null : optional(TestingLineVisualization::latest()->first())->pump_type ?? null;
})
->afterStateUpdated(function ($state, callable $set, callable $get) {
$set('updated_by', Filament::auth()->user()?->name);
})
->required(),
Forms\Components\TextInput::make('motor_details')
->label('Motor Details')
->placeholder('Enter Motor Details')
->reactive()
->default(function () {
$userHas = Filament::auth()->user()->plant_id;
return ($userHas && strlen($userHas) > 0) ? null : optional(TestingLineVisualization::latest()->first())->motor_details ?? null;
})
->afterStateUpdated(function ($state, callable $set, callable $get) {
$set('updated_by', Filament::auth()->user()?->name);
})
->required(),
Forms\Components\Select::make('test_type')
->label('Test Type')
->nullable()
->options(function (callable $get) {
$plantId = $get('Plant');
if ($plantId) {
return Configuration::where('plant_id', $plantId)
->where('c_name', 'VISUALIZATION_TEST_TYPE')
->orderBy('created_at')
->pluck('c_value', 'c_value')
->toArray();
} else {
return Configuration::where('c_name', 'VISUALIZATION_TEST_TYPE')
->orderBy('created_at')
->pluck('c_value', 'c_value')
->toArray();
}
})
->default(function () {
$userHas = Filament::auth()->user()->plant_id;
return ($userHas && strlen($userHas) > 0) ? null : optional(TestingLineVisualization::latest()->first())->test_type ?? null;
})
->afterStateUpdated(function ($state, callable $set, callable $get) {
$set('updated_by', Filament::auth()->user()?->name);
})
->searchable()
->reactive()
->required(),
Forms\Components\TextInput::make('flow')
->label('Flow')
->placeholder('Enter Flow')
->reactive()
->numeric()
->default(function () {
$userHas = Filament::auth()->user()->plant_id;
return ($userHas && strlen($userHas) > 0) ? null : optional(TestingLineVisualization::latest()->first())->flow ?? '0';
})
->afterStateUpdated(function ($state, callable $set, callable $get) {
$set('updated_by', Filament::auth()->user()?->name);
})
->required(),
Forms\Components\TextInput::make('head')
->label('Head')
->placeholder('Enter Head')
->reactive()
->numeric()
->default(function () {
$userHas = Filament::auth()->user()->plant_id;
return ($userHas && strlen($userHas) > 0) ? null : optional(TestingLineVisualization::latest()->first())->head ?? '0';
})
->afterStateUpdated(function ($state, callable $set, callable $get) {
$set('updated_by', Filament::auth()->user()?->name);
})
->required(),
Forms\Components\TextInput::make('run_time')
->label('Run Time')
->placeholder('Enter Run Time')
->reactive()
->numeric()
->default(function () {
$userHas = Filament::auth()->user()->plant_id;
return ($userHas && strlen($userHas) > 0) ? null : optional(TestingLineVisualization::latest()->first())->run_time ?? '0.0';
})
->afterStateUpdated(function ($state, callable $set, callable $get) {
$set('updated_by', Filament::auth()->user()?->name);
})
->required(),
Forms\Components\Select::make('live_status')
->label('Status')
->nullable()
->options(function (callable $get) {
$plantId = $get('Plant');
if ($plantId) {
return Configuration::where('plant_id', $plantId)
->where('c_name', 'VISUALIZATION_LIVE_STATUS')
->orderBy('created_at')
->pluck('c_value', 'c_value')
->toArray();
} else {
return Configuration::where('c_name', 'VISUALIZATION_LIVE_STATUS')
->orderBy('created_at')
->pluck('c_value', 'c_value')
->toArray();
}
})
->default(function () {
$userHas = Filament::auth()->user()->plant_id;
return ($userHas && strlen($userHas) > 0) ? null : optional(TestingLineVisualization::latest()->first())->live_status ?? null;
})
->afterStateUpdated(function ($state, callable $set, callable $get) {
$set('updated_by', Filament::auth()->user()?->name);
})
->searchable()
->reactive()
->required(),
Forms\Components\TextInput::make('observation_remarks')
->label('Observation Remarks')
->placeholder('Enter Observation Remarks')
->reactive()
->default(function () {
$userHas = Filament::auth()->user()->plant_id;
return ($userHas && strlen($userHas) > 0) ? null : optional(TestingLineVisualization::latest()->first())->observation_remarks ?? 'Normal';
})
->afterStateUpdated(function ($state, callable $set, callable $get) {
$set('updated_by', Filament::auth()->user()?->name);
}),
Forms\Components\Hidden::make('created_by')
->label('Created By')
->default(Filament::auth()->user()?->name),
Forms\Components\Hidden::make('updated_by')
->label('Updated By')
->default(Filament::auth()->user()?->name),
Forms\Components\TextInput::make('id')
->hidden()
->readOnly(),
])
->columns(['default' => 1, 'sm' => 2]),
]);
}
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 Name')
->alignCenter()
->searchable()
->sortable(),
Tables\Columns\TextColumn::make('test_bed_group')
->label('Test Bed Group')
->alignCenter()
->searchable()
->sortable(),
Tables\Columns\TextColumn::make('line_no')
->label('Line No')
->alignCenter()
->searchable()
->sortable(),
Tables\Columns\TextColumn::make('sale_order')
->label('Sale Order')
->alignCenter()
->searchable()
->sortable(),
Tables\Columns\TextColumn::make('job_order')
->label('Job Order')
->alignCenter()
->searchable()
->sortable(),
Tables\Columns\TextColumn::make('pump_model')
->label('Pump Model')
->alignCenter()
->searchable()
->sortable(),
Tables\Columns\TextColumn::make('pump_type')
->label('Pump Type')
->alignCenter()
->searchable()
->sortable(),
Tables\Columns\TextColumn::make('motor_details')
->label('Motor Details')
->alignCenter()
->searchable()
->sortable(),
Tables\Columns\TextColumn::make('test_type')
->label('Test Type')
->alignCenter()
->searchable()
->sortable(),
Tables\Columns\TextColumn::make('flow')
->label('Flow')
->alignCenter()
->searchable()
->sortable(),
Tables\Columns\TextColumn::make('head')
->label('Head')
->alignCenter()
->searchable()
->sortable(),
Tables\Columns\TextColumn::make('run_time')
->label('Run Time')
->alignCenter()
->searchable()
->sortable(),
Tables\Columns\TextColumn::make('live_status')
->label('Status')
->alignCenter()
->searchable()
->sortable()
->color(fn (string $state): string => match ($state) {
'Running' => 'success',
'OFF' => 'danger',
'Aligning' => 'warning',
'MTN' => 'info',
default => 'gray',
})
->badge()
->default('-'),
Tables\Columns\TextColumn::make('observation_remarks')
->label('Observation / Remarks')
->alignCenter()
->searchable()
->sortable()
->color(fn (string $state): string => match ($state) {
default => 'gray',
})
->badge()
->default('-'),
Tables\Columns\TextColumn::make('created_at')
->label('Created At')
->dateTime()
->alignCenter()
->searchable()
->sortable(),
Tables\Columns\TextColumn::make('created_by')
->label('Created By')
->alignCenter()
->searchable()
->sortable(),
Tables\Columns\TextColumn::make('updated_at')
->label('Updated At')
->dateTime()
->alignCenter()
->searchable()
->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')
->dateTime()
->alignCenter()
->searchable()
->sortable()
->toggleable(isToggledHiddenByDefault: true),
])
->filters([
Tables\Filters\TrashedFilter::make(),
Filter::make('advanced_filters')
->label('Advanced Filters')
->form([
Select::make('Plant')
->label('Search by Plant Name')
->nullable()
->searchable()
->reactive()
->options(function (callable $get) {
$userHas = Filament::auth()->user()->plant_id;
if ($userHas && strlen($userHas) > 0) {
return Plant::where('id', $userHas)->pluck('name', 'id')->toArray();
} else {
return Plant::whereHas('testingLineVisualizations', function ($query) {
$query->whereNotNull('id');
})->orderBy('code')->pluck('name', 'id');
}
})
->afterStateUpdated(function ($state, callable $set, callable $get): void {
$set('created_by', null);
$set('updated_by', null);
}),
TextInput::make('test_bed_group')
->label('Test Bed Group')
->placeholder('Enter Test Bed Group')
->live(500),
TextInput::make('line_no')
->label('Line No')
->placeholder('Enter Line No')
->live(500),
TextInput::make('sale_order')
->label('Sale Order')
->placeholder('Enter Sale Order')
->live(500),
TextInput::make('job_order')
->label('Job Order')
->placeholder('Enter Job Order')
->live(500),
TextInput::make('pump_model')
->label('Pump Model')
->placeholder('Enter Pump Model')
->live(500),
TextInput::make('pump_type')
->label('Pump Type')
->placeholder('Enter Pump Type')
->live(500),
TextInput::make('motor_details')
->label('Motor Details')
->placeholder('Enter Motor Details')
->live(500),
Select::make('test_type')
->label('Test Type')
->nullable()
->options(function (callable $get) {
$plantId = $get('Plant');
if ($plantId) {
return TestingLineVisualization::where('plant_id', $plantId)->whereNotNull('test_type')->select('test_type')->distinct()->pluck('test_type', 'test_type');
} else {
return TestingLineVisualization::whereNotNull('test_type')->select('test_type')->distinct()->pluck('test_type', 'test_type');
}
})
->searchable()
->reactive(),
TextInput::make('flow')
->label('Flow')
->placeholder('Enter Flow')
->reactive()
->numeric(),
TextInput::make('head')
->label('Head')
->placeholder('Enter Head')
->reactive()
->numeric(),
TextInput::make('run_time')
->label('Run Time')
->placeholder('Enter Run Time')
->reactive()
->numeric(),
Select::make('live_status')
->label('Status')
->nullable()
->options(function (callable $get) {
$plantId = $get('Plant');
if ($plantId) {
return TestingLineVisualization::where('plant_id', $plantId)->whereNotNull('live_status')->select('live_status')->distinct()->pluck('live_status', 'live_status');
} else {
return TestingLineVisualization::whereNotNull('live_status')->select('live_status')->distinct()->pluck('live_status', 'live_status');
}
})
->searchable()
->reactive(),
TextInput::make('observation_remarks')
->label('Observation / Remarks')
->placeholder('Enter Observation / Remarks')
->live(500),
Select::make('created_by')
->label('Search by Created By')
->nullable()
->options(function (callable $get) {
$plantId = $get('Plant');
if ($plantId) {
return TestingLineVisualization::where('plant_id', $plantId)->whereNotNull('created_by')->select('created_by')->distinct()->pluck('created_by', 'created_by');
} else {
return TestingLineVisualization::whereNotNull('created_by')->select('created_by')->distinct()->pluck('created_by', 'created_by');
}
})
->searchable()
->reactive(),
DateTimePicker::make('created_from')
->label('Created From')
->placeholder('Select From DateTime')
->reactive()
->native(false),
DateTimePicker::make('created_to')
->label('Created To')
->placeholder('Select To DateTime')
->reactive()
->native(false),
Select::make('updated_by')
->label('Search by Updated By')
->nullable()
->options(function (callable $get) {
$plantId = $get('Plant');
if ($plantId) {
return TestingLineVisualization::where('plant_id', $plantId)->whereNotNull('updated_by')->select('updated_by')->distinct()->pluck('updated_by', 'updated_by');
} else {
return TestingLineVisualization::whereNotNull('updated_by')->select('updated_by')->distinct()->pluck('updated_by', 'updated_by');
}
})
->searchable()
->reactive(),
DateTimePicker::make(name: 'updated_from')
->label('Updated From')
->placeholder(placeholder: 'Select From DateTime')
->reactive()
->native(false),
DateTimePicker::make('updated_to')
->label('Updated 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['test_bed_group']) && empty($data['line_no']) && empty($data['sale_order']) && empty($data['job_order']) && empty($data['pump_model']) && empty($data['pump_type']) && empty($data['motor_details']) && empty($data['test_type']) && Str::length($data['flow']) <= 0 && Str::length($data['head']) <= 0 && Str::length($data['run_time']) <= 0 && empty($data['live_status']) && empty($data['observation_remarks']) && empty($data['created_by']) && empty($data['created_from']) && empty($data['created_to']) && empty($data['updated_by']) && empty($data['updated_from']) && empty($data['updated_to'])) {
return $query->whereRaw('1 = 0');
}
if (! empty($data['Plant'])) { // $plant = $data['Plant'] ?? null
$query->where('plant_id', $data['Plant']);
} else {
$userHas = Filament::auth()->user()->plant_id;
if ($userHas && strlen($userHas) > 0) {
return $query->whereRaw('1 = 0');
}
}
if (! empty($data['test_bed_group'])) {
$query->where('test_bed_group', 'like', '%'.$data['test_bed_group'].'%');
}
if (! empty($data['line_no'])) {
$query->where('line_no', $data['line_no']);
}
if (! empty($data['sale_order'])) {
$query->where('sale_order', 'like', '%'.$data['sale_order'].'%');
}
if (! empty($data['job_order'])) {
$query->where('job_order', 'like', '%'.$data['job_order'].'%');
}
if (! empty($data['pump_model'])) {
$query->where('pump_model', 'like', '%'.$data['pump_model'].'%');
}
if (! empty($data['pump_type'])) {
$query->where('pump_type', 'like', '%'.$data['pump_type'].'%');
}
if (! empty($data['motor_details'])) {
$query->where('motor_details', 'like', '%'.$data['motor_details'].'%');
}
if (! empty($data['test_type'])) {
$query->where('test_type', $data['test_type']);
}
if (Str::length($data['flow']) > 0) {
$query->where('flow', $data['flow']);
}
if (Str::length($data['head']) > 0) {
$query->where('head', $data['head']);
}
if (Str::length($data['run_time']) > 0) {
$query->where('run_time', $data['run_time']);
}
if (! empty($data['live_status'])) {
$query->where('live_status', $data['live_status']);
}
if (! empty($data['observation_remarks'])) {
$query->where('observation_remarks', 'like', '%'.$data['observation_remarks'].'%');
}
if (! empty($data['created_by'])) {
$query->where('created_by', $data['created_by']);
}
if (! empty($data['created_from'])) {
$query->where('created_at', '>=', $data['created_from']);
}
if (! empty($data['created_to'])) {
$query->where('created_at', '<=', $data['created_to']);
}
if (! empty($data['updated_by'])) {
$query->where('updated_by', $data['updated_by']);
}
if (! empty($data['updated_from'])) {
$query->where('updated_at', '>=', $data['updated_from']);
}
if (! empty($data['updated_to'])) {
$query->where('updated_at', '<=', $data['updated_to']);
}
})
->indicateUsing(function (array $data) {
$indicators = [];
if (! empty($data['Plant'])) {
$indicators[] = 'Plant Name: '.Plant::where('id', $data['Plant'])->value('name');
} else {
$userHas = Filament::auth()->user()->plant_id;
if ($userHas && strlen($userHas) > 0) {
return 'Plant: Choose plant to filter records.';
}
}
if (! empty($data['test_bed_group'])) {
$indicators[] = 'Test Bed Group: '.$data['test_bed_group'];
}
if (! empty($data['line_no'])) {
$indicators[] = 'Line No: '.$data['line_no'];
}
if (! empty($data['sale_order'])) {
$indicators[] = 'Sale Order: '.$data['sale_order'];
}
if (! empty($data['job_order'])) {
$indicators[] = 'Job Order: '.$data['job_order'];
}
if (! empty($data['pump_model'])) {
$indicators[] = 'Pump Model: '.$data['pump_model'];
}
if (! empty($data['pump_type'])) {
$indicators[] = 'Pump Type: '.$data['pump_type'];
}
if (! empty($data['motor_details'])) {
$indicators[] = 'Motor Details: '.$data['motor_details'];
}
if (! empty($data['test_type'])) {
$indicators[] = 'Test Type: '.$data['test_type'];
}
if (Str::length($data['flow']) > 0) {
$indicators[] = 'Flow: '.$data['flow'];
}
if (Str::length($data['head']) > 0) {
$indicators[] = 'Head: '.$data['head'];
}
if (Str::length($data['run_time']) > 0) {
$indicators[] = 'Run Time: '.$data['run_time'];
}
if (! empty($data['live_status'])) {
$indicators[] = 'Status: '.$data['live_status'];
}
if (! empty($data['observation_remarks'])) {
$indicators[] = 'Observation / Remarks: '.$data['observation_remarks'];
}
if (! empty($data['created_by'])) {
$indicators[] = 'Created By: '.$data['created_by'];
}
if (! empty($data['created_from'])) {
$indicators[] = 'Created From: '.$data['created_from'];
}
if (! empty($data['created_to'])) {
$indicators[] = 'Created To: '.$data['created_to'];
}
if (! empty($data['updated_by'])) {
$indicators[] = 'Updated By: '.$data['updated_by'];
}
if (! empty($data['updated_from'])) {
$indicators[] = 'Updated From: '.$data['updated_from'];
}
if (! empty($data['updated_to'])) {
$indicators[] = 'Updated To: '.$data['updated_to'];
}
return $indicators;
}),
])
->filtersFormMaxHeight('280px')
->actions([
Tables\Actions\ViewAction::make(),
Tables\Actions\EditAction::make(),
])
->bulkActions([
Tables\Actions\BulkActionGroup::make([
Tables\Actions\DeleteBulkAction::make(),
Tables\Actions\ForceDeleteBulkAction::make(),
Tables\Actions\RestoreBulkAction::make(),
]),
])
->headerActions([
ImportAction::make()
->label('Import Testing Line Visualizations')
->color('warning')
->importer(TestingLineVisualizationImporter::class)
->visible(function () {
return Filament::auth()->user()->can('view import testing line visualizations');
}),
ExportAction::make()
->label('Export Testing Line Visualizations')
->color('warning')
->exporter(TestingLineVisualizationExporter::class)
->visible(function () {
return Filament::auth()->user()->can('view export testing line visualizations');
}),
]);
}
public static function getRelations(): array
{
return [
//
];
}
public static function getPages(): array
{
return [
'index' => Pages\ListTestingLineVisualizations::route('/'),
'create' => Pages\CreateTestingLineVisualization::route('/create'),
'view' => Pages\ViewTestingLineVisualization::route('/{record}'),
'edit' => Pages\EditTestingLineVisualization::route('/{record}/edit'),
];
}
public static function getEloquentQuery(): Builder
{
return parent::getEloquentQuery()
->withoutGlobalScopes([
SoftDeletingScope::class,
]);
}
}

View File

@@ -0,0 +1,16 @@
<?php
namespace App\Filament\Resources\TestingLineVisualizationResource\Pages;
use App\Filament\Resources\TestingLineVisualizationResource;
use Filament\Resources\Pages\CreateRecord;
class CreateTestingLineVisualization extends CreateRecord
{
protected static string $resource = TestingLineVisualizationResource::class;
protected function getRedirectUrl(): string
{
return $this->getResource()::getUrl('create');
}
}

View File

@@ -0,0 +1,22 @@
<?php
namespace App\Filament\Resources\TestingLineVisualizationResource\Pages;
use App\Filament\Resources\TestingLineVisualizationResource;
use Filament\Actions;
use Filament\Resources\Pages\EditRecord;
class EditTestingLineVisualization extends EditRecord
{
protected static string $resource = TestingLineVisualizationResource::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\TestingLineVisualizationResource\Pages;
use App\Filament\Resources\TestingLineVisualizationResource;
use Filament\Actions;
use Filament\Resources\Pages\ListRecords;
class ListTestingLineVisualizations extends ListRecords
{
protected static string $resource = TestingLineVisualizationResource::class;
protected function getHeaderActions(): array
{
return [
Actions\CreateAction::make(),
];
}
}

View File

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

View File

@@ -52,7 +52,7 @@ class TestingPanelReadingResource extends Resource
protected static ?string $navigationGroup = 'Motor Testing Panel';
protected static ?int $navigationSort = 5;
protected static ?int $navigationSort = 6;
public static function form(Form $form): Form
{
@@ -652,6 +652,16 @@ class TestingPanelReadingResource extends Resource
->reactive()
// ->live()
// ->format('d-m-Y H:i:s')
->readOnly(fn (Get $get) => $get('id')) // checkhere...............................
->disabled(fn (Get $get) => ! empty($get('id')))
->afterStateUpdated(function ($state, callable $set, callable $get) {
$set('updated_by', Filament::auth()->user()?->name);
}),
Forms\Components\DateTimePicker::make('test_finished_at')
->label('FR Finished At')
->reactive()
// ->live()
// ->format('d-m-Y H:i:s')
->readOnly(fn (Get $get) => $get('id'))
->disabled(fn (Get $get) => ! empty($get('id')))
->afterStateUpdated(function ($state, callable $set, callable $get) {
@@ -939,6 +949,11 @@ class TestingPanelReadingResource extends Resource
->alignCenter()
->sortable()
->dateTime(),
Tables\Columns\TextColumn::make('test_finished_at')
->label('FR Finished At')
->alignCenter()
->sortable()
->dateTime(),
Tables\Columns\TextColumn::make('rework_count')
->label('Rework Count')
->alignCenter(),
@@ -1232,6 +1247,16 @@ class TestingPanelReadingResource extends Resource
->placeholder('Select To DateTime')
->reactive()
->native(false),
DateTimePicker::make('test_finished_from')
->label('FR Finished From')
->placeholder('Select From DateTime')
->reactive()
->native(false),
DateTimePicker::make('test_finished_to')
->label('FR Finished To')
->placeholder('Select To DateTime')
->reactive()
->native(false),
Select::make('tested_by')
->label('Tested By')
->nullable()
@@ -1283,7 +1308,7 @@ class TestingPanelReadingResource extends Resource
// dd($data);
// Hide all records initially if no filters are applied
if (empty($data['Plant']) && empty($data['Line']) && empty($data['item_code']) && empty($data['subassembly_code']) && empty($data['machine_name']) && empty($data['item_description']) && empty($data['serial_number']) && empty($data['winded_serial_number']) && empty($data['output']) && empty($data['connection']) && empty($data['remark']) && empty($data['batch_number']) && empty($data['result']) && empty($data['test_sequence_flag']) && empty($data['test_started_from']) && empty($data['test_started_to']) && empty($data['tested_by']) && empty($data['created_from']) && empty($data['created_to']) && empty($data['updated_by']) && empty($data['updated_from']) && empty($data['updated_to'])) {
if (empty($data['Plant']) && empty($data['Line']) && empty($data['item_code']) && empty($data['subassembly_code']) && empty($data['machine_name']) && empty($data['item_description']) && empty($data['serial_number']) && empty($data['winded_serial_number']) && empty($data['output']) && empty($data['connection']) && empty($data['remark']) && empty($data['batch_number']) && empty($data['result']) && empty($data['test_sequence_flag']) && empty($data['test_started_from']) && empty($data['test_started_to']) && empty($data['test_finished_from']) && empty($data['test_finished_to']) && empty($data['tested_by']) && empty($data['created_from']) && empty($data['created_to']) && empty($data['updated_by']) && empty($data['updated_from']) && empty($data['updated_to'])) {
return $query->whereRaw('1 = 0');
}
@@ -1392,6 +1417,14 @@ class TestingPanelReadingResource extends Resource
$query->where('test_started_at', '<=', $data['test_started_to']);
}
if (! empty($data['test_finished_from'])) {
$query->where('test_finished_at', '>=', $data['test_finished_from']);
}
if (! empty($data['test_finished_to'])) {
$query->where('test_finished_at', '<=', $data['test_finished_to']);
}
if (! empty($data['created_from'])) {
$query->where('created_at', '>=', $data['created_from']);
}
@@ -1486,6 +1519,14 @@ class TestingPanelReadingResource extends Resource
$indicators[] = 'Test Started To: '.$data['test_started_to'];
}
if (! empty($data['test_finished_from'])) {
$indicators[] = 'Test Finished From: '.$data['test_finished_from'];
}
if (! empty($data['test_finished_to'])) {
$indicators[] = 'Test Finished To: '.$data['test_finished_to'];
}
if (! empty($data['serial_number'])) {
$indicators[] = 'Serial Number: '.$data['serial_number'];
}

View File

@@ -116,7 +116,7 @@ class VisitorEntryResource extends Resource
}
}),
Forms\Components\Select::make('dealer')
->label('Dealer Visit')
->label('Dealer Visit / Special Guest')
->options(
DealerVisitPlan::where('status', 'Planned')
->whereDate('visit_plan_date', today())
@@ -350,6 +350,28 @@ class VisitorEntryResource extends Resource
])
->reactive()
->placeholder('Select Mode of Travel'),
Forms\Components\Select::make('tool_gadget')
->label('Tools & Gadgets')
->reactive()
->options([
'Laptop' => 'Laptop',
'Tablets' => 'Tablets',
'Mobiles' => 'Mobiles',
'Others' => 'Others',
])
->dehydrateStateUsing(function ($state, callable $get) {
return $state == 'Others'
? $get('other_tool')
: $state;
}),
Forms\Components\TextInput::make('other_tool')
->label('Specify Tool Type')
->reactive()
->visible(fn (callable $get) => $get('tool_gadget') == 'Others')
->required(fn (callable $get) => $get('tool_gadget') == 'Others')
->dehydrated(false),
Forms\Components\TextInput::make('serial_number')
->label('Serial Number'),
Forms\Components\DateTimePicker::make('in_time')
->label('In Time')
->required()
@@ -368,10 +390,10 @@ class VisitorEntryResource extends Resource
->columnSpanFull(),
Forms\Components\Hidden::make('photo'),
Forms\Components\Hidden::make('created_by')
->label('created_by')
->label('Created By')
->default(Filament::auth()->user()?->name),
Forms\Components\Hidden::make('updated_by')
->label('updated_by')
->label('Updated By')
->default(Filament::auth()->user()?->name),
]);
}
@@ -466,6 +488,16 @@ class VisitorEntryResource extends Resource
->searchable()
->alignCenter()
->sortable(),
Tables\Columns\TextColumn::make('tool_gadget')
->label('Tools & Gadgets')
->searchable()
->alignCenter()
->sortable(),
Tables\Columns\TextColumn::make('serial_number')
->label('Serial Number')
->searchable()
->alignCenter()
->sortable(),
Tables\Columns\TextColumn::make('in_time')
->label('In Time')
->searchable()

View File

@@ -13,6 +13,8 @@ class ItemOverview extends ChartWidget
{
protected static ?string $heading = 'Hourly Production';
public ?string $filter = 'today';
protected int|string|array $columnSpan = '12';
protected static ?string $maxHeight = '400px';
@@ -150,22 +152,97 @@ class ItemOverview extends ChartWidget
// $planQuantity
// );
if (in_array($activeFilter, ['today', 'yesterday'])) {
$planQuantity = round(array_sum($orderedData) / 22.5, 2);
$planData = [];
if ($activeFilter === 'today') {
$monthlyPlanQuantity = \DB::table('production_plans')
->where('plant_id', $selectedPlant)
->where('line_id', $selectedLine)
->whereYear('created_at', $startDate->year)
->whereMonth('created_at', $startDate->month)
->sum('plan_quantity');
$weeksCount = (int) ceil(now()->daysInMonth / 7);
$dailyPlan = $weeksCount > 0
? round($monthlyPlanQuantity / ($weeksCount * 7), 2)
: 0;
$hourlyPlan = round($dailyPlan / 22.5, 2);
$planData = array_fill(0, count($orderedData), $hourlyPlan);
}
if ($activeFilter === 'yesterday') {
$monthlyPlanQuantity = \DB::table('production_plans')
->where('plant_id', $selectedPlant)
->where('line_id', $selectedLine)
->whereYear('created_at', $startDate->year)
->whereMonth('created_at', $startDate->month)
->sum('plan_quantity');
// Calculate daily target directly
$weeksCount = (int) ceil($startDate->daysInMonth / 7);
$dailyPlan = $weeksCount > 0
? round($monthlyPlanQuantity / ($weeksCount * 7), 2)
: 0;
// Calculate hourly target
$hourlyPlan = round($dailyPlan / 22.5, 2);
// Same hourly plan value for every hour
$planData = array_fill(0, 24, $hourlyPlan);
}
elseif ($activeFilter === 'this_month') {
$monthlyPlanQuantity = \DB::table('production_plans')
->where('plant_id', $selectedPlant)
->where('line_id', $selectedLine)
->whereYear('created_at', $startDate->year)
->whereMonth('created_at', $startDate->month)
->sum('plan_quantity');
// Number of weeks in the current month
$weeksCount = count($orderedData);
// Split the total monthly plan equally across all weeks
$weeklyPlan = $weeksCount > 0
? round($monthlyPlanQuantity / $weeksCount, 2)
: 0;
$planData = array_fill(
0,
count($orderedData),
$planQuantity
);
} else {
// This Week: each day's production / 22.5
// This Month: each week's production / 22.5
$planData = array_map(
fn ($quantity) => round($quantity / 22.5, 2),
$orderedData
$weeksCount,
$weeklyPlan
);
}
elseif ($activeFilter === 'this_week') {
// Get the total plan quantity for the current month
$monthlyPlanQuantity = \DB::table('production_plans')
->where('plant_id', $selectedPlant)
->where('line_id', $selectedLine)
->whereYear('created_at', $startDate->year)
->whereMonth('created_at', $startDate->month)
->sum('plan_quantity');
// Number of calendar weeks in the current month
$weeksCount = (int) ceil($startDate->daysInMonth / 7);
// Monthly plan -> weekly plan -> daily plan
$weeklyPlan = $weeksCount > 0
? $monthlyPlanQuantity / $weeksCount
: 0;
$dailyPlan = round($weeklyPlan / 7, 2);
// Monday through Sunday
$planData = array_fill(0, 7, $dailyPlan);
}
return [
'datasets' => [

View File

@@ -5923,7 +5923,7 @@ class CharacteristicsController extends Controller
$modelHeading = $request->header('model-heading');
$requestType = $request->header('request-type');
Log::info("Request {$requestType} POST API >>", ['user-name' => $userName, 'characteristic-field' => $charField, 'plant-code' => $plantCode, 'work-center' => $workCenter, 'machine-name' => $machineName, 'aufnr' => $jobNo, 'gernr' => $serialNumber, 'item-code' => $itemCode, 'work-flow-id' => $workFlowId]);
Log::info("Request {$requestType} GET API >>", ['user-name' => $userName, 'characteristic-field' => $charField, 'plant-code' => $plantCode, 'work-center' => $workCenter, 'machine-name' => $machineName, 'aufnr' => $jobNo, 'gernr' => $serialNumber, 'item-code' => $itemCode, 'work-flow-id' => $workFlowId]);
if (! $userName || $userName == null || $userName == '') {
return response()->json([

View File

@@ -314,6 +314,78 @@ class PdfController extends Controller
}
public function getCoilDetails(Request $request){
$expectedUser = env('API_AUTH_USER');
$expectedPw = env('API_AUTH_PW');
$header_auth = $request->header('Authorization');
$expectedToken = $expectedUser.':'.$expectedPw;
if ('Bearer '.$expectedToken != $header_auth) {
return response()->json([
'status_code' => 'ERROR',
'status_description' => 'Invalid authorization token!',
], 404);
}
$plantCode = $request->header('plant-code');
$processOrder = $request->header('process-order');
if (! $plantCode) {
return response()->json([
'status_code' => 'ERROR',
'status_description' => "Plant Code value can't be empty",
], 404);
} elseif (! $processOrder) {
return response()->json([
'status_code' => 'ERROR',
'status_description' => 'Process Order cannot be empty!',
], 404);
}
if (!str_contains($processOrder, '-')) {
return response()->json([
'status_code' => 'ERROR',
'status_description' => "Invalid Process Order",
], 404);
}
$plant = Plant::where('code', $plantCode)->first();
$plantId = $plant->id;
if (! $plant) {
return response()->json([
'status_code' => 'ERROR',
'status_description' => "Plant Code '{$plantCode}' not found!",
], 404);
}
$parts = explode('-', $processOrder);
$processOrder = $parts[0]; // 261010002154
$coilNo = $parts[1]; // 001
$processOrderExist = ProcessOrder::where('process_order', $processOrder)->where('plant_id', $plantId)->where('coil_number', $coilNo)->first();
if ($processOrderExist) {
$itemId = $processOrderExist->item_id;
$item = Item::where('id', $itemId)->first();
$itemCode = $item->code;
return response()->json([
'status_code' => 'ERROR',
'status_description' => "Process order '$processOrder' with coil number '$coilNo' found against item '$itemCode'",
], 404);
}
else{
return response()->json([
'status_code' => 'ERROR',
'status_description' => "Process order '$processOrder' with coil number '$coilNo' not found'",
], 404);
}
}
/**
* Store a newly created resource in storage.
*/

View File

@@ -3,6 +3,7 @@
namespace App\Http\Controllers;
use App\Models\Item;
use App\Models\Line;
use App\Models\Plant;
use Illuminate\Http\Request;
@@ -129,6 +130,124 @@ class PlantController extends Controller
], 200);
}
public function getItemLine(Request $request){
$expectedUser = env('API_AUTH_USER');
$expectedPw = env('API_AUTH_PW');
$header_auth = $request->header('Authorization');
$expectedToken = $expectedUser.':'.$expectedPw;
if ('Bearer '.$expectedToken != $header_auth) {
return response()->json([
'status_code' => 'ERROR',
'status_description' => 'Invalid authorization token!',
], 403);
}
$plantCode = $request->header('plant-code');
$lineName = $request->header('line-name');
$itemCode = $request->header('item-code');
if (! $plantCode) {
return response()->json([
'status_code' => 'ERROR',
'status_description' => "Plant Code value can't be empty",
], 404);
}
elseif (! $lineName) {
return response()->json([
'status_code' => 'ERROR',
'status_description' => 'Line Name cannot be empty!',
], 404);
} elseif (! $itemCode) {
return response()->json([
'status_code' => 'ERROR',
'status_description' => 'Item code cannot be empty!',
], 404);
}
$plant = Plant::where('code', $plantCode)->first();
$plantId = $plant->id;
if (! $plant) {
return response()->json([
'status_code' => 'ERROR',
'status_description' => "Plant Code '{$plantCode}' not found!",
], 404);
}
$itemCodeExist = Item::where('code', $itemCode)->first();
if (! $itemCodeExist) {
return response()->json([
'status_code' => 'ERROR',
'status_description' => 'Item code not found',
], 404);
}
$itemCodePlantExist = Item::where('code', $itemCode)->where('plant_id', $plantId)->first();
if (! $itemCodePlantExist) {
return response()->json([
'status_code' => 'ERROR',
'status_description' => "Item code not found against plant code '$plantCode'",
], 404);
}
$lineNameExist = Line::where('name', $lineName)->first();
if (! $lineNameExist) {
return response()->json([
'status_code' => 'ERROR',
'status_description' => "Line Name '$lineName' not found",
], 404);
}
$lineNamePlantExist = Line::where('plant_id', $plantId)->where('name', $lineName)->first();
if (! $lineNamePlantExist) {
return response()->json([
'status_code' => 'ERROR',
'status_description' => "Line Name '$lineName' not found against plant code '$plantCode'",
], 404);
}
$itemCodeLineExist = Item::where('code', $itemCode)
->where('plant_id', $plantId)
->whereNotNull('line_id')
->where('line_id', '!=', $lineNamePlantExist->id)
->first();
if ($itemCodeLineExist) {
$mappedLine = Line::find($itemCodeLineExist->line_id);
return response()->json([
'status_code' => 'ERROR',
'status_description' => "Item code '$itemCode' is already mapped to line '{$mappedLine->name}'",
], 404);
}
$itemCodeLineMapped = Item::where('code', $itemCode)
->where('plant_id', $plantId)
->where('line_id', $lineNamePlantExist->id)
->first();
if (! $itemCodeLineMapped) {
return response()->json([
'status_code' => 'ERROR',
'status_description' => 'Not Ok'
], 200);
}
else{
return response()->json([
'status_code' => 'SUCCESS',
'status_description' => 'Ok',
], 200);
}
}
/**
* Update the specified resource in storage.
*/

View File

@@ -0,0 +1,180 @@
<?php
namespace App\Http\Controllers;
// use App\Models\ItemCharacteristic;
use App\Models\Plant;
use App\Models\TestingLineVisualization;
use App\Models\User;
use Illuminate\Http\Request;
use Illuminate\Support\Facades\Log;
use Str;
class TestingLineVisualizationController extends Controller
{
/**
* Display a listing of the resource.
*/
public function index()
{
//
}
/**
* Store a newly created resource in storage.
*/
public function store(Request $request)
{
//
}
/**
* Display the specified resource.
*/
public function getTestingLineVisualization(Request $request)
{
$expectedUser = env('API_AUTH_USER');
$expectedPw = env('API_AUTH_PW');
$headerAuth = $request->header('Authorization');
$expectedToken = 'Bearer '.$expectedUser.':'.$expectedPw;
if ($headerAuth != $expectedToken) {
return response()->json([
'status_code' => 'ERROR',
'status_description' => 'Invalid authorization token!',
], 401);
}
$userName = $request->header('user-name');
$plantCode = $request->header('plant-code');
Log::info('Testing Line Visualization GET API >>', ['user-name' => $userName, 'plant-code' => $plantCode]);
if (! $userName || $userName == null || $userName == '') {
return response()->json([
'status_code' => 'ERROR',
'status_description' => "User name can't be empty!",
], 404);
} elseif ($userName == 'jothi') {
$userName = 'Admin';
}
if (! $plantCode || $plantCode == null || $plantCode == '') {
return response()->json([
'status_code' => 'ERROR',
'status_description' => "Plant code can't be empty!",
], 404);
} elseif (! is_numeric($plantCode)) {
return response()->json([
'status_code' => 'ERROR',
'status_description' => "Plant code '{$plantCode}' should contain only numeric values!",
], 400);
} elseif (Str::length($plantCode) < 4 || Str::length($plantCode) > 7) {
return response()->json([
'status_code' => 'ERROR',
'status_description' => "Plant code '{$plantCode}' must be between 4 and 7 digits only!",
], 400);
} elseif (! preg_match('/^[1-9]\d{3,6}$/', $plantCode)) {
return response()->json([
'status_code' => 'ERROR',
'status_description' => "Invalid plant code '{$plantCode}' found!",
], 400);
}
$plant = Plant::where('code', $plantCode)->first();
if (! $plant) {
return response()->json([
'status_code' => 'ERROR',
'status_description' => "Plant code '{$plantCode}' not found in plants table!",
], 404);
}
$plantId = $plant->id;
$user = User::where('name', $userName)->first();
if (! $user) {
return response()->json([
'status_code' => 'ERROR',
'status_description' => "User name '{$userName}' not found in users table!",
], 404);
}
$userPlant = User::where('name', $userName)->where('plant_id', $plantId)->first();
if (! $userPlant && ! $user->hasRole('Super Admin')) {
return response()->json([
'status_code' => 'ERROR',
'status_description' => "User name '{$userName}' not found for the plant code '{$plantCode}' in users table!",
], 404);
} elseif (! $user->hasRole(['Super Admin', 'Testing Line Visualization Manager', 'Testing Line Visualization Supervisor', 'Testing Line Visualization Employee'])) {
return response()->json([
'status_code' => 'ERROR',
'status_description' => "User '{$userName}' does not have rights!",
], 404);
}
$jobAgaPlant = TestingLineVisualization::first();
if (! $jobAgaPlant) {
return response()->json([
'status_code' => 'ERROR',
'status_description' => 'Reports not found in testing line visualization table!',
], 404);
}
$jobAgaPlant = TestingLineVisualization::where('plant_id', $plantId)->first();
if (! $jobAgaPlant) {
return response()->json([
'status_code' => 'ERROR',
'status_description' => "Reports not found for the plant code '{$plantCode}' in testing line visualization table!",
], 404);
}
$records = TestingLineVisualization::where('plant_id', $plantId)->orderBy('id')->get();
$response = [];
foreach ($records as $row) {
$response[] = [
'test_bed_group' => $row->test_bed_group ?? '',
'line_no' => $row->line_no ?? '',
'sale_order' => $row->sale_order ?? '',
'job_order' => $row->job_order ?? '',
'pump_model' => $row->pump_model ?? '',
'pump_type' => $row->pump_type ?? '',
'motor_details' => $row->motor_details ?? '',
'test_type' => $row->test_type ?? '',
'flow' => $row->flow ?? '',
'head' => $row->head ?? '',
'run_time' => $row->run_time ?? '',
'status' => $row->live_status ?? '',
'observation_remarks' => $row->observation_remarks ?? '',
'created_by' => ($row->created_by == 'Admin') ? 'jothi' : $row->created_by ?? '',
'created_at' => $row->created_at ? $row->created_at->format('Y-m-d H:i:s') : '',
'updated_by' => ($row->updated_by == 'Admin') ? 'jothi' : $row->updated_by ?? '',
'updated_at' => $row->updated_at ? $row->updated_at->format('Y-m-d H:i:s') : '',
];
}
return response()->json([
'testing_line_visualizations' => $response,
], 200);
}
/**
* Update the specified resource in storage.
*/
public function update(Request $request, string $id)
{
//
}
/**
* Remove the specified resource from storage.
*/
public function destroy(string $id)
{
//
}
}

View File

@@ -327,6 +327,7 @@ class TestingPanelController extends Controller
'rework_winded' => $serial['rework_winded'] ?? 0,
'test_sequence_flag' => $serial['test_sequence_flag'] ?? '4',
'test_started_at' => $serial['test_started_at'] ?? null,
'test_finished_at' => $serial['test_finished_at'] ?? null,
'output_flag' => $serial['output_flag'] ?? 0,
'tested_by' => (($serial['tested_by'] == 'jothi') ? 'Admin' : $serial['tested_by']) ?? null,
'updated_by' => (($serial['updated_by'] == 'jothi') ? 'Admin' : $serial['updated_by']) ?? null,

View File

@@ -0,0 +1,188 @@
<?php
namespace App\Imports;
use App\Models\Item;
use App\Models\Plant;
use App\Models\ProductionCalendar;
use App\Models\ProductionPlan;
use App\Models\ProductionPlanTarget;
use Illuminate\Support\Collection;
use Maatwebsite\Excel\Concerns\ToCollection;
use Maatwebsite\Excel\Concerns\WithHeadingRow;
use Maatwebsite\Excel\Concerns\WithCalculatedFormulas;
use Illuminate\Support\Facades\DB;
use Exception;
use Carbon\Carbon;
class DayPlanTargetImport implements ToCollection, WithHeadingRow, WithCalculatedFormulas
{
protected $plantId;
protected $lineId;
protected $year;
protected $month;
protected $week;
public function __construct($plantId, $lineId, $year, $month, $week)
{
$this->plantId = $plantId;
$this->lineId = $lineId;
$this->year = $year;
$this->month = $month;
$this->week = strtolower($week);
}
public function collection(Collection $rows)
{
$weekMapping = [
'week_1' => 1,
'week_2' => 8,
'week_3' => 15,
'week_4' => 22,
'week_5' => 29,
];
if (!isset($weekMapping[$this->week])) {
throw new Exception('Invalid week selected.');
}
$startDay = $weekMapping[$this->week];
$daysInMonth = cal_days_in_month(
CAL_GREGORIAN,
(int) $this->month,
(int) $this->year
);
$maxDays = min(7, $daysInMonth - $startDay + 1);
if ($maxDays <= 0) {
throw new Exception('Selected week is outside the selected month.');
}
DB::transaction(function () use ($rows, $startDay, $maxDays) {
// Get calendar leave dates
$calendar = ProductionCalendar::where('plant_id', $this->plantId)
->whereMonth('created_at', $this->month)
->whereYear('created_at', $this->year)
->first();
$leaveDates = $calendar->leave_dates ?? [];
if (is_string($leaveDates)) {
$leaveDates = explode(',', $leaveDates);
}
$leaveDates = collect($leaveDates)
->map(fn ($date) => trim((string) $date))
->filter()
->map(fn ($date) => Carbon::parse($date)->format('Y-m-d'))
->toArray();
foreach ($rows as $index => $row) {
$excelValues = array_values($row->toArray());
// First two columns
$plantCode = trim((string) ($excelValues[0] ?? ''));
$itemCode = trim((string) ($excelValues[1] ?? ''));
if ($plantCode === '' || $itemCode === '') {
throw new Exception(
'Plant Code or Item Code missing in Excel row ' . ($index + 2)
);
}
$plant = Plant::where('code', $plantCode)->first();
if (!$plant) {
throw new Exception("Plant Code {$plantCode} not found.");
}
$item = Item::where('code', $itemCode)
->where('plant_id', $plant->id)
->first();
if (!$item) {
throw new Exception(
"Item Code {$itemCode} not found for Plant Code {$plantCode}."
);
}
$plan = ProductionPlan::where('plant_id', $plant->id)
->where('item_id', $item->id)
->whereMonth('created_at', $this->month)
->whereYear('created_at', $this->year)
->first();
if (!$plan) {
throw new Exception(
"Production plan not found for Item Code: {$itemCode}"
);
}
// Remaining columns contain daily quantities
$dayValues = array_slice($excelValues, 2);
$updateData = [];
for ($i = 0; $i < $maxDays; $i++) {
$databaseDay = $startDay + $i;
$date = Carbon::create(
$this->year,
$this->month,
$databaseDay
)->format('Y-m-d');
// Leave date: always zero
if (in_array($date, $leaveDates)) {
$updateData["day_{$databaseDay}"] = 0;
continue;
}
$quantity = $dayValues[$i] ?? null;
// Blank quantity: do not update
if ($quantity === null || trim((string) $quantity) === '') {
continue;
}
if (!is_numeric($quantity) || $quantity < 0) {
throw new Exception(
"Invalid quantity for Plant {$plantCode}, Item {$itemCode}, Day {$databaseDay}."
);
}
$updateData["day_{$databaseDay}"] = $quantity;
}
if (!empty($updateData)) {
$plan->update($updateData);
// Refresh the latest database values
$plan->refresh();
// Calculate total of day_1 to day_31
$totalPlanQuantity = 0;
for ($day = 1; $day <= 31; $day++) {
$totalPlanQuantity += (float) (
$plan->{"day_{$day}"} ?? 0
);
}
// Update monthly plan quantity
$plan->update([
'plan_quantity' => $totalPlanQuantity,
]);
}
}
});
}
}

View File

@@ -850,6 +850,25 @@ class InvoiceDataTable extends Component
if($categoryExist?->category == 'Panel Box'){
$panelExistsInvoice = InvoiceValidation::where('plant_id', $this->plantId)
->where('panel_box_serial_number', $serialNumber)
// ->where('panel_box_code', $itemCode)
->where('panel_box_supplier', $supplier)
->first();
if ($panelExistsInvoice) {
Notification::make()
->title('Duplicate Panel Box Serial Number')
->body("Duplicate panel already exists.<br>Panel Box Code: $itemCode, Item Code: {$this->currentItemCode}, Serial Number: $serialNumber, Supplier Number: $supplier against invoice Number: $panelExistsInvoice->invoice_number")
->danger()
->seconds(2)
->send();
$this->capacitorInput = '';
return;
}
$panelExist = PanelBoxValidation::where('plant_id', $this->plantId)->where('panel_box_serial_number', $serialNumber)->where('panel_box_code', $itemCode)->where('panel_box_supplier', $supplier)->first();
if(!$panelExist){
@@ -864,20 +883,15 @@ class InvoiceDataTable extends Component
return;
}
$panelExistsInvoice = InvoiceValidation::where('plant_id', $this->plantId)
->where('panel_box_serial_number', $serialNumber)
->where('panel_box_code', $itemCode)
->where('panel_box_supplier', $supplier)
->first();
$panelExistNotOk = PanelBoxValidation::where('plant_id', $this->plantId)->where('panel_box_serial_number', $serialNumber)->where('panel_box_code', $itemCode)->where('panel_box_supplier', $supplier)->whereNotNull('status')->where('status', '!=', '')->where('status', 'NotOk')->first();
if ($panelExistsInvoice) {
if($panelExistNotOk){
Notification::make()
->title('Duplicate Panel')
->body("Duplicate panel already exists.<br>Panel Box Code: $itemCode, Item Code: {$this->currentItemCode}, Serial Number: $serialNumber.")
->title('Panel Not Ok')
->body("Panel Quality Inspection NotOk.<br>Panel Box Code: $itemCode, Item Code: {$this->currentItemCode}, Serial Number: $serialNumber.</br>")
->danger()
->seconds(2)
->send();
$this->capacitorInput = '';
return;

File diff suppressed because it is too large Load Diff

View File

@@ -698,12 +698,18 @@ class ProductionTargetPlan extends Component
foreach ($plans as $plan) {
$row = $plan->toArray();
//$row = $plan->toArray();
$row['plan_quantity'] = (int) round($row['plan_quantity']);
$workingDays = (int) ($row['working_days'] ?? 0);
// $normalDailyTarget = $workingDays > 0
// ? round((float) $row['plan_quantity'] / $workingDays, 2)
// : 0;
$normalDailyTarget = $workingDays > 0
? round((float) $row['plan_quantity'] / $workingDays, 2)
? (int) round((float) $row['plan_quantity'] / $workingDays)
: 0;
$pendingQty = 0;
@@ -728,10 +734,12 @@ class ProductionTargetPlan extends Component
continue;
}
$todayTarget = round(
$normalDailyTarget + $pendingQty,
2
);
// $todayTarget = round(
// $normalDailyTarget + $pendingQty,
// 2
// );
$todayTarget = (int) round($normalDailyTarget + $pendingQty);
$producedQty = $producedData[$key][$date]->total_qty ?? 0;

View File

@@ -0,0 +1,253 @@
<?php
namespace App\Livewire;
use App\Models\ClassCharacteristic;
use App\Models\StickerStructureDetail;
use App\Models\Item;
use App\Models\StickerMappingMaster;
use Filament\Notifications\Notification;
use Livewire\Component;
use Livewire\Attributes\Reactive;
use Livewire\Attributes\On;
class RandomSerialNumberList extends Component
{
public bool $showMultipleSerials = false;
public array $serialNumbers = [''];
#[Reactive]
public $plantId = null;
#[Reactive]
public $machineId = null;
public function updatedShowMultipleSerials($value): void
{
$this->serialNumbers = collect($this->serialNumbers)
->filter(fn ($serial) => trim($serial) !== '')
->values()
->toArray();
// Clear all values whenever the checkbox changes
$this->serialNumbers = [''];
}
public function splitSerialNumbers(string $text): void
{
$serials = preg_split('/[\r\n\t ,;]+/', trim($text));
$this->serialNumbers = collect($serials)
->filter(fn ($serial) => $serial !== '')
->values()
->toArray();
if (empty($this->serialNumbers)) {
$this->serialNumbers = [''];
}
$plantId = $this->plantId;
$machineId = $this->machineId;
if (!$plantId) {
Notification::make()
->danger()
->title('Plant Not Selected')
->body('Please select a plant before pasting serial numbers.')
->send();
$this->dispatch('sticker-options-clear', stickerOptions: '');
$this->dispatch('production-order-clear', productionOrder: '');
return;
}
$serialNumbersArray = array_values(
array_filter(
array_map('trim', $this->serialNumbers),
fn ($serial) => $serial !== ''
)
);
if (count($serialNumbersArray) > 50) {
Notification::make()
->title('Too Many Serial Numbers')
->body('You can enter a maximum of 50 serial numbers.')
->danger()
->send();
$this->dispatch('sticker-options-clear', stickerOptions: '');
$this->dispatch('production-order-clear', productionOrder: '');
$this->serialNumbers = [''];
return;
}
$records = ClassCharacteristic::where('plant_id', $plantId)->whereIn('gernr', $serialNumbersArray)->get();
$foundSerialNumbers = $records->pluck('gernr')
->map(fn ($serial) => trim((string) $serial))
->unique()
->toArray();
$missingSerialNumbers = array_values(
array_diff($serialNumbersArray, $foundSerialNumbers)
);
if (!empty($missingSerialNumbers)) {
Notification::make()
->danger()
->title('Serial Numbers Not Found')
->body('The following serial numbers do not exist for the selected plant: '. implode(', ', $missingSerialNumbers))
->send();
return;
}
$productionOrder = $records->first()->aufnr;
$invalidSerialNumbers = $productionOrder
? $records->filter(
fn ($record) => $record->aufnr != $productionOrder
)->pluck('gernr')->unique()->values()->toArray()
: [];
if (!empty($invalidSerialNumbers)) {
Notification::make()
->danger()
->title('Invalid Serial Numbers')
->body('The following serial numbers belong to a different production order: '. implode(', ', $invalidSerialNumbers))
->send();
return;
}
$record = $records->first();
$itemId = $record->item_id;
$item = Item::find($itemId);
if (! $item) {
Notification::make()
->title('Item not found')
->body("Item code '{$itemId}' was not found in item master.")
->danger()
->send();
$this->dispatch('sticker-options-clear', stickerOptions: '');
$this->dispatch('production-order-clear', productionOrder: '');
return;
}
$itemCode = $item->code;
$item = Item::where('code', $itemCode)->where('plant_id', $plantId)->first();
if (! $item) {
Notification::make()
->title('Item not found')
->body("Item '{$itemCode}' was not found for the selected plant.")
->danger()
->send();
$this->dispatch('sticker-options-clear', stickerOptions: '');
$this->dispatch('production-order-clear', productionOrder: '');
return;
}
$itemCharacteristic = ClassCharacteristic::where('plant_id', $plantId)->where('item_id', $item->id)->first();
if (! $itemCharacteristic) {
Notification::make()
->title('Class characteristic not found')
->body("No class characteristic found for item '{$itemCode}'.")
->danger()
->send();
return;
}
// $itemCharacteristicId = $itemCharacteristic->id;
$stickerMappings = StickerMappingMaster::where('plant_id', $plantId)
->where('item_id', $item->id)
->get();
if (! $stickerMappings) {
Notification::make()
->title('Sticker mapping not found')
->body("No sticker mapping found for this plant and item '$itemCode'.")
->danger()
->send();
return;
}
$stickerOptions = [];
foreach ($stickerMappings as $stickerMapping) {
for ($i = 1; $i <= 8; $i++) {
$machineColumn = "sticker{$i}_machine_id";
$stickerMachineId = $stickerMapping->$machineColumn;
if ((string) $stickerMachineId != (string) $machineId) {
continue;
}
$structureColumn = "sticker_structure{$i}_id";
$stickerStructureId = $stickerMapping->$structureColumn;
if (empty($stickerStructureId)) {
continue;
}
$detail = StickerStructureDetail::find($stickerStructureId);
if ($detail && $detail->sticker_id) {
$stickerOptions[$detail->sticker_id] =
$detail->sticker_id;
}
$this->dispatch('sticker-structure-updated', stickerStructureId: $stickerStructureId);
}
}
$this->dispatch('sticker-options', stickerOptions: $stickerOptions);
$this->dispatch('production-order-updated', productionOrder: $productionOrder);
}
public function generate(): void
{
$serialNumbersString = implode(',', array_filter(
$this->serialNumbers,
fn ($serial) => trim($serial) !== ''
));
$this->dispatch('generate-sticker-id', serialNumbers: $serialNumbersString);
}
#[On('load-serial-numbers')]
public function loadSerialNumbers(array $serialNumbers = []): void
{
$this->serialNumbers = $serialNumbers ?: [''];
}
#[On('clear-serial-numbers')]
public function clearSerialNumbers(): void
{
$this->serialNumbers = [''];
$this->dispatch('sticker-options-clear', stickerOptions: '');
$this->dispatch('production-order-clear', productionOrder: '');
}
public function clear(){
$this->serialNumbers = [''];
$this->dispatch('sticker-options-clear', stickerOptions: '');
$this->dispatch('production-order-clear', productionOrder: '');
}
public function render()
{
return view('livewire.random-serial-number-list');
}
}

View File

@@ -0,0 +1,34 @@
<?php
namespace App\Models;
use Illuminate\Database\Eloquent\Model;
use Illuminate\Database\Eloquent\Relations\BelongsTo;
use Illuminate\Database\Eloquent\SoftDeletes;
class CourierInward extends Model
{
use SoftDeletes;
protected $fillable = [
'plant_id',
'date',
'from_address_name',
'cover_material',
'pod_number',
'courier_name',
'place',
'to_address_name',
'return_to_other_unit',
'created_at',
'updated_at',
'created_by',
'updated_by',
];
public function plant(): BelongsTo
{
return $this->belongsTo(Plant::class);
}
}

View File

@@ -0,0 +1,32 @@
<?php
namespace App\Models;
use Illuminate\Database\Eloquent\Model;
use Illuminate\Database\Eloquent\Relations\BelongsTo;
use Illuminate\Database\Eloquent\SoftDeletes;
class CourierOutward extends Model
{
use SoftDeletes;
protected $fillable = [
'plant_id',
'date',
'to_address',
'cover_material',
'name_of_sender',
'place_pincode',
'pod_number',
'remark',
'created_at',
'updated_at',
'created_by',
'updated_by',
];
public function plant(): BelongsTo
{
return $this->belongsTo(Plant::class);
}
}

View File

@@ -18,6 +18,8 @@ class Plant extends Model
'address',
'warehouse_number',
'reg_address',
'feed_address',
'tollfree',
];
public function company(): BelongsTo
@@ -220,15 +222,20 @@ class Plant extends Model
return $this->hasMany(BeforeTestReading::class, 'plant_id', 'id');
}
public function testingLineVisualizations()
{
return $this->hasMany(TestingLineVisualization::class, 'plant_id', 'id');
}
public function asrsItemValidations()
{
return $this->hasMany(AsrsItemValidation::class, 'plant_id', 'id');
}
// public function locatorValidations()
// {
// return $this->hasMany(LocatorValidation::class, 'plant_id', 'id');
// }
public function locatorValidations()
{
return $this->hasMany(LocatorValidation::class, 'plant_id', 'id');
}
public function characteristicApproverMaster()
{
@@ -259,4 +266,9 @@ class Plant extends Model
{
return $this->hasMany(ItemCharacteristic::class, 'plant_id', 'id');
}
public function courierInwards()
{
return $this->hasMany(CourierInward::class, 'plant_id', 'id');
}
}

View File

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

View File

@@ -23,6 +23,37 @@ class ProductionPlan extends Model
'working_days',
'leave_dates',
'operator_id',
'day_1',
'day_2',
'day_3',
'day_4',
'day_5',
'day_6',
'day_7',
'day_8',
'day_9',
'day_10',
'day_11',
'day_12',
'day_13',
'day_14',
'day_15',
'day_16',
'day_17',
'day_18',
'day_19',
'day_20',
'day_21',
'day_22',
'day_23',
'day_24',
'day_25',
'day_26',
'day_27',
'day_28',
'day_29',
'day_30',
'day_31',
'created_at',
'updated_at',
];

View File

@@ -0,0 +1,38 @@
<?php
namespace App\Models;
use Illuminate\Database\Eloquent\Model;
use Illuminate\Database\Eloquent\Relations\BelongsTo;
use Illuminate\Database\Eloquent\SoftDeletes;
class TestingLineVisualization extends Model
{
use SoftDeletes;
protected $fillable = [
'plant_id',
'test_bed_group',
'line_no',
'sale_order',
'job_order',
'pump_model',
'pump_type',
'motor_details',
'test_type',
'flow',
'head',
'run_time',
'live_status',
'observation_remarks',
'created_at',
'created_by',
'updated_at',
'updated_by',
];
public function plant(): BelongsTo
{
return $this->belongsTo(Plant::class);
}
}

View File

@@ -59,6 +59,7 @@ class TestingPanelReading extends Model
'remark',
'test_sequence_flag',
'test_started_at',
'test_finished_at',
'rework_count',
'rework_winded',
'update_count',

View File

@@ -25,6 +25,8 @@ class VisitorEntry extends Model
'number_of_person',
'valid_upto',
'mode_of_travel',
'tool_gadget',
'serial_number',
];
public function employeeMaster(): BelongsTo

View File

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

View File

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

View File

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

View File

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

View File

@@ -9,6 +9,8 @@ use App\Models\StickerDetail;
use App\Models\StickerMappingMaster;
use App\Models\StickerStructureDetail;
use App\Models\StickerValidation;
use App\Models\Company;
use App\Models\Plant;
use App\Models\TestApprovalMapping;
use App\Models\ClassCharacteristic;
use Illuminate\Http\Response;
@@ -1057,6 +1059,7 @@ class StickerPdfService
$plantName = $itemCharacteristic?->plant?->name ?? '';
$plantAddress = $itemCharacteristic?->plant?->address ?? '';
$plantRegdAddress = $itemCharacteristic?->plant?->reg_address ?? '';
$dateOfTest = $itemCharacteristic?->created_at?->format('d.m.Y') ?? '';
// $currentDate = $itemCharacteristic?->created_at?->format('M-y') ?? '';
@@ -1154,6 +1157,158 @@ class StickerPdfService
? number_format((float) $itemCharacteristic->{$column} * 2, 2, '.', '')
: '';
}
if ($row->characteristics_type == 'regd_address') {
$column = 'zmm_brand';
$textValue = $itemCharacteristic?->{$column} != null
? $itemCharacteristic->{$column}
: '';
if($textValue == 'TORMAC'){
$cName = Company::where('name', 'TORMAC')->first();
$plantRegdAddress = Plant::where('company_id', $cName->id)->first();
$textValue = $plantRegdAddress->reg_address;
}
else if($textValue == 'CRI'){
$cName = Company::where('name', 'CRI')->first();
$plantRegdAddress = Plant::where('company_id', $cName->id)->where('id', $plantId)->first();
$textValue = $plantRegdAddress->address;
}
else if($textValue == 'GENVIK'){
$cName = Company::where('name', 'GENVIK')->first();
$plantRegdAddress = Plant::where('company_id', $cName->id)->first();
$textValue = $plantRegdAddress->reg_address;
}
else if($textValue == 'ZIRANTEC'){
$cName = Company::where('name', 'ZIRANTEC')->first();
$plantRegdAddress = Plant::where('company_id', $cName->id)->first();
$textValue = $plantRegdAddress->reg_address;
}
}
if ($row->characteristics_type == 'feed_address') {
$column = 'zmm_brand';
$textValue = $itemCharacteristic?->{$column} != null
? $itemCharacteristic->{$column}
: '';
if($textValue == 'TORMAC'){
$cName = Company::where('name', 'TORMAC')->first();
$plantRegdAddress = Plant::where('company_id', $cName->id)->first();
$textValue = $plantRegdAddress->feed_address;
}
else if($textValue == 'CRI'){
$cName = Company::where('name', 'CRI')->first();
$plantRegdAddress = Plant::where('company_id', $cName->id)->where('id', $plantId)->first();
$textValue = $plantRegdAddress->feed_address;
}
else if($textValue == 'GENVIK'){
$cName = Company::where('name', 'GENVIK')->first();
$plantRegdAddress = Plant::where('company_id', $cName->id)->first();
$textValue = $plantRegdAddress->feed_address;
}
else if($textValue == 'ZIRANTEC'){
$cName = Company::where('name', 'ZIRANTEC')->first();
$plantRegdAddress = Plant::where('company_id', $cName->id)->first();
$textValue = $plantRegdAddress->feed_address;
}
}
if ($row->characteristics_type == 'regd_unit') {
$column = 'zmm_brand';
$textValue = $itemCharacteristic?->{$column} != null
? $itemCharacteristic->{$column}
: '';
if($textValue == 'TORMAC'){
$cName = Company::where('name', 'TORMAC')->first();
$plantRegdUnit = Plant::where('company_id', $cName->id)->first();
$textValue = $plantRegdUnit->name;
}
else if($textValue == 'CRI'){
$cName = Company::where('name', 'CRI')->first();
$plantRegdUnit = Plant::where('company_id', $cName->id)->where('id', $plantId)->first();
$textValue = $plantRegdUnit->name;
}
else if($textValue == 'GENVIK'){
$cName = Company::where('name', 'GENVIK')->first();
$plantRegdUnit = Plant::where('company_id', $cName->id)->first();
$textValue = $plantRegdUnit->name;
}
else if($textValue == 'ZIRANTEC'){
$cName = Company::where('name', 'ZIRANTEC')->first();
$plantRegdUnit = Plant::where('company_id', $cName->id)->first();
$textValue = $plantRegdUnit->name;
}
}
if ($row->characteristics_type == 'company_name') {
$column = 'zmm_brand';
$textValue = $itemCharacteristic?->{$column} != null
? $itemCharacteristic->{$column}
: '';
if($textValue == 'TORMAC'){
$cName = Company::where('name', 'TORMAC')->first();
$textValue = $cName->name;
}
else if($textValue == 'CRI'){
$cName = Company::where('name', 'CRI')->first();
$textValue = $cName->name;
}
else if($textValue == 'GENVIK'){
$cName = Company::where('name', 'GENVIK')->first();
$textValue = $cName->name;
}
else if($textValue == 'ZIRANTEC'){
$cName = Company::where('name', 'ZIRANTEC')->first();
$textValue = $cName->name;
}
}
if ($row->characteristics_type == 'tollfree') {
$column = 'zmm_brand';
$textValue = $itemCharacteristic?->{$column} != null
? $itemCharacteristic->{$column}
: '';
if($textValue == 'TORMAC'){
$cName = Company::where('name', 'TORMAC')->first();
$plantRegdUnit = Plant::where('company_id', $cName->id)->first();
$textValue = $plantRegdUnit->tollfree;
}
else if($textValue == 'CRI'){
$cName = Company::where('name', 'CRI')->first();
$plantRegdUnit = Plant::where('company_id', $cName->id)->where('id', $plantId)->first();
$textValue = $plantRegdUnit->tollfree;
}
else if($textValue == 'GENVIK'){
$cName = Company::where('name', 'GENVIK')->first();
$plantRegdUnit = Plant::where('company_id', $cName->id)->first();
$textValue = $plantRegdUnit->tollfree;
}
else if($textValue == 'ZIRANTEC'){
$cName = Company::where('name', 'ZIRANTEC')->first();
$plantRegdUnit = Plant::where('company_id', $cName->id)->first();
$textValue = $plantRegdUnit->tollfree;
}
}
if (str_contains($row->string_value ?? '', '₹')) {
@@ -1170,30 +1325,15 @@ class StickerPdfService
if (!empty($row->string_font)) {
$fontFile = storage_path('app/private/fonts/' . $row->string_font . '.ttf');
Log::info($fontFile, [
'font' => $row->string_font,
]);
if (file_exists($fontFile)) {
\Log::info('TCPDF FONT DEBUG', [
'K_PATH_FONTS' => defined('K_PATH_FONTS') ? K_PATH_FONTS : 'NOT DEFINED',
'fontFile' => $fontFile,
'php_sapi' => PHP_SAPI,
]);
$font = TCPDF_FONTS::addTTFfont(
$fontFile,
'TrueTypeUnicode',
'',
32
);
Log::info('FONT CONVERSION RESULT', [
'result' => $font,
]);
} else {
Log::warning('FONT FILE NOT FOUND', [
'font_file' => $fontFile,
]);
$font = 'helvetica';
}
} else {
@@ -1211,6 +1351,7 @@ class StickerPdfService
'font' => $font,
'size' => (int) ($row->string_size ?? 10),
'color' => $row->element_colour ?? '#000000',
'string_align' => strtolower($row->string_align ?? ''),
];
}
elseif ($row->design_element_type == 'QR') {
@@ -1467,7 +1608,7 @@ class StickerPdfService
// }
public function generateBulkFromTemplate(array $template,$fromSerial,$toSerial,string $itemCode)
public function generateBulkFromTemplate(array $template,$fromSerial,$toSerial,string $itemCode, ?string $randomSerials = null)
{
$stickerWidth = (float) $template['width'];
$stickerHeight = (float) $template['height'];
@@ -1564,11 +1705,42 @@ class StickerPdfService
$rgb[2]
);
$pdf->Text(
$element['x'],
$element['y'] + $currentY,
(string) $textValue
);
// $pdf->Text(
// $element['x'],
// $element['y'] + $currentY,
// (string) $textValue
// );
$alignment = strtolower($element['string_align'] ?? '');
$pdf->SetFont($element['font'], '', $element['size']);
$x = (float) $element['x'];
$y = $element['y'] + $currentY;
// $textWidth = $pdf->GetStringWidth((string) $textValue);
if ($alignment == 'center') {
if($stickerId == 'Sewage PumpSet Test Certificate' || $stickerId == 'Submersible Mixer Test Certificate' || $stickerId == 'Pump Test Certificate' || $stickerId == 'Submersible Aerator Pump Test Certificate'){
$leftMargin = 10; // mm from left edge
$rightMargin = 24; // mm from right edge
$usableWidth = $stickerWidth - $leftMargin - $rightMargin;
$textWidth = $pdf->GetStringWidth((string) $textValue);
// start x = left margin + half of the leftover space
$x = $leftMargin + (($usableWidth - $textWidth) / 2);
// if text is wider than the usable area, don't go past the left margin
if ($textWidth > $usableWidth) {
$x = $leftMargin;
}
}
}
$pdf->Text($x, $y, (string) $textValue);
}
elseif ($element['type'] == 'qr') {
@@ -1871,6 +2043,445 @@ class StickerPdfService
}
}
//..Multiple Serial Numbers
public function generateMultipleBulkFromTemplate(array $template, array $serialNumbersArray,string $itemCode, ?string $randomSerials = null)
{
$stickerWidth = (float) $template['width'];
$stickerHeight = (float) $template['height'];
$stickerId = $template['sticker_id'] ?? null;
// $gap = 5.0;
// $count = ($toSerial - $fromSerial) + 1;
// $totalHeight =
// ($stickerHeight * $count)
// +
// ($gap * ($count - 1));
$orientation = $stickerWidth > $stickerHeight ? 'L' : 'P';
// $pdf = new TCPDF(
// 'P',
// 'mm',
// [
// $stickerWidth,
// $stickerHeight
// ],
// true,
// 'UTF-8',
// false
// );
$pdf = new TCPDF($orientation, 'mm', [$stickerWidth, $stickerHeight], true, 'UTF-8', false);
$pdf->setPrintHeader(false);
$pdf->setPrintFooter(false);
$pdf->SetMargins(
0,
0,
0,
0
);
$pdf->SetAutoPageBreak(false, 0);
// $pdf->AddPage();
$currentY = 0;
// Generate every serial
if ($stickerId != 'SelfPriming Monoblock Pump Dual') {
foreach ($serialNumbersArray as $serial) {
$serial = (string) $serial;
$pdf->AddPage();
$qrContent = $itemCode . '|' . $serial;
$serialString = (string) $serial;
$serialDate = '';
if (strlen($serialString) >= 4) {
$year = substr($serialString, 0, 2);
$month = substr($serialString, 2, 2);
if ((int) $month >= 1 && (int) $month <= 12) {
$serialDate = \Carbon\Carbon::createFromFormat(
'y-m',
$year . '-' . $month
)->format('M-y');
}
}
foreach ($template['elements'] as $element) {
if ($element['type'] == 'text') {
$textValue = $element['value'];
if ($textValue == '__SERIAL_NUMBER__') {
$textValue = (string) $serial;
}
if ($textValue == '__CURRENT_DATE__') {
$textValue = $serialDate;
}
$pdf->SetFont($element['font'],'',$element['size']);
$rgb = $this->hexToRgb($element['color']);
$pdf->SetTextColor(
$rgb[0],
$rgb[1],
$rgb[2]
);
// $pdf->Text(
// $element['x'],
// $element['y'] + $currentY,
// (string) $textValue
// );
$alignment = strtolower($element['string_align'] ?? '');
$pdf->SetFont($element['font'], '', $element['size']);
$x = (float) $element['x'];
$y = $element['y'] + $currentY;
// $textWidth = $pdf->GetStringWidth((string) $textValue);
if ($alignment == 'center') {
if($stickerId == 'Sewage PumpSet Test Certificate' || $stickerId == 'Submersible Mixer Test Certificate' || $stickerId == 'Pump Test Certificate' || $stickerId == 'Submersible Aerator Pump Test Certificate'){
$leftMargin = 10; // mm from left edge
$rightMargin = 24; // mm from right edge
$usableWidth = $stickerWidth - $leftMargin - $rightMargin;
$textWidth = $pdf->GetStringWidth((string) $textValue);
// start x = left margin + half of the leftover space
$x = $leftMargin + (($usableWidth - $textWidth) / 2);
// if text is wider than the usable area, don't go past the left margin
if ($textWidth > $usableWidth) {
$x = $leftMargin;
}
}
}
$pdf->Text($x, $y, (string) $textValue);
}
elseif ($element['type'] == 'qr') {
$qrValue = $element['value'];
if ($qrValue == '__DYNAMIC_QR__') {
$qrValue = $qrContent;
}
$pdf->write2DBarcode(
$qrValue,
'QRCODE,H',
$element['x'],
$element['y'] + $currentY,
$element['size'],
$element['size']
);
}
elseif ($element['type'] == 'image') {
if (!empty($element['path']) && file_exists($element['path']))
{
$pdf->Image(
$element['path'],
$element['x'],
$element['y'] + $currentY,
$element['width'],
$element['height']
);
}
}
elseif ($element['type'] == 'shape') {
$rgb = $this->hexToRgb(
$element['color']
);
$pdf->SetDrawColor(
$rgb[0],
$rgb[1],
$rgb[2]
);
$pdf->SetLineWidth(
$element['pen_size']
);
if ($element['name'] == 'Line') {
$pdf->Line(
$element['x1'],
$element['y1'] + $currentY,
$element['x2'],
$element['y2'] + $currentY
);
}
elseif ($element['name'] == 'Rectangle') {
$x = min($element['x1'],$element['x2']);
$y = min($element['y1'],$element['y2']);
$width = abs($element['x2'] - $element['x1']);
$height = abs($element['y2'] - $element['y1']);
$pdf->Rect(
$x,
$y + $currentY,
$width,
$height,
'D'
);
}
elseif ($element['name'] == 'CurvedRectangle')
{
$x = min($element['x1'],$element['x2']);
$y = min($element['y1'],$element['y2']);
$width = abs($element['x2'] - $element['x1']);
$height = abs($element['y2'] - $element['y1']);
$pdf->RoundedRect(
$x,
$y + $currentY,
$width,
$height,
$element['radius'],
'1111',
'D'
);
}
}
}
// $currentY += $stickerHeight + $gap;
}
return $pdf->Output('', 'S');
}
// if($stickerId == 'SelfPriming Monoblock Pump Dual'){
// foreach ($serialNumbersArray as $serial) {
// $serial = (string) $serial;
// $pdf->AddPage();
// $serialString = (string) $serial;
// $serialDate = '';
// $firstSerial = $serial;
// $secondSerial = $serial + 1;
// $serialString = (string) $firstSerial;
// $serialDate = '';
// if (strlen($serialString) >= 4) {
// $year = substr($serialString, 0, 2);
// $month = substr($serialString, 2, 2);
// if ((int) $month >= 1 && (int) $month <= 12) {
// $serialDate = \Carbon\Carbon::createFromFormat(
// 'y-m',
// $year . '-' . $month
// )->format('M-y');
// }
// }
// foreach ($template['elements'] as $element) {
// if ($element['type'] == 'text') {
// $textValue = $element['value'];
// if ($textValue == '__SERIAL_NUMBER__') {
// $textValue = (string) $firstSerial;
// }
// if ($textValue == 'TO__SERIAL_NUMBER__') {
// if ($secondSerial <= $toSerial) {
// $textValue = (string) $secondSerial;
// } else {
// $textValue = '';
// }
// }
// if ($textValue == '__CURRENT_DATE__') {
// $textValue = $serialDate;
// }
// $pdf->SetFont(
// $element['font'],
// '',
// $element['size']
// );
// $rgb = $this->hexToRgb($element['color']);
// $pdf->SetTextColor(
// $rgb[0],
// $rgb[1],
// $rgb[2]
// );
// $pdf->Text(
// $element['x'],
// $element['y'] + $currentY,
// (string) $textValue
// );
// }
// elseif ($element['type'] == 'qr') {
// $qrValue = $element['value'];
// if ($qrValue == '__DYNAMIC_QR__') {
// $qrValue = $itemCode . '|' . $firstSerial;
// }
// elseif ($qrValue == '__DYNAMIC_QR2__') {
// if ($secondSerial <= $toSerial) {
// $qrValue = $itemCode . '|' . $secondSerial;
// } else {
// $qrValue = '';
// }
// }
// if ($qrValue != '') {
// $pdf->write2DBarcode(
// $qrValue,
// 'QRCODE,H',
// $element['x'],
// $element['y'] + $currentY,
// $element['size'],
// $element['size']
// );
// }
// }
// elseif ($element['type'] == 'image') {
// if (
// !empty($element['path']) &&
// file_exists($element['path'])
// ) {
// $pdf->Image(
// $element['path'],
// $element['x'],
// $element['y'] + $currentY,
// $element['width'],
// $element['height']
// );
// }
// }
// elseif ($element['type'] == 'shape') {
// $rgb = $this->hexToRgb($element['color']);
// $pdf->SetDrawColor(
// $rgb[0],
// $rgb[1],
// $rgb[2]
// );
// $pdf->SetLineWidth(
// $element['pen_size']
// );
// if ($element['name'] == 'Line') {
// $pdf->Line(
// $element['x1'],
// $element['y1'] + $currentY,
// $element['x2'],
// $element['y2'] + $currentY
// );
// }
// elseif ($element['name'] == 'Rectangle') {
// $x = min(
// $element['x1'],
// $element['x2']
// );
// $y = min(
// $element['y1'],
// $element['y2']
// );
// $width = abs(
// $element['x2'] - $element['x1']
// );
// $height = abs(
// $element['y2'] - $element['y1']
// );
// $pdf->Rect(
// $x,
// $y + $currentY,
// $width,
// $height,
// 'D'
// );
// }
// elseif ($element['name'] == 'CurvedRectangle') {
// $x = min(
// $element['x1'],
// $element['x2']
// );
// $y = min(
// $element['y1'],
// $element['y2']
// );
// $width = abs(
// $element['x2'] - $element['x1']
// );
// $height = abs(
// $element['y2'] - $element['y1']
// );
// $pdf->RoundedRect(
// $x,
// $y + $currentY,
// $width,
// $height,
// $element['radius'],
// '1111',
// 'D'
// );
// }
// }
// }
// }
// return $pdf->Output('', 'S');
// }
}
public function generatePdfBySerial($item, $serNo, $plantId, $refNumber)
{
$recFound = ProductionQuantity::where('plant_id', $plantId)

View File

@@ -7,7 +7,7 @@
"license": "MIT",
"require": {
"php": "^8.2",
"alperenersoy/filament-export": "^5.0",
"alperenersoy/filament-export": "^3.0",
"althinect/filament-spatie-roles-permissions": "^2.3",
"diogogpinto/filament-auth-ui-enhancer": "^1.0",
"erag/laravel-pwa": "^1.9",

View File

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

View File

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

View File

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

View File

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

View File

@@ -0,0 +1,241 @@
<?php
use Illuminate\Database\Migrations\Migration;
use Illuminate\Database\Schema\Blueprint;
use Illuminate\Support\Facades\Schema;
return new class extends Migration
{
/**
* Run the migrations.
*/
public function up(): void
{
$sql1 = <<<'SQL'
ALTER TABLE production_plans
ADD COLUMN day_1 TEXT DEFAULT NULL
SQL;
DB::statement($sql1);
$sql2 = <<<'SQL'
ALTER TABLE production_plans
ADD COLUMN day_2 TEXT DEFAULT NULL
SQL;
DB::statement($sql2);
$sql3 = <<<'SQL'
ALTER TABLE production_plans
ADD COLUMN day_3 TEXT DEFAULT NULL
SQL;
DB::statement($sql3);
$sql4 = <<<'SQL'
ALTER TABLE production_plans
ADD COLUMN day_4 TEXT DEFAULT NULL
SQL;
DB::statement($sql4);
$sql5 = <<<'SQL'
ALTER TABLE production_plans
ADD COLUMN day_5 TEXT DEFAULT NULL
SQL;
DB::statement($sql5);
$sql6 = <<<'SQL'
ALTER TABLE production_plans
ADD COLUMN day_6 TEXT DEFAULT NULL
SQL;
DB::statement($sql6);
$sql7 = <<<'SQL'
ALTER TABLE production_plans
ADD COLUMN day_7 TEXT DEFAULT NULL
SQL;
DB::statement($sql7);
$sql8 = <<<'SQL'
ALTER TABLE production_plans
ADD COLUMN day_8 TEXT DEFAULT NULL
SQL;
DB::statement($sql8);
$sql9 = <<<'SQL'
ALTER TABLE production_plans
ADD COLUMN day_9 TEXT DEFAULT NULL
SQL;
DB::statement($sql9);
$sql10 = <<<'SQL'
ALTER TABLE production_plans
ADD COLUMN day_10 TEXT DEFAULT NULL
SQL;
DB::statement($sql10);
$sql11 = <<<'SQL'
ALTER TABLE production_plans
ADD COLUMN day_11 TEXT DEFAULT NULL
SQL;
DB::statement($sql11);
$sql12 = <<<'SQL'
ALTER TABLE production_plans
ADD COLUMN day_12 TEXT DEFAULT NULL
SQL;
DB::statement($sql12);
$sql13 = <<<'SQL'
ALTER TABLE production_plans
ADD COLUMN day_13 TEXT DEFAULT NULL
SQL;
DB::statement($sql13);
$sql14 = <<<'SQL'
ALTER TABLE production_plans
ADD COLUMN day_14 TEXT DEFAULT NULL
SQL;
DB::statement($sql14);
$sql15 = <<<'SQL'
ALTER TABLE production_plans
ADD COLUMN day_15 TEXT DEFAULT NULL
SQL;
DB::statement($sql15);
$sql16 = <<<'SQL'
ALTER TABLE production_plans
ADD COLUMN day_16 TEXT DEFAULT NULL
SQL;
DB::statement($sql16);
$sql17 = <<<'SQL'
ALTER TABLE production_plans
ADD COLUMN day_17 TEXT DEFAULT NULL
SQL;
DB::statement($sql17);
$sql18 = <<<'SQL'
ALTER TABLE production_plans
ADD COLUMN day_18 TEXT DEFAULT NULL
SQL;
DB::statement($sql18);
$sql19 = <<<'SQL'
ALTER TABLE production_plans
ADD COLUMN day_19 TEXT DEFAULT NULL
SQL;
DB::statement($sql19);
$sql20 = <<<'SQL'
ALTER TABLE production_plans
ADD COLUMN day_20 TEXT DEFAULT NULL
SQL;
DB::statement($sql20);
$sql21 = <<<'SQL'
ALTER TABLE production_plans
ADD COLUMN day_21 TEXT DEFAULT NULL
SQL;
DB::statement($sql21);
$sql22 = <<<'SQL'
ALTER TABLE production_plans
ADD COLUMN day_22 TEXT DEFAULT NULL
SQL;
DB::statement($sql22);
$sql23 = <<<'SQL'
ALTER TABLE production_plans
ADD COLUMN day_23 TEXT DEFAULT NULL
SQL;
DB::statement($sql23);
$sql24 = <<<'SQL'
ALTER TABLE production_plans
ADD COLUMN day_24 TEXT DEFAULT NULL
SQL;
DB::statement($sql24);
$sql25 = <<<'SQL'
ALTER TABLE production_plans
ADD COLUMN day_25 TEXT DEFAULT NULL
SQL;
DB::statement($sql25);
$sql26 = <<<'SQL'
ALTER TABLE production_plans
ADD COLUMN day_26 TEXT DEFAULT NULL
SQL;
DB::statement($sql26);
$sql27 = <<<'SQL'
ALTER TABLE production_plans
ADD COLUMN day_27 TEXT DEFAULT NULL
SQL;
DB::statement($sql27);
$sql28 = <<<'SQL'
ALTER TABLE production_plans
ADD COLUMN day_28 TEXT DEFAULT NULL
SQL;
DB::statement($sql28);
$sql29 = <<<'SQL'
ALTER TABLE production_plans
ADD COLUMN day_29 TEXT DEFAULT NULL
SQL;
DB::statement($sql29);
$sql30 = <<<'SQL'
ALTER TABLE production_plans
ADD COLUMN day_30 TEXT DEFAULT NULL
SQL;
DB::statement($sql30);
$sql31 = <<<'SQL'
ALTER TABLE production_plans
ADD COLUMN day_31 TEXT DEFAULT NULL
SQL;
DB::statement($sql31);
}
/**
* Reverse the migrations.
*/
public function down(): void
{
// Schema::table('production_plans', function (Blueprint $table) {
// //
// });
}
};

View File

@@ -0,0 +1,49 @@
<?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 testing_line_visualizations (
id BIGINT GENERATED always AS IDENTITY PRIMARY KEY,
plant_id BIGINT NOT NULL,
test_bed_group TEXT DEFAULT NULL,
line_no TEXT DEFAULT NULL,
pump_model TEXT DEFAULT NULL,
pump_type TEXT DEFAULT NULL,
motor_details TEXT DEFAULT NULL,
test_type TEXT DEFAULT NULL,
flow TEXT DEFAULT '0',
head TEXT DEFAULT '0',
run_time TEXT DEFAULT '0.0',
live_status TEXT DEFAULT NULL,
observation_remarks 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,
-- UNIQUE (plant_id, machine_name),
FOREIGN KEY (plant_id) REFERENCES plants (id)
);
SQL;
DB::statement($sql);
}
/**
* Reverse the migrations.
*/
public function down(): void
{
Schema::dropIfExists('testing_line_visualizations');
}
};

View File

@@ -0,0 +1,47 @@
<?php
use Illuminate\Database\Migrations\Migration;
use Illuminate\Database\Schema\Blueprint;
use Illuminate\Support\Facades\Schema;
return new class extends Migration
{
/**
* Run the migrations.
*/
public function up(): void
{
$sql = <<<'SQL'
CREATE TABLE courier_inwards (
id BIGINT GENERATED always AS IDENTITY PRIMARY KEY,
plant_id BIGINT NOT NULL,
date DATE NULL,
from_address_name TEXT DEFAULT NULL,
cover_material TEXT DEFAULT NULL,
pod_number TEXT DEFAULT NULL,
courier_name TEXT DEFAULT NULL,
place TEXT DEFAULT NULL,
to_address_name TEXT DEFAULT NULL,
return_to_other_unit 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('courier_inwards');
}
};

View File

@@ -0,0 +1,46 @@
<?php
use Illuminate\Database\Migrations\Migration;
use Illuminate\Database\Schema\Blueprint;
use Illuminate\Support\Facades\Schema;
return new class extends Migration
{
/**
* Run the migrations.
*/
public function up(): void
{
$sql = <<<'SQL'
CREATE TABLE courier_outwards (
id BIGINT GENERATED always AS IDENTITY PRIMARY KEY,
plant_id BIGINT NOT NULL,
date DATE NULL,
to_address TEXT DEFAULT NULL,
cover_material TEXT DEFAULT NULL,
name_of_sender TEXT DEFAULT NULL,
place_pincode TEXT DEFAULT NULL,
pod_number TEXT DEFAULT NULL,
remark 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('courier_outwards');
}
};

View File

@@ -0,0 +1,41 @@
<?php
use Illuminate\Database\Migrations\Migration;
use Illuminate\Database\Schema\Blueprint;
use Illuminate\Support\Facades\Schema;
return new class extends Migration
{
/**
* Run the migrations.
*/
public function up(): void
{
$sql = <<<'SQL'
CREATE TABLE production_calendars (
id BIGINT GENERATED always AS IDENTITY PRIMARY KEY,
plant_id BIGINT NOT NULL,
working_days TEXT DEFAULT NULL,
leave_dates 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('production_calendars');
}
};

View File

@@ -0,0 +1,32 @@
<?php
use Illuminate\Database\Migrations\Migration;
use Illuminate\Database\Schema\Blueprint;
use Illuminate\Support\Facades\Schema;
return new class extends Migration
{
/**
* Run the migrations.
*/
public function up(): void
{
$sql = <<<'SQL'
ALTER TABLE gr_masters
ADD CONSTRAINT gr_masters_plant_id_gr_number_key
UNIQUE (plant_id, gr_number)
SQL;
DB::statement($sql);
}
/**
* Reverse the migrations.
*/
public function down(): void
{
// Schema::table('gr_masters', function (Blueprint $table) {
// //
// });
}
};

View File

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

View File

@@ -281,6 +281,14 @@ class PermissionSeeder extends Seeder
Permission::updateOrCreate(['name' => 'view export test approval mapping']);
Permission::updateOrCreate(['name' => 'view production non planned page']);
Permission::updateOrCreate(['name' => 'view production plan target page']);
Permission::updateOrCreate(['name' => 'view import courier inward']);
Permission::updateOrCreate(['name' => 'view export courier inward']);
Permission::updateOrCreate(['name' => 'view import courier outward']);
Permission::updateOrCreate(['name' => 'view export courier outward']);
}
}

View File

@@ -18,7 +18,25 @@
>
Generate Sticker
</button>
</div>
</div>
{{-- <label class="flex items-center gap-2 mt-4">
<input
type="checkbox"
wire:model="showMultipleSerials"
class="rounded border-gray-300 text-primary-600 focus:ring-primary-500"
>
<span class="text-sm font-medium">Show Multiple Serial Numbers</span>
</label> --}}
{{-- <div class="bg-white shadow rounded-xl p-4 mt-6">
<livewire:random-serial-number-list />
</div> --}}
<div class="bg-white shadow rounded-xl p-4 mt-6">
<livewire:random-serial-number-list
:plant-id="$filters['plant_id'] ?? null"
:machine-id="$filters['machine_id'] ?? null"
/>
</div>
{{-- <script>
document.addEventListener('livewire:init', () => {

View File

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

Some files were not shown because too many files have changed in this diff Show More