167 Commits

Author SHA1 Message Date
addcffb508 Merge pull request 'Added permiisons for cycle count page and export asn invoice' (#521) from ranjith-dev into master
Some checks are pending
Scan for leaked secrets using Kingfisher / kingfisher-secrets-scan (push) Waiting to run
Reviewed-on: #521
2026-04-11 10:58:19 +00:00
dhanabalan
745ecbeee1 Added permiisons for cycle count page and export asn invoice
Some checks are pending
Scan for leaked secrets using Kingfisher / kingfisher-secrets-scan (push) Waiting to run
Gemini PR Review / Gemini PR Review (pull_request) Waiting to run
Scan for leaked secrets using Kingfisher / kingfisher-secrets-scan (pull_request) Waiting to run
Laravel Larastan / larastan (pull_request) Waiting to run
Laravel Pint / pint (pull_request) Waiting to run
2026-04-11 16:28:02 +05:30
63a73b3202 Merge pull request 'solved issue for opening only asn invoice' (#520) from ranjith-dev into master
Some checks failed
Scan for leaked secrets using Kingfisher / kingfisher-secrets-scan (push) Has been cancelled
Reviewed-on: #520
2026-04-11 10:52:15 +00:00
dhanabalan
3547f437f7 solved issue for opening only asn invoice
Some checks failed
Gemini PR Review / Gemini PR Review (pull_request) Waiting to run
Scan for leaked secrets using Kingfisher / kingfisher-secrets-scan (pull_request) Waiting to run
Laravel Larastan / larastan (pull_request) Waiting to run
Laravel Pint / pint (pull_request) Waiting to run
Scan for leaked secrets using Kingfisher / kingfisher-secrets-scan (push) Has been cancelled
2026-04-11 16:22:03 +05:30
0d1ad08e93 Merge pull request 'Removed export asn invoice' (#519) from ranjith-dev into master
Some checks failed
Scan for leaked secrets using Kingfisher / kingfisher-secrets-scan (push) Has been cancelled
Reviewed-on: #519
2026-04-11 10:44:08 +00:00
dhanabalan
eb33c57973 Removed export asn invoice
Some checks failed
Gemini PR Review / Gemini PR Review (pull_request) Waiting to run
Scan for leaked secrets using Kingfisher / kingfisher-secrets-scan (pull_request) Waiting to run
Laravel Larastan / larastan (pull_request) Waiting to run
Laravel Pint / pint (pull_request) Waiting to run
Scan for leaked secrets using Kingfisher / kingfisher-secrets-scan (push) Has been cancelled
2026-04-11 16:13:53 +05:30
6320d01c55 Merge pull request 'Added axn export page in invoice validation resource page' (#518) from ranjith-dev into master
Some checks failed
Scan for leaked secrets using Kingfisher / kingfisher-secrets-scan (push) Has been cancelled
Reviewed-on: #518
2026-04-11 06:27:38 +00:00
dhanabalan
34821d6a89 Added axn export page in invoice validation resource page
Some checks failed
Gemini PR Review / Gemini PR Review (pull_request) Waiting to run
Scan for leaked secrets using Kingfisher / kingfisher-secrets-scan (pull_request) Waiting to run
Laravel Larastan / larastan (pull_request) Waiting to run
Laravel Pint / pint (pull_request) Waiting to run
Scan for leaked secrets using Kingfisher / kingfisher-secrets-scan (push) Has been cancelled
2026-04-11 11:57:24 +05:30
30807d9124 Merge pull request 'Changed msg in welcome page' (#517) from ranjith-dev into master
Some checks failed
Scan for leaked secrets using Kingfisher / kingfisher-secrets-scan (push) Has been cancelled
Reviewed-on: #517
2026-04-11 04:25:03 +00:00
dhanabalan
97af15e148 Changed msg in welcome page
Some checks failed
Gemini PR Review / Gemini PR Review (pull_request) Waiting to run
Scan for leaked secrets using Kingfisher / kingfisher-secrets-scan (pull_request) Waiting to run
Laravel Larastan / larastan (pull_request) Waiting to run
Laravel Pint / pint (pull_request) Waiting to run
Scan for leaked secrets using Kingfisher / kingfisher-secrets-scan (push) Has been cancelled
2026-04-11 09:54:45 +05:30
ceab83ceda Merge pull request 'Refactored alignments and updated validation logic on resource / importer / exporter pages' (#516) from ranjith-dev into master
Some checks failed
Scan for leaked secrets using Kingfisher / kingfisher-secrets-scan (push) Has been cancelled
Reviewed-on: #516
2026-04-09 07:27:40 +00:00
dhanabalan
3fbb2be254 Refactored alignments and updated validation logic on resource / importer / exporter pages
Some checks failed
Scan for leaked secrets using Kingfisher / kingfisher-secrets-scan (push) Has been cancelled
Gemini PR Review / Gemini PR Review (pull_request) Has been cancelled
Scan for leaked secrets using Kingfisher / kingfisher-secrets-scan (pull_request) Has been cancelled
Laravel Larastan / larastan (pull_request) Has been cancelled
Laravel Pint / pint (pull_request) Has been cancelled
2026-04-09 12:56:44 +05:30
c96a278749 Merge pull request 'Removed email method from characteristic approver master resource page and added logic multiple mail in trigger pending approval mail page' (#515) from ranjith-dev into master
Some checks failed
Scan for leaked secrets using Kingfisher / kingfisher-secrets-scan (push) Has been cancelled
Reviewed-on: #515
2026-04-09 03:36:12 +00:00
dhanabalan
f5014af3ea Removed email method from characteristic approver master resource page and added logic multiple mail in trigger pending approval mail 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) Has been cancelled
Scan for leaked secrets using Kingfisher / kingfisher-secrets-scan (pull_request) Has been cancelled
Laravel Larastan / larastan (pull_request) Has been cancelled
Laravel Pint / pint (pull_request) Has been cancelled
2026-04-09 09:05:52 +05:30
2a91525b12 Merge pull request 'Updated mail_status value in proper manner in report view / export' (#514) from ranjith-dev into master
Some checks failed
Scan for leaked secrets using Kingfisher / kingfisher-secrets-scan (push) Has been cancelled
Reviewed-on: #514
2026-04-08 07:33:58 +00:00
dhanabalan
97f93c7938 Updated mail_status value in proper manner in report view / export
Some checks failed
Scan for leaked secrets using Kingfisher / kingfisher-secrets-scan (push) Has been cancelled
Gemini PR Review / Gemini PR Review (pull_request) Has been cancelled
Scan for leaked secrets using Kingfisher / kingfisher-secrets-scan (pull_request) Has been cancelled
Laravel Larastan / larastan (pull_request) Has been cancelled
Laravel Pint / pint (pull_request) Has been cancelled
2026-04-08 13:03:32 +05:30
4107844ff1 Merge pull request 'Issue solved in quality validation resource page for automatic submit' (#513) from ranjith-dev into master
Some checks failed
Scan for leaked secrets using Kingfisher / kingfisher-secrets-scan (push) Has been cancelled
Reviewed-on: #513
2026-04-08 05:09:47 +00:00
dhanabalan
1ea4928b3f Issue solved in quality validation resource page for automatic submit
Some checks failed
Scan for leaked secrets using Kingfisher / kingfisher-secrets-scan (push) Has been cancelled
Gemini PR Review / Gemini PR Review (pull_request) Has been cancelled
Scan for leaked secrets using Kingfisher / kingfisher-secrets-scan (pull_request) Has been cancelled
Laravel Larastan / larastan (pull_request) Has been cancelled
Laravel Pint / pint (pull_request) Has been cancelled
2026-04-08 10:39:33 +05:30
87e3b1f35f Merge pull request 'Added production characteristics models in all related model files' (#512) from ranjith-dev into master
Some checks failed
Scan for leaked secrets using Kingfisher / kingfisher-secrets-scan (push) Has been cancelled
Reviewed-on: #512
2026-04-07 17:26:25 +00:00
dhanabalan
360ea0b437 Added production characteristics models in all related model files
Some checks failed
Scan for leaked secrets using Kingfisher / kingfisher-secrets-scan (push) Has been cancelled
Gemini PR Review / Gemini PR Review (pull_request) Has been cancelled
Scan for leaked secrets using Kingfisher / kingfisher-secrets-scan (pull_request) Has been cancelled
Laravel Larastan / larastan (pull_request) Has been cancelled
Laravel Pint / pint (pull_request) Has been cancelled
2026-04-07 22:56:14 +05:30
a3251cfade Merge pull request 'Added filter in production characteristics resource page' (#511) from ranjith-dev into master
Some checks failed
Scan for leaked secrets using Kingfisher / kingfisher-secrets-scan (push) Has been cancelled
Reviewed-on: #511
2026-04-07 17:25:12 +00:00
dhanabalan
7cfa2dae07 Added filter in production characteristics 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) Has been cancelled
Scan for leaked secrets using Kingfisher / kingfisher-secrets-scan (pull_request) Has been cancelled
Laravel Larastan / larastan (pull_request) Has been cancelled
Laravel Pint / pint (pull_request) Has been cancelled
2026-04-07 22:54:59 +05:30
36f0bc81ef Merge pull request 'Added final inspection status for the not ok serial number and added Expected scanned part number for all part validations' (#510) from ranjith-dev into master
Some checks failed
Scan for leaked secrets using Kingfisher / kingfisher-secrets-scan (push) Has been cancelled
Reviewed-on: #510
2026-04-07 12:12:34 +00:00
dhanabalan
98c53c25a3 Added final inspection status for the not ok serial number and added Expected scanned part number for all part validations
Some checks failed
Scan for leaked secrets using Kingfisher / kingfisher-secrets-scan (push) Has been cancelled
Gemini PR Review / Gemini PR Review (pull_request) Has been cancelled
Scan for leaked secrets using Kingfisher / kingfisher-secrets-scan (pull_request) Has been cancelled
Laravel Larastan / larastan (pull_request) Has been cancelled
Laravel Pint / pint (pull_request) Has been cancelled
2026-04-07 17:42:22 +05:30
9b5ed2b517 Merge pull request 'Added new validation characteristics form in pop up and updating data in production characteristics' (#509) from ranjith-dev into master
Some checks failed
Scan for leaked secrets using Kingfisher / kingfisher-secrets-scan (push) Has been cancelled
Reviewed-on: #509
2026-04-07 12:11:02 +00:00
dhanabalan
5c3fd2bb04 Added new validation characteristics form in pop up and updating data in production characteristics
Some checks failed
Scan for leaked secrets using Kingfisher / kingfisher-secrets-scan (push) Has been cancelled
Gemini PR Review / Gemini PR Review (pull_request) Has been cancelled
Scan for leaked secrets using Kingfisher / kingfisher-secrets-scan (pull_request) Has been cancelled
Laravel Larastan / larastan (pull_request) Has been cancelled
Laravel Pint / pint (pull_request) Has been cancelled
2026-04-07 17:40:48 +05:30
13eda35965 Merge pull request 'Added production checklist blade file in components' (#508) from ranjith-dev into master
Some checks failed
Scan for leaked secrets using Kingfisher / kingfisher-secrets-scan (push) Has been cancelled
Reviewed-on: #508
2026-04-07 12:07:13 +00:00
dhanabalan
80c9ca827f Added production checklist blade file in components
Some checks failed
Scan for leaked secrets using Kingfisher / kingfisher-secrets-scan (push) Has been cancelled
Gemini PR Review / Gemini PR Review (pull_request) Has been cancelled
Scan for leaked secrets using Kingfisher / kingfisher-secrets-scan (pull_request) Has been cancelled
Laravel Larastan / larastan (pull_request) Has been cancelled
Laravel Pint / pint (pull_request) Has been cancelled
2026-04-07 17:37:02 +05:30
8b0054cca1 Merge pull request 'Added production checklist livewire pages' (#507) from ranjith-dev into master
Some checks failed
Scan for leaked secrets using Kingfisher / kingfisher-secrets-scan (push) Has been cancelled
Reviewed-on: #507
2026-04-07 12:06:04 +00:00
dhanabalan
d1c4d7a3bc Added production checklist livewire pages
Some checks failed
Scan for leaked secrets using Kingfisher / kingfisher-secrets-scan (push) Has been cancelled
Gemini PR Review / Gemini PR Review (pull_request) Has been cancelled
Scan for leaked secrets using Kingfisher / kingfisher-secrets-scan (pull_request) Has been cancelled
Laravel Larastan / larastan (pull_request) Has been cancelled
Laravel Pint / pint (pull_request) Has been cancelled
2026-04-07 17:35:47 +05:30
950ee92056 Merge pull request 'ranjith-dev' (#506) from ranjith-dev into master
Some checks failed
Scan for leaked secrets using Kingfisher / kingfisher-secrets-scan (push) Has been cancelled
Reviewed-on: #506
2026-04-07 12:01:24 +00:00
dhanabalan
fa1e88d13c Added production characteristic importer and exporter 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) Has been cancelled
Scan for leaked secrets using Kingfisher / kingfisher-secrets-scan (pull_request) Has been cancelled
Laravel Larastan / larastan (pull_request) Has been cancelled
Laravel Pint / pint (pull_request) Has been cancelled
2026-04-07 17:31:04 +05:30
dhanabalan
e607b3ff02 Added production characteristic policy file
Some checks failed
Scan for leaked secrets using Kingfisher / kingfisher-secrets-scan (push) Has been cancelled
2026-04-07 17:30:22 +05:30
dhanabalan
236c7904d3 Added production characteristics resource pages
Some checks failed
Scan for leaked secrets using Kingfisher / kingfisher-secrets-scan (push) Has been cancelled
2026-04-07 17:29:41 +05:30
dhanabalan
30cf8203ef Added production characteristics model file
Some checks failed
Scan for leaked secrets using Kingfisher / kingfisher-secrets-scan (push) Has been cancelled
2026-04-07 17:28:35 +05:30
dhanabalan
869e91c9c6 Added production characteristics migration file
Some checks failed
Scan for leaked secrets using Kingfisher / kingfisher-secrets-scan (push) Has been cancelled
2026-04-07 17:27:44 +05:30
18d264d5b3 Merge pull request 'quality issue solved for empty records in trigger mail' (#505) from ranjith-dev into master
Some checks failed
Scan for leaked secrets using Kingfisher / kingfisher-secrets-scan (push) Has been cancelled
Reviewed-on: #505
2026-04-06 10:04:37 +00:00
dhanabalan
3a6068b6b2 quality issue solved for empty records in trigger mail
Some checks failed
Scan for leaked secrets using Kingfisher / kingfisher-secrets-scan (push) Has been cancelled
Gemini PR Review / Gemini PR Review (pull_request) Has been cancelled
Scan for leaked secrets using Kingfisher / kingfisher-secrets-scan (pull_request) Has been cancelled
Laravel Larastan / larastan (pull_request) Has been cancelled
Laravel Pint / pint (pull_request) Has been cancelled
2026-04-06 15:34:16 +05:30
dcc912945b Merge pull request 'Updated validation for hasWorkFlow ID updation logic on storeLaserRequestChar and Added hasWorkFlow ID updation logic on getLaserRequestChar' (#504) from ranjith-dev into master
Some checks failed
Scan for leaked secrets using Kingfisher / kingfisher-secrets-scan (push) Has been cancelled
Reviewed-on: #504
2026-04-06 02:45:58 +00:00
dhanabalan
b41c70f94b Updated validation for hasWorkFlow ID updation logic on storeLaserRequestChar and Added hasWorkFlow ID updation logic on getLaserRequestChar
Some checks failed
Scan for leaked secrets using Kingfisher / kingfisher-secrets-scan (push) Has been cancelled
Gemini PR Review / Gemini PR Review (pull_request) Has been cancelled
Scan for leaked secrets using Kingfisher / kingfisher-secrets-scan (pull_request) Has been cancelled
Laravel Larastan / larastan (pull_request) Has been cancelled
Laravel Pint / pint (pull_request) Has been cancelled
2026-04-06 08:15:28 +05:30
c804183ae0 Merge pull request 'Updated role from Design to Laser and hasWorkFlowId updated against work flow status' (#503) from ranjith-dev into master
Some checks failed
Scan for leaked secrets using Kingfisher / kingfisher-secrets-scan (push) Has been cancelled
Reviewed-on: #503
2026-04-06 02:40:06 +00:00
dhanabalan
c33bbce950 Updated filter logic, validations and alignments
Some checks failed
Gemini PR Review / Gemini PR Review (pull_request) Has been cancelled
Scan for leaked secrets using Kingfisher / kingfisher-secrets-scan (push) Has been cancelled
Scan for leaked secrets using Kingfisher / kingfisher-secrets-scan (pull_request) Has been cancelled
Laravel Larastan / larastan (pull_request) Has been cancelled
Laravel Pint / pint (pull_request) Has been cancelled
2026-04-04 22:19:11 +05:30
dhanabalan
ff6713e1d6 Updated role from Design to Laser and hasWorkFlowId updated against work flow status
Some checks failed
Scan for leaked secrets using Kingfisher / kingfisher-secrets-scan (push) Has been cancelled
Gemini PR Review / Gemini PR Review (pull_request) Has been cancelled
Scan for leaked secrets using Kingfisher / kingfisher-secrets-scan (pull_request) Has been cancelled
Laravel Larastan / larastan (pull_request) Has been cancelled
Laravel Pint / pint (pull_request) Has been cancelled
2026-04-04 21:40:41 +05:30
4ccb57c017 Merge pull request 'Added warning message on item code not found in sticker master' (#502) from ranjith-dev into master
Some checks failed
Scan for leaked secrets using Kingfisher / kingfisher-secrets-scan (push) Has been cancelled
Reviewed-on: #502
2026-04-04 10:40:13 +00:00
dhanabalan
9b8f178bed Added warning message on item code not found in sticker master
Some checks failed
Scan for leaked secrets using Kingfisher / kingfisher-secrets-scan (push) Has been cancelled
Gemini PR Review / Gemini PR Review (pull_request) Has been cancelled
Scan for leaked secrets using Kingfisher / kingfisher-secrets-scan (pull_request) Has been cancelled
Laravel Larastan / larastan (pull_request) Has been cancelled
Laravel Pint / pint (pull_request) Has been cancelled
2026-04-04 16:09:50 +05:30
a81a8b7aea Merge pull request 'Added request characteristics in all model files' (#501) from ranjith-dev into master
Some checks failed
Scan for leaked secrets using Kingfisher / kingfisher-secrets-scan (push) Has been cancelled
Reviewed-on: #501
2026-04-04 10:04:09 +00:00
dhanabalan
3cec2f6e2b Added request characteristics in all model files
Some checks failed
Scan for leaked secrets using Kingfisher / kingfisher-secrets-scan (push) Has been cancelled
Gemini PR Review / Gemini PR Review (pull_request) Has been cancelled
Scan for leaked secrets using Kingfisher / kingfisher-secrets-scan (pull_request) Has been cancelled
Laravel Larastan / larastan (pull_request) Has been cancelled
Laravel Pint / pint (pull_request) Has been cancelled
2026-04-04 15:33:55 +05:30
66e83c26bc Merge pull request 'Added filter logic in request characteristics resource page' (#500) from ranjith-dev into master
Some checks failed
Scan for leaked secrets using Kingfisher / kingfisher-secrets-scan (push) Has been cancelled
Reviewed-on: #500
2026-04-04 10:00:40 +00:00
dhanabalan
63473a84a6 Added filter logic in request characteristics 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) Has been cancelled
Scan for leaked secrets using Kingfisher / kingfisher-secrets-scan (pull_request) Has been cancelled
Laravel Larastan / larastan (pull_request) Has been cancelled
Laravel Pint / pint (pull_request) Has been cancelled
2026-04-04 15:30:18 +05:30
8c53bffd0c Merge pull request 'ranjith-dev' (#499) from ranjith-dev into master
Some checks failed
Scan for leaked secrets using Kingfisher / kingfisher-secrets-scan (push) Has been cancelled
Reviewed-on: #499
2026-04-02 12:25:47 +00:00
dhanabalan
7223da8b1a Updated label on filter report
Some checks failed
Scan for leaked secrets using Kingfisher / kingfisher-secrets-scan (push) Has been cancelled
Gemini PR Review / Gemini PR Review (pull_request) Has been cancelled
Scan for leaked secrets using Kingfisher / kingfisher-secrets-scan (pull_request) Has been cancelled
Laravel Larastan / larastan (pull_request) Has been cancelled
Laravel Pint / pint (pull_request) Has been cancelled
2026-04-02 17:52:08 +05:30
dhanabalan
9512ff4036 Updated validation logic in resource file
Some checks failed
Scan for leaked secrets using Kingfisher / kingfisher-secrets-scan (push) Has been cancelled
2026-04-02 17:51:24 +05:30
dhanabalan
e90973ea23 Updated label and updated_by user name on edit and plant load logic updated on filter
Some checks failed
Scan for leaked secrets using Kingfisher / kingfisher-secrets-scan (push) Has been cancelled
2026-04-02 12:52:43 +05:30
dhanabalan
75b88e4b8a Commented batch id mismatch warning validation
Some checks failed
Scan for leaked secrets using Kingfisher / kingfisher-secrets-scan (push) Has been cancelled
2026-04-02 12:25:05 +05:30
dhanabalan
c8cc9e3ba0 Updated foreign key for motorTestingMasters hasMany relation on model file
Some checks failed
Scan for leaked secrets using Kingfisher / kingfisher-secrets-scan (push) Has been cancelled
2026-04-02 12:17:58 +05:30
dhanabalan
aa09e90107 Added motorTestingMasters hasMany relation on model file
Some checks failed
Scan for leaked secrets using Kingfisher / kingfisher-secrets-scan (push) Has been cancelled
2026-04-02 12:15:53 +05:30
dhanabalan
43694dc5de Added unique validation on resource file
Some checks failed
Scan for leaked secrets using Kingfisher / kingfisher-secrets-scan (push) Has been cancelled
2026-04-02 12:10:04 +05:30
bcb74d619f Merge pull request 'ranjith-dev' (#498) from ranjith-dev into master
Some checks failed
Scan for leaked secrets using Kingfisher / kingfisher-secrets-scan (push) Has been cancelled
Reviewed-on: #498
2026-04-02 06:30:20 +00:00
dhanabalan
6c3c7094ce Commented required function for subassembly_code
Some checks failed
Scan for leaked secrets using Kingfisher / kingfisher-secrets-scan (push) Has been cancelled
Gemini PR Review / Gemini PR Review (pull_request) Has been cancelled
Scan for leaked secrets using Kingfisher / kingfisher-secrets-scan (pull_request) Has been cancelled
Laravel Larastan / larastan (pull_request) Has been cancelled
Laravel Pint / pint (pull_request) Has been cancelled
2026-04-02 11:57:36 +05:30
dhanabalan
ea130fab4d Updated navigation, download, upload, and delete icon on resource file
Some checks failed
Scan for leaked secrets using Kingfisher / kingfisher-secrets-scan (push) Has been cancelled
2026-04-02 10:50:25 +05:30
dhanabalan
c9794508a2 Updated navigation icon and moved into vehicle group on resource file
Some checks failed
Scan for leaked secrets using Kingfisher / kingfisher-secrets-scan (push) Has been cancelled
2026-04-02 10:25:17 +05:30
dhanabalan
0c7c16943d Updated navigation icon on resource file
Some checks failed
Scan for leaked secrets using Kingfisher / kingfisher-secrets-scan (push) Has been cancelled
2026-04-02 10:23:23 +05:30
7ef6f94f35 Merge pull request 'Added default value as '-' for foreignKey (uom) column on report view' (#497) from ranjith-dev into master
Some checks failed
Scan for leaked secrets using Kingfisher / kingfisher-secrets-scan (push) Has been cancelled
Reviewed-on: #497
2026-03-26 05:40:41 +00:00
dhanabalan
33d44b5479 Added default value as '-' for foreignKey (uom) column on report view
Some checks failed
Scan for leaked secrets using Kingfisher / kingfisher-secrets-scan (push) Has been cancelled
Gemini PR Review / Gemini PR Review (pull_request) Has been cancelled
Scan for leaked secrets using Kingfisher / kingfisher-secrets-scan (pull_request) Has been cancelled
Laravel Larastan / larastan (pull_request) Has been cancelled
Laravel Pint / pint (pull_request) Has been cancelled
2026-03-26 11:10:25 +05:30
eed8c8e7fd Merge pull request 'Added searchable method for plant_id column on resource' (#496) from ranjith-dev into master
Some checks failed
Scan for leaked secrets using Kingfisher / kingfisher-secrets-scan (push) Has been cancelled
Reviewed-on: #496
2026-03-26 05:34:27 +00:00
dhanabalan
5d0004160c Added searchable method for plant_id column on resource
Some checks failed
Scan for leaked secrets using Kingfisher / kingfisher-secrets-scan (push) Has been cancelled
Gemini PR Review / Gemini PR Review (pull_request) Has been cancelled
Scan for leaked secrets using Kingfisher / kingfisher-secrets-scan (pull_request) Has been cancelled
Laravel Larastan / larastan (pull_request) Has been cancelled
Laravel Pint / pint (pull_request) Has been cancelled
2026-03-26 11:03:50 +05:30
0b8177aa5c Merge pull request 'ranjith-dev' (#495) from ranjith-dev into master
Some checks failed
Scan for leaked secrets using Kingfisher / kingfisher-secrets-scan (push) Has been cancelled
Reviewed-on: #495
2026-03-26 05:29:29 +00:00
dhanabalan
b9be6cf10d Removed toggleable method for updated_at column in resource
Some checks failed
Scan for leaked secrets using Kingfisher / kingfisher-secrets-scan (push) Has been cancelled
Gemini PR Review / Gemini PR Review (pull_request) Has been cancelled
Scan for leaked secrets using Kingfisher / kingfisher-secrets-scan (pull_request) Has been cancelled
Laravel Larastan / larastan (pull_request) Has been cancelled
Laravel Pint / pint (pull_request) Has been cancelled
2026-03-26 10:58:20 +05:30
dhanabalan
966f72c682 Added some foreignKey columns on import / resource and filter / report view logic updated
Some checks failed
Scan for leaked secrets using Kingfisher / kingfisher-secrets-scan (push) Has been cancelled
2026-03-26 10:54:27 +05:30
5a646639c6 Merge pull request 'Commented item_id load functionality on resource page and process order import only if it has characteristics master' (#494) from ranjith-dev into master
Some checks failed
Scan for leaked secrets using Kingfisher / kingfisher-secrets-scan (push) Has been cancelled
Reviewed-on: #494
2026-03-25 08:42:18 +00:00
dhanabalan
88f1674f23 Commented item_id load functionality on resource page and process order import only if it has characteristics master
Some checks failed
Scan for leaked secrets using Kingfisher / kingfisher-secrets-scan (push) Has been cancelled
Gemini PR Review / Gemini PR Review (pull_request) Has been cancelled
Scan for leaked secrets using Kingfisher / kingfisher-secrets-scan (pull_request) Has been cancelled
Laravel Larastan / larastan (pull_request) Has been cancelled
Laravel Pint / pint (pull_request) Has been cancelled
2026-03-25 14:11:21 +05:30
3daaa26b1d Merge pull request 'ranjith-dev' (#493) from ranjith-dev into master
Some checks failed
Scan for leaked secrets using Kingfisher / kingfisher-secrets-scan (push) Has been cancelled
Reviewed-on: #493
2026-03-25 05:50:50 +00:00
dhanabalan
1c37e1bb0b Updated process order import only if it has characteristics master
Some checks failed
Scan for leaked secrets using Kingfisher / kingfisher-secrets-scan (push) Has been cancelled
Gemini PR Review / Gemini PR Review (pull_request) Has been cancelled
Scan for leaked secrets using Kingfisher / kingfisher-secrets-scan (pull_request) Has been cancelled
Laravel Larastan / larastan (pull_request) Has been cancelled
Laravel Pint / pint (pull_request) Has been cancelled
2026-03-25 11:20:05 +05:30
dhanabalan
c6fd61a9ba Updated item_id load functionality on resource page
Some checks failed
Scan for leaked secrets using Kingfisher / kingfisher-secrets-scan (push) Has been cancelled
2026-03-25 10:49:13 +05:30
2a124c2b94 Merge pull request 'Refactored alignments and updated get_motor_master method' (#492) from ranjith-dev into master
Some checks failed
Scan for leaked secrets using Kingfisher / kingfisher-secrets-scan (push) Has been cancelled
Reviewed-on: #492
2026-03-24 10:48:40 +00:00
dhanabalan
9a73751e35 Refactored alignments and updated get_motor_master method
Some checks failed
Scan for leaked secrets using Kingfisher / kingfisher-secrets-scan (push) Has been cancelled
Gemini PR Review / Gemini PR Review (pull_request) Has been cancelled
Scan for leaked secrets using Kingfisher / kingfisher-secrets-scan (pull_request) Has been cancelled
Laravel Larastan / larastan (pull_request) Has been cancelled
Laravel Pint / pint (pull_request) Has been cancelled
2026-03-24 16:18:07 +05:30
33dc97b562 Merge pull request 'Updated warning message and added update has_work_flow_id on request approval creation' (#491) from ranjith-dev into master
Some checks failed
Scan for leaked secrets using Kingfisher / kingfisher-secrets-scan (push) Has been cancelled
Reviewed-on: #491
2026-03-24 09:10:28 +00:00
dhanabalan
3de43a9495 Updated warning message and added update has_work_flow_id on request approval creation
Some checks failed
Scan for leaked secrets using Kingfisher / kingfisher-secrets-scan (push) Has been cancelled
Gemini PR Review / Gemini PR Review (pull_request) Has been cancelled
Scan for leaked secrets using Kingfisher / kingfisher-secrets-scan (pull_request) Has been cancelled
Laravel Larastan / larastan (pull_request) Has been cancelled
Laravel Pint / pint (pull_request) Has been cancelled
2026-03-24 14:39:55 +05:30
f53580b930 Merge pull request 'Removed plant select box in not in stock' (#490) from ranjith-dev into master
Some checks failed
Scan for leaked secrets using Kingfisher / kingfisher-secrets-scan (push) Has been cancelled
Reviewed-on: #490
2026-03-22 08:18:48 +00:00
dhanabalan
10081fd20e Removed plant select box in not in 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) Has been cancelled
Scan for leaked secrets using Kingfisher / kingfisher-secrets-scan (pull_request) Has been cancelled
Laravel Larastan / larastan (pull_request) Has been cancelled
Laravel Pint / pint (pull_request) Has been cancelled
2026-03-22 13:48:34 +05:30
01209efaac Merge pull request 'Added plant select box in not in stock for testing' (#489) from ranjith-dev into master
Some checks failed
Scan for leaked secrets using Kingfisher / kingfisher-secrets-scan (push) Has been cancelled
Reviewed-on: #489
2026-03-22 08:17:30 +00:00
dhanabalan
5d7b9d52f8 Added plant select box in not in stock for testing
Some checks failed
Scan for leaked secrets using Kingfisher / kingfisher-secrets-scan (push) Has been cancelled
Gemini PR Review / Gemini PR Review (pull_request) Has been cancelled
Scan for leaked secrets using Kingfisher / kingfisher-secrets-scan (pull_request) Has been cancelled
Laravel Larastan / larastan (pull_request) Has been cancelled
Laravel Pint / pint (pull_request) Has been cancelled
2026-03-22 13:47:14 +05:30
257c60e69a Merge pull request 'Changed dashboard logic as welcome page in dashboard page' (#488) from ranjith-dev into master
Some checks failed
Scan for leaked secrets using Kingfisher / kingfisher-secrets-scan (push) Has been cancelled
Reviewed-on: #488
2026-03-22 04:01:21 +00:00
dhanabalan
499fa0b2dd Changed dashboard logic as welcome page in dashboard 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) Has been cancelled
Scan for leaked secrets using Kingfisher / kingfisher-secrets-scan (pull_request) Has been cancelled
Laravel Larastan / larastan (pull_request) Has been cancelled
Laravel Pint / pint (pull_request) Has been cancelled
2026-03-22 09:31:00 +05:30
9b5468fdf7 Merge pull request 'Updated laser cloud communication logics' (#487) from ranjith-dev into master
Some checks failed
Scan for leaked secrets using Kingfisher / kingfisher-secrets-scan (push) Has been cancelled
Reviewed-on: #487
2026-03-21 10:53:20 +00:00
dhanabalan
27b5ad2cfe Updated laser cloud communication logics
Some checks failed
Scan for leaked secrets using Kingfisher / kingfisher-secrets-scan (push) Has been cancelled
Gemini PR Review / Gemini PR Review (pull_request) Has been cancelled
Scan for leaked secrets using Kingfisher / kingfisher-secrets-scan (pull_request) Has been cancelled
Laravel Larastan / larastan (pull_request) Has been cancelled
Laravel Pint / pint (pull_request) Has been cancelled
2026-03-21 16:22:44 +05:30
74cdcb89b9 Merge pull request 'Updated validation logic against machin name on resource and import page' (#486) from ranjith-dev into master
Some checks failed
Scan for leaked secrets using Kingfisher / kingfisher-secrets-scan (push) Has been cancelled
Reviewed-on: #486
2026-03-20 10:46:51 +00:00
dhanabalan
4c7bed8c63 Updated validation logic against machin name on resource and 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) Has been cancelled
Scan for leaked secrets using Kingfisher / kingfisher-secrets-scan (pull_request) Has been cancelled
Laravel Larastan / larastan (pull_request) Has been cancelled
Laravel Pint / pint (pull_request) Has been cancelled
2026-03-20 16:16:04 +05:30
60d17902a2 Merge pull request 'ranjith-dev' (#485) from ranjith-dev into master
Some checks failed
Scan for leaked secrets using Kingfisher / kingfisher-secrets-scan (push) Has been cancelled
Reviewed-on: #485
2026-03-20 08:41:30 +00:00
dhanabalan
253d319587 Added updated order quantity in importer and 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) Has been cancelled
Scan for leaked secrets using Kingfisher / kingfisher-secrets-scan (pull_request) Has been cancelled
Laravel Larastan / larastan (pull_request) Has been cancelled
Laravel Pint / pint (pull_request) Has been cancelled
2026-03-20 14:10:05 +05:30
dhanabalan
ead2edc63b Changed logic in post api of process order
Some checks failed
Scan for leaked secrets using Kingfisher / kingfisher-secrets-scan (push) Has been cancelled
2026-03-20 14:08:57 +05:30
dhanabalan
18f23ce097 Added updated order quantity in resource pages
Some checks failed
Scan for leaked secrets using Kingfisher / kingfisher-secrets-scan (push) Has been cancelled
2026-03-20 14:07:30 +05:30
6a752b81b2 Merge pull request 'ranjith-dev' (#484) from ranjith-dev into master
Some checks failed
Scan for leaked secrets using Kingfisher / kingfisher-secrets-scan (push) Has been cancelled
Reviewed-on: #484
2026-03-20 08:37:03 +00:00
dhanabalan
198b901671 Added updated order quantity in process order 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) Has been cancelled
Scan for leaked secrets using Kingfisher / kingfisher-secrets-scan (pull_request) Has been cancelled
Laravel Larastan / larastan (pull_request) Has been cancelled
Laravel Pint / pint (pull_request) Has been cancelled
2026-03-20 14:06:11 +05:30
dhanabalan
3192e32d5d Added updated order quantity column in process order table
Some checks failed
Scan for leaked secrets using Kingfisher / kingfisher-secrets-scan (push) Has been cancelled
2026-03-20 14:05:21 +05:30
44b2ff6f24 Merge pull request 'Updated marked_datetime column default value as current datetime instead of null in migration' (#483) from ranjith-dev into master
Some checks failed
Scan for leaked secrets using Kingfisher / kingfisher-secrets-scan (push) Has been cancelled
Reviewed-on: #483
2026-03-19 13:25:11 +00:00
dhanabalan
61be13c367 Updated marked_datetime column default value as current datetime instead of null in migration
Some checks failed
Scan for leaked secrets using Kingfisher / kingfisher-secrets-scan (push) Has been cancelled
Gemini PR Review / Gemini PR Review (pull_request) Has been cancelled
Scan for leaked secrets using Kingfisher / kingfisher-secrets-scan (pull_request) Has been cancelled
Laravel Larastan / larastan (pull_request) Has been cancelled
Laravel Pint / pint (pull_request) Has been cancelled
2026-03-19 18:54:34 +05:30
7a242c820c Merge pull request 'Added hasMany relationship on model files' (#482) from ranjith-dev into master
Some checks failed
Scan for leaked secrets using Kingfisher / kingfisher-secrets-scan (push) Has been cancelled
Reviewed-on: #482
2026-03-16 13:53:31 +00:00
dhanabalan
3d139c005a Added hasMany relationship on model files
Some checks failed
Scan for leaked secrets using Kingfisher / kingfisher-secrets-scan (push) Has been cancelled
Gemini PR Review / Gemini PR Review (pull_request) Has been cancelled
Scan for leaked secrets using Kingfisher / kingfisher-secrets-scan (pull_request) Has been cancelled
Laravel Larastan / larastan (pull_request) Has been cancelled
Laravel Pint / pint (pull_request) Has been cancelled
2026-03-16 19:23:09 +05:30
bc02a49b54 Merge pull request 'ranjith-dev' (#481) from ranjith-dev into master
Some checks failed
Scan for leaked secrets using Kingfisher / kingfisher-secrets-scan (push) Has been cancelled
Reviewed-on: #481
2026-03-16 13:32:16 +00:00
dhanabalan
4325f2695f Added separate get user data api for clarity
Some checks failed
Scan for leaked secrets using Kingfisher / kingfisher-secrets-scan (push) Has been cancelled
Gemini PR Review / Gemini PR Review (pull_request) Has been cancelled
Scan for leaked secrets using Kingfisher / kingfisher-secrets-scan (pull_request) Has been cancelled
Laravel Larastan / larastan (pull_request) Has been cancelled
Laravel Pint / pint (pull_request) Has been cancelled
2026-03-16 19:01:18 +05:30
dhanabalan
8eeb23e2aa Updated method name on UserController
Some checks failed
Scan for leaked secrets using Kingfisher / kingfisher-secrets-scan (push) Has been cancelled
2026-03-16 18:59:12 +05:30
aa60fc14e0 Merge pull request 'Updated received quantity exceed validation on process order resource page' (#480) from ranjith-dev into master
Some checks failed
Scan for leaked secrets using Kingfisher / kingfisher-secrets-scan (push) Has been cancelled
Reviewed-on: #480
2026-03-14 07:51:16 +00:00
dhanabalan
73611a417b Updated received quantity exceed validation on process order 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) Has been cancelled
Scan for leaked secrets using Kingfisher / kingfisher-secrets-scan (pull_request) Has been cancelled
Laravel Larastan / larastan (pull_request) Has been cancelled
Laravel Pint / pint (pull_request) Has been cancelled
2026-03-14 13:20:10 +05:30
e7a7ea063f Merge pull request 'Updated quantity exceed warning message against process order' (#479) from ranjith-dev into master
Some checks failed
Scan for leaked secrets using Kingfisher / kingfisher-secrets-scan (push) Has been cancelled
Reviewed-on: #479
2026-03-13 10:12:42 +00:00
dhanabalan
37df670eab Updated quantity exceed warning message against process order
Some checks failed
Scan for leaked secrets using Kingfisher / kingfisher-secrets-scan (push) Has been cancelled
Gemini PR Review / Gemini PR Review (pull_request) Has been cancelled
Scan for leaked secrets using Kingfisher / kingfisher-secrets-scan (pull_request) Has been cancelled
Laravel Larastan / larastan (pull_request) Has been cancelled
Laravel Pint / pint (pull_request) Has been cancelled
2026-03-13 15:42:04 +05:30
891b02b6a4 Merge pull request 'ranjith-dev' (#478) from ranjith-dev into master
Some checks failed
Scan for leaked secrets using Kingfisher / kingfisher-secrets-scan (push) Has been cancelled
Reviewed-on: #478
2026-03-13 09:25:05 +00:00
dhanabalan
58b801b8e2 Updated quantity exceed validation against process order
Some checks failed
Scan for leaked secrets using Kingfisher / kingfisher-secrets-scan (push) Has been cancelled
Gemini PR Review / Gemini PR Review (pull_request) Has been cancelled
Scan for leaked secrets using Kingfisher / kingfisher-secrets-scan (pull_request) Has been cancelled
Laravel Larastan / larastan (pull_request) Has been cancelled
Laravel Pint / pint (pull_request) Has been cancelled
2026-03-13 14:54:11 +05:30
dhanabalan
5aa2e7a871 Updated type from SFG to NON-FG on Livewire page
Some checks failed
Scan for leaked secrets using Kingfisher / kingfisher-secrets-scan (push) Has been cancelled
2026-03-13 08:50:50 +05:30
10eff34cc9 Merge pull request 'Updated process order value validation on import' (#477) from ranjith-dev into master
Some checks failed
Scan for leaked secrets using Kingfisher / kingfisher-secrets-scan (push) Has been cancelled
Reviewed-on: #477
2026-03-12 07:28:41 +00:00
dhanabalan
97fb46883f Updated process order value validation on 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) Has been cancelled
Scan for leaked secrets using Kingfisher / kingfisher-secrets-scan (pull_request) Has been cancelled
Laravel Larastan / larastan (pull_request) Has been cancelled
Laravel Pint / pint (pull_request) Has been cancelled
2026-03-12 12:58:14 +05:30
1a37dd5e49 Merge pull request 'ranjith-dev' (#476) from ranjith-dev into master
Some checks failed
Scan for leaked secrets using Kingfisher / kingfisher-secrets-scan (push) Has been cancelled
Reviewed-on: #476
2026-03-11 14:07:20 +00:00
dhanabalan
e20892cc83 Refactored alignments on 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) Has been cancelled
Scan for leaked secrets using Kingfisher / kingfisher-secrets-scan (pull_request) Has been cancelled
Laravel Larastan / larastan (pull_request) Has been cancelled
Laravel Pint / pint (pull_request) Has been cancelled
2026-03-11 19:36:48 +05:30
dhanabalan
658db00ac8 Refactored alignments and updated type from SFG to NON-FG on resource / importer / exporter pages
Some checks failed
Scan for leaked secrets using Kingfisher / kingfisher-secrets-scan (push) Has been cancelled
Gemini PR Review / Gemini PR Review (pull_request) Has been cancelled
Scan for leaked secrets using Kingfisher / kingfisher-secrets-scan (pull_request) Has been cancelled
Laravel Larastan / larastan (pull_request) Has been cancelled
Laravel Pint / pint (pull_request) Has been cancelled
2026-03-11 19:29:31 +05:30
6bdabe3e1f Merge pull request 'Commented enter event logic in cycle count page' (#474) from ranjith-dev into master
Some checks failed
Scan for leaked secrets using Kingfisher / kingfisher-secrets-scan (push) Has been cancelled
Reviewed-on: #474
2026-03-11 09:39:30 +00:00
dhanabalan
ec8bfc8296 Commented enter event logic in cycle count 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) Has been cancelled
Scan for leaked secrets using Kingfisher / kingfisher-secrets-scan (pull_request) Has been cancelled
Laravel Larastan / larastan (pull_request) Has been cancelled
Laravel Pint / pint (pull_request) Has been cancelled
2026-03-11 15:09:17 +05:30
1dba08f5da Merge pull request 'Added serila number in method confirm serila update in stock data livewire page' (#473) from ranjith-dev into master
Some checks failed
Scan for leaked secrets using Kingfisher / kingfisher-secrets-scan (push) Has been cancelled
Reviewed-on: #473
2026-03-11 07:35:45 +00:00
dhanabalan
6dff4fb77e Added serila number in method confirm serila update in stock data livewire 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) Has been cancelled
Scan for leaked secrets using Kingfisher / kingfisher-secrets-scan (pull_request) Has been cancelled
Laravel Larastan / larastan (pull_request) Has been cancelled
Laravel Pint / pint (pull_request) Has been cancelled
2026-03-11 13:05:31 +05:30
80d24b7448 Merge pull request 'Changed logic in cycle count page and added stock count in export page' (#472) from ranjith-dev into master
Some checks failed
Scan for leaked secrets using Kingfisher / kingfisher-secrets-scan (push) Has been cancelled
Reviewed-on: #472
2026-03-11 07:32:39 +00:00
dhanabalan
41d158877e Changed logic in cycle count page and added stock count in 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) Has been cancelled
Scan for leaked secrets using Kingfisher / kingfisher-secrets-scan (pull_request) Has been cancelled
Laravel Larastan / larastan (pull_request) Has been cancelled
Laravel Pint / pint (pull_request) Has been cancelled
2026-03-11 13:02:18 +05:30
db43960f43 Merge pull request 'Added unique constrain for class characteristics migration' (#471) from ranjith-dev into master
All checks were successful
Scan for leaked secrets using Kingfisher / kingfisher-secrets-scan (push) Successful in 16s
Reviewed-on: #471
2026-03-11 05:00:35 +00:00
dhanabalan
0b5b0b8dd4 Added unique constrain for class characteristics migration
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 27s
Scan for leaked secrets using Kingfisher / kingfisher-secrets-scan (pull_request) Successful in 16s
Laravel Pint / pint (pull_request) Successful in 3m49s
Laravel Larastan / larastan (pull_request) Failing after 5m2s
2026-03-11 10:29:09 +05:30
c633d78d7e Merge pull request 'ranjith-dev' (#470) from ranjith-dev into master
Some checks failed
Scan for leaked secrets using Kingfisher / kingfisher-secrets-scan (push) Has been cancelled
Reviewed-on: #470
2026-03-11 04:58:55 +00:00
dhanabalan
9c582b73a5 Added filters and duplicate confirmation in cycle count page
Some checks failed
Scan for leaked secrets using Kingfisher / kingfisher-secrets-scan (push) Successful in 12s
Scan for leaked secrets using Kingfisher / kingfisher-secrets-scan (pull_request) Successful in 12s
Gemini PR Review / Gemini PR Review (pull_request) Failing after 18s
Laravel Pint / pint (pull_request) Successful in 2m43s
Laravel Larastan / larastan (pull_request) Failing after 3m58s
2026-03-11 10:28:33 +05:30
dhanabalan
a67386f7a0 Updated alignment in device masters migration
All checks were successful
Scan for leaked secrets using Kingfisher / kingfisher-secrets-scan (push) Successful in 11s
2026-03-11 10:27:44 +05:30
31f96dd11e Merge pull request 'Added stock data masters in plant model file' (#469) from ranjith-dev into master
All checks were successful
Scan for leaked secrets using Kingfisher / kingfisher-secrets-scan (push) Successful in 16s
Reviewed-on: #469
2026-03-11 03:34:00 +00:00
dhanabalan
c8fafeb140 Added stock data masters in plant model file
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 22s
Scan for leaked secrets using Kingfisher / kingfisher-secrets-scan (pull_request) Successful in 14s
Laravel Pint / pint (pull_request) Successful in 2m35s
Laravel Larastan / larastan (pull_request) Failing after 3m50s
2026-03-11 09:03:47 +05:30
4044af92c4 Merge pull request 'Added all stock calculations in table reports of stock data master page' (#468) from ranjith-dev into master
Some checks failed
Scan for leaked secrets using Kingfisher / kingfisher-secrets-scan (push) Has been cancelled
Reviewed-on: #468
2026-03-11 03:31:38 +00:00
dhanabalan
f58044036b Added all stock calculations in table reports of stock data master page
Some checks failed
Scan for leaked secrets using Kingfisher / kingfisher-secrets-scan (push) Successful in 11s
Scan for leaked secrets using Kingfisher / kingfisher-secrets-scan (pull_request) Successful in 12s
Gemini PR Review / Gemini PR Review (pull_request) Failing after 20s
Laravel Pint / pint (pull_request) Successful in 2m58s
Laravel Larastan / larastan (pull_request) Failing after 4m30s
2026-03-11 09:01:22 +05:30
2ccf1a38e2 Merge pull request 'Added logic for sfg cycle count in cycle count page' (#467) from ranjith-dev into master
All checks were successful
Scan for leaked secrets using Kingfisher / kingfisher-secrets-scan (push) Successful in 16s
Reviewed-on: #467
2026-03-10 09:48:31 +00:00
dhanabalan
a91a4ef4f7 Added logic for sfg cycle count in cycle count page
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 12s
Gemini PR Review / Gemini PR Review (pull_request) Failing after 18s
Laravel Pint / pint (pull_request) Successful in 2m51s
Laravel Larastan / larastan (pull_request) Failing after 3m50s
2026-03-10 15:18:00 +05:30
084c041f6d Merge pull request 'Added cycle count page and stock data table livewire page' (#466) from ranjith-dev into master
All checks were successful
Scan for leaked secrets using Kingfisher / kingfisher-secrets-scan (push) Successful in 18s
Reviewed-on: #466
2026-03-10 05:24:40 +00:00
dhanabalan
363241b880 Added cycle count page and stock data table livewire page
Some checks failed
Scan for leaked secrets using Kingfisher / kingfisher-secrets-scan (push) Successful in 12s
Scan for leaked secrets using Kingfisher / kingfisher-secrets-scan (pull_request) Successful in 13s
Gemini PR Review / Gemini PR Review (pull_request) Failing after 18s
Laravel Pint / pint (pull_request) Successful in 2m42s
Laravel Larastan / larastan (pull_request) Failing after 3m31s
2026-03-10 10:54:25 +05:30
b3d39d416a Merge pull request 'Added cycle count blade file' (#465) from ranjith-dev into master
All checks were successful
Scan for leaked secrets using Kingfisher / kingfisher-secrets-scan (push) Successful in 18s
Reviewed-on: #465
2026-03-10 04:01:19 +00:00
dhanabalan
23908b1493 Added cycle count blade 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 27s
Scan for leaked secrets using Kingfisher / kingfisher-secrets-scan (pull_request) Successful in 15s
Laravel Pint / pint (pull_request) Successful in 3m36s
Laravel Larastan / larastan (pull_request) Failing after 4m37s
2026-03-10 09:30:19 +05:30
dbaadd27e3 Merge pull request 'Added stock data table livewire pages' (#464) from ranjith-dev into master
Some checks failed
Scan for leaked secrets using Kingfisher / kingfisher-secrets-scan (push) Has been cancelled
Reviewed-on: #464
2026-03-10 03:59:05 +00:00
dhanabalan
1fe0012a9b Added stock data table 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 14s
Gemini PR Review / Gemini PR Review (pull_request) Failing after 19s
Laravel Pint / pint (pull_request) Successful in 2m50s
Laravel Larastan / larastan (pull_request) Failing after 4m0s
2026-03-10 09:28:53 +05:30
313edfed0b Merge pull request 'Added cycle count page' (#463) from ranjith-dev into master
Some checks failed
Scan for leaked secrets using Kingfisher / kingfisher-secrets-scan (push) Has been cancelled
Reviewed-on: #463
2026-03-10 03:57:41 +00:00
dhanabalan
2efa172e36 Added cycle count 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 26s
Scan for leaked secrets using Kingfisher / kingfisher-secrets-scan (pull_request) Successful in 15s
Laravel Larastan / larastan (pull_request) Failing after 3m30s
Laravel Pint / pint (pull_request) Successful in 3m9s
2026-03-10 09:27:25 +05:30
a5d4c12348 Merge pull request 'Added duplicate stock policy file' (#462) from ranjith-dev into master
Some checks failed
Scan for leaked secrets using Kingfisher / kingfisher-secrets-scan (push) Has been cancelled
Reviewed-on: #462
2026-03-10 03:54:49 +00:00
dhanabalan
a72f03b496 Added duplicate stock policy 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 25s
Scan for leaked secrets using Kingfisher / kingfisher-secrets-scan (pull_request) Successful in 13s
Laravel Pint / pint (pull_request) Successful in 2m17s
Laravel Larastan / larastan (pull_request) Failing after 3m30s
2026-03-10 09:24:30 +05:30
23cdc04a09 Merge pull request 'Added duplicate stock resource pages' (#461) from ranjith-dev into master
Some checks failed
Scan for leaked secrets using Kingfisher / kingfisher-secrets-scan (push) Has been cancelled
Reviewed-on: #461
2026-03-10 03:53:47 +00:00
dhanabalan
33ef93a23f Added duplicate stock resource 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 12s
Gemini PR Review / Gemini PR Review (pull_request) Failing after 17s
Laravel Pint / pint (pull_request) Successful in 2m48s
Laravel Larastan / larastan (pull_request) Failing after 3m42s
2026-03-10 09:23:14 +05:30
fb5f69df5f Merge pull request 'Added duplicate stock model file' (#460) from ranjith-dev into master
Some checks failed
Scan for leaked secrets using Kingfisher / kingfisher-secrets-scan (push) Has been cancelled
Reviewed-on: #460
2026-03-10 03:52:15 +00:00
dhanabalan
66a7406ee3 Added duplicate stock 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 24s
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 3m21s
2026-03-10 09:22:02 +05:30
7ec3e5e9f7 Merge pull request 'Added duplicate stock migration file' (#459) from ranjith-dev into master
Some checks failed
Scan for leaked secrets using Kingfisher / kingfisher-secrets-scan (push) Has been cancelled
Reviewed-on: #459
2026-03-10 03:51:32 +00:00
dhanabalan
392a563561 Added duplicate stock migration file
Some checks failed
Scan for leaked secrets using Kingfisher / kingfisher-secrets-scan (push) Has been cancelled
Scan for leaked secrets using Kingfisher / kingfisher-secrets-scan (pull_request) Successful in 12s
Gemini PR Review / Gemini PR Review (pull_request) Failing after 18s
Laravel Pint / pint (pull_request) Successful in 2m57s
Laravel Larastan / larastan (pull_request) Failing after 4m15s
2026-03-10 09:21:20 +05:30
c7239b02f2 Merge pull request 'Added scanned quantity in stock master and not in stock resource page' (#458) from ranjith-dev into master
Some checks failed
Scan for leaked secrets using Kingfisher / kingfisher-secrets-scan (push) Has been cancelled
Reviewed-on: #458
2026-03-10 03:49:57 +00:00
dhanabalan
ed9d53b0ae Added scanned quantity in stock master and not in stock 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 24s
Scan for leaked secrets using Kingfisher / kingfisher-secrets-scan (pull_request) Successful in 16s
Laravel Pint / pint (pull_request) Successful in 3m7s
Laravel Larastan / larastan (pull_request) Failing after 3m39s
2026-03-10 09:19:39 +05:30
f61e452f33 Merge pull request 'Added not in stock policy file' (#457) from ranjith-dev into master
Some checks failed
Scan for leaked secrets using Kingfisher / kingfisher-secrets-scan (push) Has been cancelled
Reviewed-on: #457
2026-03-10 03:44:52 +00:00
dhanabalan
4fa6d485da Added not in stock policy 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 26s
Scan for leaked secrets using Kingfisher / kingfisher-secrets-scan (pull_request) Successful in 14s
Laravel Pint / pint (pull_request) Successful in 2m15s
Laravel Larastan / larastan (pull_request) Failing after 3m28s
2026-03-10 09:14:37 +05:30
54f5a3b386 Merge pull request 'Added not in stock resource pages' (#456) from ranjith-dev into master
Some checks failed
Scan for leaked secrets using Kingfisher / kingfisher-secrets-scan (push) Has been cancelled
Reviewed-on: #456
2026-03-10 03:43:14 +00:00
dhanabalan
7e49872760 Added not in stock resource pages
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 23s
Scan for leaked secrets using Kingfisher / kingfisher-secrets-scan (pull_request) Successful in 16s
Laravel Pint / pint (pull_request) Successful in 2m40s
Laravel Larastan / larastan (pull_request) Failing after 4m0s
2026-03-10 09:12:47 +05:30
ebc4ba672a Merge pull request 'Added not in stock model file' (#455) from ranjith-dev into master
Some checks failed
Scan for leaked secrets using Kingfisher / kingfisher-secrets-scan (push) Has been cancelled
Reviewed-on: #455
2026-03-10 03:41:47 +00:00
dhanabalan
e3a60b276c Added not in stock 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 21s
Scan for leaked secrets using Kingfisher / kingfisher-secrets-scan (pull_request) Successful in 17s
Laravel Pint / pint (pull_request) Successful in 2m17s
Laravel Larastan / larastan (pull_request) Failing after 4m9s
2026-03-10 09:11:33 +05:30
68a75b2677 Merge pull request 'Added not in stock migration file' (#454) from ranjith-dev into master
Some checks failed
Scan for leaked secrets using Kingfisher / kingfisher-secrets-scan (push) Has been cancelled
Reviewed-on: #454
2026-03-10 03:40:55 +00:00
dhanabalan
8764ebcbee Added not in stock migration file
Some checks failed
Scan for leaked secrets using Kingfisher / kingfisher-secrets-scan (push) Has been cancelled
Scan for leaked secrets using Kingfisher / kingfisher-secrets-scan (pull_request) Successful in 14s
Gemini PR Review / Gemini PR Review (pull_request) Failing after 19s
Laravel Pint / pint (pull_request) Successful in 2m17s
Laravel Larastan / larastan (pull_request) Failing after 3m34s
2026-03-10 09:10:43 +05:30
2f28cf28e1 Merge pull request 'Added stock data master policy file' (#453) from ranjith-dev into master
Some checks failed
Scan for leaked secrets using Kingfisher / kingfisher-secrets-scan (push) Has been cancelled
Reviewed-on: #453
2026-03-10 03:36:35 +00:00
dhanabalan
d66a043fa8 Added stock data master policy 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 25s
Scan for leaked secrets using Kingfisher / kingfisher-secrets-scan (pull_request) Successful in 16s
Laravel Pint / pint (pull_request) Successful in 3m1s
Laravel Larastan / larastan (pull_request) Failing after 3m29s
2026-03-10 09:06:22 +05:30
592818c743 Merge pull request 'Added stock data master importer and exporter pages' (#452) from ranjith-dev into master
Some checks failed
Scan for leaked secrets using Kingfisher / kingfisher-secrets-scan (push) Has been cancelled
Reviewed-on: #452
2026-03-10 03:35:39 +00:00
dhanabalan
48f90c7b41 Added stock data master importer and exporter pages
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 20s
Laravel Pint / pint (pull_request) Successful in 2m28s
Laravel Larastan / larastan (pull_request) Failing after 3m57s
2026-03-10 09:05:23 +05:30
0dd6e5796b Merge pull request 'Added stock data master resource pages' (#451) from ranjith-dev into master
Some checks failed
Scan for leaked secrets using Kingfisher / kingfisher-secrets-scan (push) Has been cancelled
Reviewed-on: #451
2026-03-10 03:34:15 +00:00
dhanabalan
1735527722 Added stock data master resource pages
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 12s
Laravel Pint / pint (pull_request) Successful in 2m28s
Laravel Larastan / larastan (pull_request) Failing after 3m41s
2026-03-10 09:04:04 +05:30
c317eec67e Merge pull request 'Added stock data master model file' (#450) from ranjith-dev into master
Some checks failed
Scan for leaked secrets using Kingfisher / kingfisher-secrets-scan (push) Has been cancelled
Reviewed-on: #450
2026-03-10 03:32:51 +00:00
dhanabalan
c46d49898d Added stock data master 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 19s
Scan for leaked secrets using Kingfisher / kingfisher-secrets-scan (pull_request) Successful in 17s
Laravel Larastan / larastan (pull_request) Failing after 3m16s
Laravel Pint / pint (pull_request) Successful in 3m7s
2026-03-10 09:02:40 +05:30
9895297570 Merge pull request 'Added stock data master migration file' (#449) from ranjith-dev into master
Some checks failed
Scan for leaked secrets using Kingfisher / kingfisher-secrets-scan (push) Has been cancelled
Reviewed-on: #449
2026-03-10 03:31:52 +00:00
dhanabalan
7921694adb Added stock data master migration file
Some checks failed
Scan for leaked secrets using Kingfisher / kingfisher-secrets-scan (push) Successful in 12s
Scan for leaked secrets using Kingfisher / kingfisher-secrets-scan (pull_request) Successful in 12s
Gemini PR Review / Gemini PR Review (pull_request) Failing after 18s
Laravel Pint / pint (pull_request) Successful in 2m55s
Laravel Larastan / larastan (pull_request) Failing after 4m19s
2026-03-10 09:01:35 +05:30
91 changed files with 10742 additions and 1246 deletions

View File

@@ -42,7 +42,6 @@ class TriggerPendingApprovalMails extends Command
public $wfId;
public function handle()
{
$this->info('Approval mail job started');
@@ -74,10 +73,8 @@ class TriggerPendingApprovalMails extends Command
});
if ($records->isEmpty()) {
$this->info('No pending approvals');
return;
}
$this->info('No characteristics pending approvals');
}else{
$grouped = $records->groupBy(function ($item) {
$this->wfId = $item->work_flow_id;
return $item->plant_id . '|' . $item->machine_id . '|' . $item->aufnr . '|' . $item->work_flow_id;
@@ -231,7 +228,7 @@ class TriggerPendingApprovalMails extends Command
'SENT'
];
}
}
// .. Quality Mail trigger logic
@@ -374,7 +371,9 @@ class TriggerPendingApprovalMails extends Command
$subjectLine = 'Quality Approval Mail';
Mail::to($mail)->send(
$emails = array_map('trim', explode(',', $mail));
Mail::to($emails)->send(
new CharacteristicApprovalMail(
$first,
$name,
@@ -382,8 +381,8 @@ class TriggerPendingApprovalMails extends Command
$pdfPath,
$pendingApprovers,
$approverNameFromMaster,
$subjectLine,
$characteristics
$subjectLine
// $characteristics
)
);

View File

@@ -0,0 +1,67 @@
<?php
namespace App\Filament\Exports;
use App\Models\Axn;
use App\Models\InvoiceValidation;
use Filament\Actions\Exports\ExportColumn;
use Filament\Actions\Exports\Exporter;
use Filament\Actions\Exports\Models\Export;
class AxnExporter extends Exporter
{
protected static ?string $model = InvoiceValidation::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('invoice_number')
// ->label('INVOICE NUMBER'),
ExportColumn::make('year')
->label('YEAR')
->state(function ($record) {
return substr($record->serial_number, 0, 2);
}),
ExportColumn::make('month')
->label('MONTH')
->state(function ($record) {
return substr($record->serial_number, 2, 2);
}),
ExportColumn::make('vendor')
->label('VENDOR NUMBER')
->state(function ($record) {
return substr($record->serial_number, 4, 4);
}),
ExportColumn::make('serial_number')
->label('SERIAL NUMBER')
->state(function ($record) {
$sn = $record->serial_number;
$offset = 2 + 2 + 4;
return substr($sn, $offset);
}),
];
}
public static function getCompletedNotificationBody(Export $export): string
{
$body = 'Your axn 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

@@ -28,28 +28,28 @@ class CharacteristicApproverMasterExporter extends Exporter
->label('PLANT CODE'),
ExportColumn::make('machine.work_center')
->label('WORK CENTER'),
ExportColumn::make('machine_name')
->label('MACHINE NAME'),
ExportColumn::make('approver_type')
->label('APPROVER TYPE'),
ExportColumn::make('machine_name')
->label('MACHINE NAME'),
ExportColumn::make('characteristic_field')
->label('MASTER CHARACTERISTIC FIELD'),
ExportColumn::make('name1')
->label('APPROVER NAME 1'),
ExportColumn::make('mail1')
->label('APPROVER MAIL 1'),
->label('MAIL 1'),
ExportColumn::make('duration1')
->label('DURATION 1'),
ExportColumn::make('name2')
->label('APPROVER NAME 2'),
ExportColumn::make('mail2')
->label('APPROVER MAIL 2'),
->label('MAIL 2'),
ExportColumn::make('duration2')
->label('DURATION 2'),
ExportColumn::make('name3')
->label('APPROVER NAME 3'),
ExportColumn::make('mail3')
->label('APPROVER MAIL 3'),
->label('MAIL 3'),
ExportColumn::make('duration3')
->label('DURATION 3'),
ExportColumn::make('created_at')

View File

@@ -36,6 +36,8 @@ class ProcessOrderExporter extends Exporter
->label('COIL NUMBER'),
ExportColumn::make('order_quantity')
->label('ORDER QUANTITY'),
ExportColumn::make('updated_order_quantity')
->label('UPDATED ORDER QUANTITY'),
ExportColumn::make('received_quantity')
->label('RECEIVED QUANTITY'),
ExportColumn::make('sfg_number')

View File

@@ -0,0 +1,69 @@
<?php
namespace App\Filament\Exports;
use App\Models\ProductionCharacteristic;
use Filament\Actions\Exports\ExportColumn;
use Filament\Actions\Exports\Exporter;
use Filament\Actions\Exports\Models\Export;
class ProductionCharacteristicExporter extends Exporter
{
protected static ?string $model = ProductionCharacteristic::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('line.name')
->label('LINE NAME'),
ExportColumn::make('item.code')
->label('ITEM CODE'),
ExportColumn::make('machine.work_center')
->label('WORK CENTER'),
ExportColumn::make('production_order')
->label('PRODUCTION ORDER'),
ExportColumn::make('serial_number')
->label('SERIAL NUMBER'),
ExportColumn::make('characteristic_name')
->label('CHARACTERISTIC NAME'),
ExportColumn::make('observed_value')
->label('OBSERVED VALUE'),
ExportColumn::make('status')
->label('STATUS'),
ExportColumn::make('inspection_status')
->label('INSPECTION STATUS'),
ExportColumn::make('remark')
->label('REMARK'),
ExportColumn::make('created_at')
->label('CREATED AT'),
ExportColumn::make('updated_at')
->label('UPDATED AT'),
ExportColumn::make('created_by')
->label('CREATED BY'),
ExportColumn::make('updated_by')
->label('UPDATED BY'),
ExportColumn::make('deleted_at')
->label('DELETED AT'),
];
}
public static function getCompletedNotificationBody(Export $export): string
{
$body = 'Your production characteristic 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

@@ -71,7 +71,19 @@ class RequestCharacteristicExporter extends Exporter
ExportColumn::make('approved3_at')
->label('APPROVED AT 1'),
ExportColumn::make('mail_status')
->label('MAIL STATUS'),
->label('MAIL STATUS')
->formatStateUsing(function ($state) {
if (! $state || $state == '' || $state == null) {
return '-';
}
return match ($state) {
'Sent' => 'Sent-M1',
'Sent-Mail2' => 'Sent-M2',
'Sent-Mail3' => 'Sent-M3',
default => '-',
};
}),
ExportColumn::make('trigger_at')
->label('TRIGGERED AT'),
ExportColumn::make('created_at')

View File

@@ -28,6 +28,10 @@ class StickerMasterExporter extends Exporter
->label('PLANT CODE'),
ExportColumn::make('item.code')
->label('ITEM CODE'),
ExportColumn::make('item.description')
->label('ITEM DESCRIPTION'),
ExportColumn::make('item.uom')
->label('UNIT OF MEASURE'),
ExportColumn::make('serial_number_motor')
->label('SERIAL NUMBER MOTOR'),
ExportColumn::make('serial_number_pump')

View File

@@ -0,0 +1,143 @@
<?php
namespace App\Filament\Exports;
use App\Models\StockDataMaster;
use Filament\Actions\Exports\ExportColumn;
use Filament\Actions\Exports\Exporter;
use Filament\Actions\Exports\Models\Export;
class StockDataMasterExporter extends Exporter
{
protected static ?string $model = StockDataMaster::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('stickerMaster.item.code')
->label('ITEM CODE'),
ExportColumn::make('type')
->label('TYPE')
->formatStateUsing(fn ($state) => match ($state) {
'0' => 'FG',
'1' => 'NON-FG',
default => '-',
}),
ExportColumn::make('location')
->label('LOCATION'),
ExportColumn::make('bin')
->label('BIN'),
ExportColumn::make('serial_number')
->label('SERIAL NUMBER'),
ExportColumn::make('batch')
->label('BATCH'),
ExportColumn::make('quantity')
->label('QUANTITY'),
ExportColumn::make('doc_no')
->label('DOCUMENT NUMBER'),
ExportColumn::make('motor_scanned_status')
->label('MOTOR SCANNED STATUS'),
ExportColumn::make('pump_scanned_status')
->label('PUMP SCANNED STATUS'),
ExportColumn::make('capacitor_scanned_status')
->label('CAPACITOR SCANNED STATUS'),
ExportColumn::make('scanned_status_set')
->label('SCANNED STATUS SET'),
ExportColumn::make('panel_box_item_code')
->label('PANEL BOX ITEM CODE'),
ExportColumn::make('panel_box_supplier')
->label('PANEL BOX SUPPLIER'),
ExportColumn::make('panel_box_sno')
->label('PANEL BOX SNO'),
ExportColumn::make('scanned_status')
->label('SCANNED STATUS'),
ExportColumn::make('scanned_quantity')
->label('SCANNED QUANTITY'),
ExportColumn::make('system_stock')
->label('SYSTEM STOCK')
->state(fn ($record) => $record->quantity),
ExportColumn::make('scanned_stock')
->label('SCANNED STOCK')
->state(fn ($record) => $record->scanned_quantity),
ExportColumn::make('duplicate_stock')
->label('DUPLICATE STOCK')
->state(function ($record) {
return \App\Models\DuplicateStock::where('stock_data_master_id', $record->id)->count();
}),
ExportColumn::make('not_in_stock')
->label('NOT IN STOCK')
->state(function ($record) {
return \App\Models\NotInStock::where('serial_number', $record->serial_number)
->where('plant_id', $record->plant_id)
->count();
}),
ExportColumn::make('physical_stock')
->label('PHYSICAL STOCK')
->state(function ($record) {
$duplicate = \App\Models\DuplicateStock::where('stock_data_master_id', $record->id)->count();
$notInStock = \App\Models\NotInStock::where('serial_number', $record->serial_number)
->where('plant_id', $record->plant_id)
->count();
$scanned = $record->scanned_quantity ?? 0;
return $scanned + $duplicate + $notInStock;
}),
ExportColumn::make('stock_difference')
->label('STOCK DIFFERENCE COUNT')
->state(function ($record) {
$duplicate = \App\Models\DuplicateStock::where('stock_data_master_id', $record->id)->count();
$notInStock = \App\Models\NotInStock::where('serial_number', $record->serial_number)
->where('plant_id', $record->plant_id)
->count();
$scanned = (int) $record->scanned_quantity;
$physicalStock = $scanned + $duplicate + $notInStock;
$systemStock = (int) $record->quantity;
$difference = $physicalStock - $systemStock;
return max($difference, 0);
}),
ExportColumn::make('created_at')
->label('CREATED AT'),
ExportColumn::make('updated_at')
->label('UPDATED AT'),
ExportColumn::make('created_by')
->label('CREATED BY'),
ExportColumn::make('updated_by')
->label('UPDATED BY'),
ExportColumn::make('deleted_at')
->label('DELETED AT')
->enabledByDefault(false),
];
}
public static function getCompletedNotificationBody(Export $export): string
{
$body = 'Your stock data master 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

@@ -3,9 +3,14 @@
namespace App\Filament\Imports;
use App\Models\CharacteristicApproverMaster;
use App\Models\Machine;
use App\Models\Plant;
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 CharacteristicApproverMasterImporter extends Importer
{
@@ -17,80 +22,80 @@ class CharacteristicApproverMasterImporter extends Importer
ImportColumn::make('plant')
->requiredMapping()
->exampleHeader('Plant Code')
->examples(['1000','1000'])
->examples(['1000', '1000'])
->label('Plant Code')
->relationship(resolveUsing: 'code')
->rules(['required']),
ImportColumn::make('machine')
->requiredMapping()
->exampleHeader('Work Center')
->examples(['RMGLAS02','RMGLAS02'])
->examples(['RMGLAS02', 'RMGLAS02'])
->label('Work Center')
->relationship()
->relationship(resolveUsing: 'work_center')
->rules(['required']),
ImportColumn::make('approver_type')
->requiredMapping()
->exampleHeader('Approver Type')
->examples(['Characteristic', 'Quality'])
->label('Approver Type'),
ImportColumn::make('machine_name')
->requiredMapping()
->exampleHeader('Machine Name')
->examples(['15002635','17002635'])
->examples(['15002635', '17002635'])
->label('Machine Name'),
ImportColumn::make('characteristic_field')
->requiredMapping()
->exampleHeader('Master Characteristic Field')
->examples(['NIL', 'MV SERIES'])
->label('Master Characteristic Field'),
ImportColumn::make('name1')
->requiredMapping()
->exampleHeader('Approver Name 1')
->examples(['Suresh.D','Suresh.D'])
->examples(['Test 1', 'Test 4'])
->label('Approver Name 1'),
ImportColumn::make('mail1')
->requiredMapping()
->exampleHeader('Approver Mail 1')
->examples(['suresh@cripumps.com','suresh@cripumps.com'])
->label('Approver Mail 1'),
ImportColumn::make('name2')
->requiredMapping()
->exampleHeader('Approver Name 2')
->examples(['Ramesh.G','Ramesh.G'])
->label('Approver Name 2'),
ImportColumn::make('mail2')
->requiredMapping()
->exampleHeader('Approver Mail 2')
->examples(['ramesh@cripumps.com','ramesh@cripumps.com'])
->label('Approver Mail 2'),
ImportColumn::make('name3')
->requiredMapping()
->exampleHeader('Approver Name 3')
->examples(['Ganesh.K','Ganesh.K'])
->label('Approver Name 3'),
ImportColumn::make('mail3')
->requiredMapping()
->exampleHeader('Approver Mail 3')
->examples(['ganesh@cripumps.com','ganesh@cripumps.com'])
->label('Approver Mail 3'),
->exampleHeader('Mail 1')
->examples(['test1@cripumps.com', 'test4@cripumps.com'])
->label('Mail 1'),
ImportColumn::make('duration1')
->numeric()
->requiredMapping()
->exampleHeader('Duration 1')
->examples(['0.05','0.30'])
->examples(['0.05', '0.30'])
->label('Duration 1'),
ImportColumn::make('name2')
->requiredMapping()
->exampleHeader('Approver Name 2')
->examples(['Test 2', 'Test 5'])
->label('Approver Name 2'),
ImportColumn::make('mail2')
->requiredMapping()
->exampleHeader('Mail 2')
->examples(['test2@cripumps.com', 'test5@cripumps.com'])
->label('Mail 2'),
ImportColumn::make('duration2')
->numeric()
->requiredMapping()
->exampleHeader('Duration 2')
->examples(['0.05','0.30'])
->examples(['0.05', '0.30'])
->label('Duration 2'),
ImportColumn::make('name3')
->requiredMapping()
->exampleHeader('Approver Name 3')
->examples(['Test 3', 'Test 6'])
->label('Approver Name 3'),
ImportColumn::make('mail3')
->requiredMapping()
->exampleHeader('Mail 3')
->examples(['test3@cripumps.com', 'test6@cripumps.com'])
->label('Mail 3'),
ImportColumn::make('duration3')
->numeric()
->requiredMapping()
->exampleHeader('Duration 3')
->examples(['0.05','0.30'])
->examples(['0.05', '0.30'])
->label('Duration 3'),
ImportColumn::make('characteristic_field')
->requiredMapping()
->exampleHeader('Characteristic Field')
->examples(['MV SERIES','PV SERIES'])
->label('Characteristic Field'),
ImportColumn::make('approver_type')
->requiredMapping()
->exampleHeader('Approver Type')
->examples(['Characteristic','Quality'])
->label('Approver Type'),
];
}
@@ -101,15 +106,132 @@ class CharacteristicApproverMasterImporter extends Importer
// 'email' => $this->data['email'],
// ]);
return new CharacteristicApproverMaster();
$warnMsg = [];
$plantCod = trim($this->data['plant']) ?? null;
$workCenter = trim($this->data['machine']) ?? null;
$apprTyp = trim($this->data['approver_type']) ?? null;
$machineNam = trim($this->data['machine_name']) ?? null;
$mastCharFld = trim($this->data['characteristic_field']) ?? null; // zmm_pumpseries
$apprNam1 = trim($this->data['name1']) ?? null;
$apprMail1 = trim($this->data['mail1']) ?? null;
$apprDur1 = trim($this->data['duration1']) ?? 0.01;
$apprNam2 = trim($this->data['name2']) ?? null;
$apprMail2 = trim($this->data['mail2']) ?? null;
$apprDur2 = trim($this->data['duration2']) ?? 0.01;
$apprNam3 = trim($this->data['name3']) ?? null;
$apprMail3 = trim($this->data['mail3']) ?? null;
$apprDur3 = trim($this->data['duration3']) ?? 0.01;
$createdBy = Filament::auth()->user()->name;
$updatedBy = $createdBy;
$plantId = null;
$machineId = null;
if ($plantCod == null || $plantCod == '') {
$warnMsg[] = "Plant code can't be empty!";
} elseif (Str::length($plantCod) < 4 || ! is_numeric($plantCod) || ! preg_match('/^[1-9]\d{3,}$/', $plantCod)) {
$warnMsg[] = 'Invalid plant code found!';
}
if ($workCenter == null || $workCenter == '') {
$warnMsg[] = "Work center can't be empty!";
}
if ($apprTyp == '' || $apprTyp == null || ($apprTyp != 'Characteristic' && $apprTyp != 'Quality')) {
$warnMsg[] = "Approver type must be either 'Characteristic' or 'Quality'!";
}
if ($machineNam == null || $machineNam == '') {
$warnMsg[] = "Machine name can't be empty!";
}
if ($mastCharFld == null || $mastCharFld == '') {
$mastCharFld = 'NIL';
}
if ($apprNam1 == null || $apprNam1 == '') {
$warnMsg[] = "Approver name 1 can't be empty!";
}
if ($apprMail1 == null || $apprMail1 == '') {
$warnMsg[] = "Approver email 1 can't be empty!";
}
if (! is_numeric($apprDur1)) {
$warnMsg[] = 'Duration 1 must be a numeric value (HH.MM)!';
}
if ($apprDur2 != null && $apprDur2 != '' && ! is_numeric($apprDur2)) {
$warnMsg[] = 'Duration 2 must be a numeric value (HH.MM)!';
}
if ($apprDur3 != null && $apprDur3 != '' && ! is_numeric($apprDur3)) {
$warnMsg[] = 'Duration 3 must be a numeric value (HH.MM)!';
}
if (! empty($warnMsg)) {
throw new RowImportFailedException(implode(', ', $warnMsg));
}
$plant = Plant::where('code', $plantCod)->first();
if (! $plant) {
$warnMsg[] = 'Plant code not found!';
} else {
$plantId = $plant->id;
$machine = Machine::where('work_center', $workCenter)->first();
if (! $machine) {
$warnMsg[] = 'Work center not found!';
} else {
$machine = Machine::where('work_center', $workCenter)->where('plant_id', $plantId)->first();
if (! $machine) {
$warnMsg[] = 'Work center not found for the given plant!';
} else {
$machineId = $machine->id;
}
}
$getCreatedBy = CharacteristicApproverMaster::where('plant_id', $plantId)
->where('machine_id', $machineId)
->where('approver_type', $apprTyp)
->where('machine_name', $machineNam)
->where('characteristic_field', $mastCharFld)
->first()?->created_by;
if ($getCreatedBy) {
$createdBy = $getCreatedBy;
}
}
if (! empty($warnMsg)) {
throw new RowImportFailedException(implode(', ', $warnMsg));
}
CharacteristicApproverMaster::updateOrCreate(
[
'plant_id' => $plantId,
'machine_id' => $machineId,
'approver_type' => $apprTyp,
'machine_name' => $machineNam,
'characteristic_field' => $mastCharFld,
],
[
'name1' => $apprNam1,
'mail1' => $apprMail1,
'duration1' => $apprDur1,
'name2' => $apprNam2,
'mail2' => $apprMail2,
'duration2' => $apprDur2,
'name3' => $apprNam3,
'mail3' => $apprMail3,
'duration3' => $apprDur3,
'created_by' => $createdBy,
'updated_by' => $updatedBy,
]);
return null;
// return new CharacteristicApproverMaster;
}
public static function getCompletedNotificationBody(Import $import): string
{
$body = 'Your characteristic approver master import has completed and ' . number_format($import->successful_rows) . ' ' . str('row')->plural($import->successful_rows) . ' imported.';
$body = 'Your characteristic approver master import has completed and '.number_format($import->successful_rows).' '.str('row')->plural($import->successful_rows).' imported.';
if ($failedRowsCount = $import->getFailedRowsCount()) {
$body .= ' ' . number_format($failedRowsCount) . ' ' . str('row')->plural($failedRowsCount) . ' failed to import.';
$body .= ' '.number_format($failedRowsCount).' '.str('row')->plural($failedRowsCount).' failed to import.';
}
return $body;

View File

@@ -211,9 +211,9 @@ class MotorTestingMasterImporter extends Importer
->rules(['required']),
ImportColumn::make('plant')
->requiredMapping()
->exampleHeader('Plant')
->exampleHeader('Plant Code')
->example(['1000', '1010', '1020'])
->label('Plant')
->label('Plant Code')
->relationship(resolveUsing: 'code')
->rules(['required']),
ImportColumn::make('created_by')

View File

@@ -6,6 +6,7 @@ use App\Models\Item;
use App\Models\Line;
use App\Models\Plant;
use App\Models\ProcessOrder;
use App\Models\ProductCharacteristicsMaster;
use App\Models\User;
use Filament\Actions\Imports\Exceptions\RowImportFailedException;
use Filament\Actions\Imports\ImportColumn;
@@ -30,7 +31,7 @@ class ProcessOrderImporter extends Importer
->rules(['required']),
ImportColumn::make('line')
->exampleHeader('LINE NAME')
->example(' Poly Wrapped Wire SFG')
->example('Poly Wrapped Wire SFG')
->label('LINE NAME')
->relationship(resolveUsing: 'name'),
ImportColumn::make('item')
@@ -43,7 +44,7 @@ class ProcessOrderImporter extends Importer
ImportColumn::make('process_order')
->requiredMapping()
->exampleHeader('PROCESS ORDER')
->example('2025002123456')
->example('202601123456')
->label('PROCESS ORDER')
->rules(['required']),
ImportColumn::make('order_quantity')
@@ -52,6 +53,9 @@ class ProcessOrderImporter extends Importer
->example('1000')
->label('ORDER QUANTITY')
->rules(['required']),
ImportColumn::make('updated_order_quantity')
->exampleHeader('UPDATED ORDER QUANTITY')
->label('UPDATED ORDER QUANTITY'),
ImportColumn::make('coil_number')
->exampleHeader('COIL NUMBER')
// ->example('01')
@@ -101,15 +105,16 @@ class ProcessOrderImporter extends Importer
$plant = null;
$plantCod = trim($this->data['plant']) ?? '';
$plantId = null;
$item = null;
$iCode = trim($this->data['item']) ?? '';
$itemId = null;
$lineNam = trim($this->data['line']) ?? '';
$lineId = null;
$processOrder = trim($this->data['process_order'] ?? '');
$coilNo = trim($this->data['coil_number'] ?? '');
$sfgNo = trim($this->data['sfg_number'] ?? '');
$machineName = trim($this->data['machine_name'] ?? '');
$orderQuan = trim($this->data['order_quantity'] ?? '');
$updatedOrderQuan = trim($this->data['updated_order_quantity'] ?? '');
$scrapQuan = trim($this->data['scrap_quantity'] ?? '');
$reworkStatus = trim($this->data['rework_status'] ?? '');
$recQuan = trim($this->data['received_quantity'] ?? '');
@@ -128,11 +133,14 @@ class ProcessOrderImporter extends Importer
if ($iCode == null || $iCode == '') {
$warnMsg[] = "Item code can't be empty!";
} elseif (Str::length($iCode) < 6 || ! ctype_alnum($iCode)) {
$warnMsg[] = 'Invalid item code found';
$warnMsg[] = 'Invalid item code found!';
}
if ($machineName != null && $machineName != '' && Str::length($machineName) > 18) {
$warnMsg[] = 'Invalid machine name found!';
}
if ($processOrder == null || $processOrder == '') {
$warnMsg[] = "Process order can't be empty!";
} elseif ($processOrder && Str::contains($processOrder, '.')) {
} elseif ($processOrder && (Str::contains($processOrder, '.') || Str::contains($processOrder, 'E', ignoreCase: true))) {
$warnMsg[] = 'Invalid process order found!';
}
if ($lineNam == null || $lineNam == '') {
@@ -145,6 +153,12 @@ class ProcessOrderImporter extends Importer
} elseif (Str::length($orderQuan) >= 1 && ! is_numeric($orderQuan)) {
$warnMsg[] = 'Invalid order quantity found!';
}
if ($updatedOrderQuan == null || $updatedOrderQuan == '' || $updatedOrderQuan == 0 || $updatedOrderQuan == '0') {
$updatedOrderQuan = $orderQuan;
} elseif (Str::length($updatedOrderQuan) >= 1 && ! is_numeric($updatedOrderQuan)) {
$warnMsg[] = 'Invalid Updated order quantity found!';
}
if ($coilNo == null || $coilNo == '') {
$coilNo = '0';
}
@@ -159,7 +173,7 @@ class ProcessOrderImporter extends Importer
} elseif ($reworkStatus == 1 || $reworkStatus = '1') {
$reworkStatus = 1;
} else {
$warnMsg[] = 'Invalid rework status found';
$warnMsg[] = 'Invalid rework status found!';
}
if (! empty($warnMsg)) {
@@ -217,14 +231,26 @@ class ProcessOrderImporter extends Importer
}
}
if ($plantId && $itemCode && $lineId && $processOrder != '') {
if ($plantId && $itemId && $lineId && $processOrder != '') {
$existingOrder = ProcessOrder::where('plant_id', $plantId)
->where('process_order', $processOrder)
->first();
if ($existingOrder && $existingOrder->item_id !== ($itemId ?? null)) {
$warnMsg[] = 'Same Process Order already exists for this Plant with a different Item Code';
$warnMsg[] = 'Same Process Order already exists for this Plant with a different Item Code!';
}
// $masterExist = ProductCharacteristicsMaster::where('plant_id', $plantId)->where('item_id', $itemId)->first();
// if (! $masterExist) {
// $warnMsg[] = 'Characteristics master not found for the given plant!';
// } else {
// $masterExist = ProductCharacteristicsMaster::where('plant_id', $plantId)->where('line_id', $lineId)->where('item_id', $itemId)->first();
// if (! $masterExist) {
// $warnMsg[] = 'Characteristics master not found for the given line!';
// }
// }
}
// $user = User::where('name', $this->data['created_by'])->first();
@@ -243,6 +269,39 @@ class ProcessOrderImporter extends Importer
throw new RowImportFailedException(implode(', ', $warnMsg));
}
$existing = ProcessOrder::where('plant_id', $plantId)
->where('process_order', $processOrder)
// ->where('coil_number', $coilNo)
->first();
$receivedQty = ProcessOrder::where('plant_id', $plantId)
->where('process_order', $processOrder)
->sum('received_quantity');
if ($existing) {
$liveOrdQuan = (float) $existing->order_quantity;
$liveUpdatedOrdQuan = (float) $existing->updated_order_quantity;
$allowedIncrease = $liveOrdQuan * 0.10;
$maxAllowedQty = $liveOrdQuan + $allowedIncrease;
$minAllowedQty = $liveOrdQuan - $allowedIncrease;
if ($liveUpdatedOrdQuan > $maxAllowedQty) {
throw new RowImportFailedException(
"Updated order quantity cannot exceed 10% of existing order quantity. Max allowed: {$maxAllowedQty}!"
);
} elseif ($liveUpdatedOrdQuan < $minAllowedQty) {
throw new RowImportFailedException(
"Updated order quantity cannot decrease -10% of existing order quantity. Min allowed: {$minAllowedQty}!"
);
} elseif ($liveUpdatedOrdQuan < $receivedQty) {
throw new RowImportFailedException(
"Updated order quantity cannot decrease below its received quantity {$receivedQty}!"
);
}
}
if ($coilNo != null && $coilNo != '' && $scrapQuan && $reworkStatus && $recQuan && $createdAt && $createdBy && $updatedAt && $updatedBy && Filament::auth()->user()->hasRole('Super Admin')) {
$existingCoil = ProcessOrder::where('plant_id', $plantId)
->where('process_order', $processOrder)
@@ -250,6 +309,17 @@ class ProcessOrderImporter extends Importer
->where('coil_number', $coilNo)
->first();
// $existingProcess = ProcessOrder::where('plant_id', $plantId)
// ->where('process_order', $processOrder)
// ->where('line_id', $lineId)
// ->first();
if ($existing) {
$existUpdateOrdQuan = $existing->updated_order_quantity;
} else {
$existUpdateOrdQuan = $updatedOrderQuan;
}
if (! $existingCoil) {
ProcessOrder::Create(
[
@@ -259,6 +329,7 @@ class ProcessOrderImporter extends Importer
'item_id' => $itemId,
'coil_number' => $coilNo,
'order_quantity' => $orderQuan,
'updated_order_quantity' => $existUpdateOrdQuan,
'received_quantity' => $recQuan,
'scrap_quantity' => $scrapQuan,
'sfg_number' => $sfgNo,
@@ -288,10 +359,16 @@ class ProcessOrderImporter extends Importer
}
} else {
$coilNo = '0';
$existing = ProcessOrder::where('plant_id', $plantId)
->where('process_order', $processOrder)
// ->where('coil_number', $coilNo)
->first();
// $existing = ProcessOrder::where('plant_id', $plantId)
// ->where('process_order', $processOrder)
// // ->where('coil_number', $coilNo)
// ->first();
if ($existing) {
$existUpdateOrdQuan = $existing->updated_order_quantity;
} else {
$existUpdateOrdQuan = $updatedOrderQuan;
}
if (! $existing && ($coilNo == '0' || $coilNo == 0)) {
ProcessOrder::create([
@@ -301,6 +378,7 @@ class ProcessOrderImporter extends Importer
'process_order' => $processOrder,
'coil_number' => '0',
'order_quantity' => $orderQuan,
'updated_order_quantity' => $existUpdateOrdQuan,
'received_quantity' => 0,
'scrap_quantity' => 0,
'created_by' => $createdBy,
@@ -315,6 +393,7 @@ class ProcessOrderImporter extends Importer
'process_order' => $processOrder,
'coil_number' => $coilNo,
'order_quantity' => $orderQuan,
'updated_order_quantity' => $existUpdateOrdQuan,
'received_quantity' => $recQuan,
'scrap_quantity' => $scrapQuan ?? 0,
'sfg_number' => $sfgNo,

View File

@@ -0,0 +1,65 @@
<?php
namespace App\Filament\Imports;
use App\Models\ProductionCharacteristic;
use Filament\Actions\Imports\ImportColumn;
use Filament\Actions\Imports\Importer;
use Filament\Actions\Imports\Models\Import;
class ProductionCharacteristicImporter extends Importer
{
protected static ?string $model = ProductionCharacteristic::class;
public static function getColumns(): array
{
return [
ImportColumn::make('plant')
->requiredMapping()
->relationship()
->rules(['required']),
ImportColumn::make('line')
->requiredMapping()
->relationship()
->rules(['required']),
ImportColumn::make('item')
->requiredMapping()
->relationship()
->rules(['required']),
ImportColumn::make('machine')
->requiredMapping()
->relationship()
->rules(['required']),
ImportColumn::make('production_order'),
ImportColumn::make('serial_number'),
ImportColumn::make('characteristic_name'),
ImportColumn::make('observed_value'),
ImportColumn::make('status'),
ImportColumn::make('inspection_status'),
ImportColumn::make('remark'),
ImportColumn::make('created_by'),
ImportColumn::make('updated_by'),
];
}
public function resolveRecord(): ?ProductionCharacteristic
{
// return ProductionCharacteristic::firstOrNew([
// // Update existing records, matching them by `$this->data['column_name']`
// 'email' => $this->data['email'],
// ]);
return new ProductionCharacteristic();
}
public static function getCompletedNotificationBody(Import $import): string
{
$body = 'Your production characteristic 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,234 @@
<?php
namespace App\Filament\Imports;
use App\Models\Item;
use App\Models\Plant;
use App\Models\StickerMaster;
use App\Models\StockDataMaster;
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 StockDataMasterImporter extends Importer
{
protected static ?string $model = StockDataMaster::class;
public static function getColumns(): array
{
return [
ImportColumn::make('plant')
->requiredMapping()
->exampleHeader('PLANT CODE')
->examples(['1000', '1000'])
->label('PLANT CODE')
->relationship(resolveUsing: 'code')
->rules(['required']),
ImportColumn::make('type')
->requiredMapping()
->exampleHeader('TYPE')
->examples(['FG', 'NON-FG'])
->label('TYPE'),
ImportColumn::make('location')
->requiredMapping()
->exampleHeader('LOCATION')
->examples(['2001', '2002'])
->label('LOCATION')
->rules(['required']),
ImportColumn::make('item_reference')
->requiredMapping()
->exampleHeader('ITEM CODE')
->examples(['123456', '246118'])
->label('ITEM CODE')
->rules(['required']),
ImportColumn::make('serial_number')
->requiredMapping()
->exampleHeader('SERIAL NUMBER')
->examples(['200235236622', '200235236623'])
->label('SERIAL NUMBER'),
ImportColumn::make('batch')
->requiredMapping()
->exampleHeader('BATCH')
->examples(['20102', '20103'])
->label('BATCH'),
ImportColumn::make('quantity')
->requiredMapping()
->exampleHeader('QUANTITY')
->examples(['1', '1'])
->label('QUANTITY'),
ImportColumn::make('doc_no')
->requiredMapping()
->exampleHeader('DOCUMENT NUMBER')
->examples(['82128', '21222'])
->label('DOCUMENT NUMBER'),
];
}
public function resolveRecord(): ?StockDataMaster
{
$warnMsg = [];
$plantId = null;
$stickId = null;
$plantCod = $this->data['plant'];
$typeValue = $this->data['type'];
$iCode = trim($this->data['item_reference']) ?? null;
$location = trim($this->data['location']) ?? null;
$serialNumber = trim($this->data['serial_number']) ?? null;
$batch = trim($this->data['batch']) ?? null;
$quantity = trim($this->data['quantity']) ?? null;
$docNo = trim($this->data['doc_no']) ?? null;
$user = Filament::auth()->user();
$operatorName = $user->name;
if ($plantCod == null || $plantCod == '') {
$warnMsg[] = "Plant code can't be empty!";
} elseif ($typeValue == null || $typeValue == '') {
$warnMsg[] = "Type can't be empty!";
} elseif ($iCode == null || $iCode == '') {
$warnMsg[] = "Item code can't be empty!";
} elseif ($location == null || $location == '') {
$warnMsg[] = "Location can't be empty!";
} elseif ($serialNumber == null || $serialNumber == '') {
$warnMsg[] = "Serial number can't be empty!";
}
// else if ($batch == null || $batch == '') {
// $warnMsg[] = "Batch can't be empty!";
// }
elseif ($quantity == null || $quantity == '') {
$warnMsg[] = "Quantity can't be empty!";
}
// else if ($docNo == null || $docNo == '') {
// $warnMsg[] = "Doc No can't be empty!";
// }
if (Str::length($plantCod) > 0 && (Str::length($plantCod) < 4 || ! is_numeric($plantCod) || ! preg_match('/^[1-9]\d{3,}$/', $plantCod))) {
$warnMsg[] = 'Invalid plant code found!';
} elseif (Str::length($plantCod) > 0) {
$plant = Plant::where('code', $plantCod)->first();
if (! $plant) {
$warnMsg[] = 'Plant code not found!';
} else {
$plantId = $plant->id;
}
}
if (Str::length($iCode) > 0 && (Str::length($iCode) < 6 || ! ctype_alnum($iCode))) {
$warnMsg[] = 'Invalid item code found!';
} elseif ($plantId) {
$itemCode = Item::where('code', $iCode)->first();
if (! $itemCode) {
$warnMsg[] = 'Item code not found in item master!';
} else {
$itemCode = Item::where('code', $iCode)->where('plant_id', $plantId)->first();
if (! $itemCode) {
$warnMsg[] = 'Item code not found in item master for the given plant!';
} else {
$itemId = $itemCode->id;
$itemCode = StickerMaster::where('item_id', $itemId)->first();
if (! $itemCode) {
$warnMsg[] = 'Item code not found in sticker master!';
} else {
if ($plantId) {
$itemCode = StickerMaster::where('item_id', $itemId)->where('plant_id', $plantId)->first();
if (! $itemCode) {
$warnMsg[] = 'Item code not found in sticker master for the given plant!';
}
}
}
}
}
}
$typeValue = strtoupper($typeValue);
if (! in_array($typeValue, ['FG', 'NON-FG'])) {
$warnMsg[] = 'Invalid type found! It should be either FG or NON-FG.';
} elseif (Str::length($location) < 4) {
$warnMsg[] = 'Location should contain minimum 4 digits!';
} elseif (! ctype_digit((string) $location)) {
$warnMsg[] = 'Location must be an integer!';
} elseif (Str::length($serialNumber) < 9) {
$warnMsg[] = 'Serial number should contain minimum 9 digits!';
} elseif (! ctype_alnum($serialNumber)) {
$warnMsg[] = 'Serial number should contain alpha-numeric values!';
} elseif (! ctype_digit((string) $quantity) || (int) $quantity <= 0) {
$warnMsg[] = 'Quantity must be an integer and greater than 0!';
}
if ($batch) {
if (Str::length($batch) < 5) {
$warnMsg[] = 'Batch should contain minimum 5 digits!';
}
}
if ($docNo) {
if (Str::length($docNo) < 5) {
$warnMsg[] = 'Document number contain minimum 5 digits!';
}
}
if (! empty($warnMsg)) {
throw new RowImportFailedException(implode(', ', $warnMsg));
}
$type = match ($typeValue) {
'FG' => '0',
'NON-FG' => '1',
default => null,
};
$stickId = $itemCode->id;
$record = StockDataMaster::where([
'plant_id' => $plantId,
'sticker_master_id' => $stickId,
'serial_number' => $serialNumber,
])->first();
if ($record) {
$record->update([
'type' => $type,
'location' => $location ?? null,
'batch' => $batch ?? null,
'quantity' => $quantity ?? null,
'doc_no' => $docNo ?? null,
'updated_by' => $operatorName,
]);
} else {
StockDataMaster::create([
'plant_id' => $plantId,
'sticker_master_id' => $stickId,
'type' => $type,
'location' => $location ?? null,
'serial_number' => $serialNumber ?? null,
'batch' => $batch ?? null,
'quantity' => $quantity ?? null,
'doc_no' => $docNo ?? null,
'created_by' => $operatorName,
'updated_by' => $operatorName,
]);
}
return null;
}
public static function getCompletedNotificationBody(Import $import): string
{
$body = 'Your stock data master 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;
}
}

File diff suppressed because it is too large Load Diff

View File

@@ -2,6 +2,7 @@
namespace App\Filament\Pages;
use App\Filament\Widgets\CumulativeChart;
use App\Filament\Widgets\ProductionQuantityStat;
use Filament\Forms\Components\Select;
use Filament\Forms\Components\TextInput;
use Filament\Forms\Form;
@@ -9,6 +10,8 @@ use Filament\Pages\Dashboard\Concerns\HasFiltersForm;
use Filament\Tables\Filters\SelectFilter;
use Illuminate\Support\Facades\DB;
use App\Models\Plant;
use Filament\Facades\Filament;
use Filament\Forms\Components\DatePicker;
use Filament\Widgets\Widget;
use Illuminate\Support\Facades\Auth;
@@ -16,57 +19,108 @@ class Dashboard extends \Filament\Pages\Dashboard
{
use HasFiltersForm;
protected static ?string $navigationGroup = 'Production DashBoard';
protected static ?string $navigationIcon = 'heroicon-s-gift';
public function mount(): void
{
session()->forget(['selected_plant']);
$this->filtersForm->fill([
'plant' => null
]);
}
protected static string $view = 'filament.pages.dashboard';
public function filtersForm(Form $form): Form
{
return $form
->statePath('filters') // Store form state in 'filters'
->schema([
Select::make('plant')
->options(Plant::pluck('name', 'id'))
->label('Select Plant')
->reactive()
->afterStateUpdated(function ($state) {
session(['selected_plant' => $state]); // fixed typo
//$this->dispatch('cumulativeChart'); // custom Livewire event
}),
]);
// public function mount(): void
// {
// session()->forget(['selected_plant']);
// session()->forget(['from_date']);
// session()->forget(['to_date']);
// $this->filtersForm->fill([
// 'plant' => null,
// 'from_date' => null,
// 'to_date' => null,
// // 'success_status' => null
// ]);
// }
}
// public function filtersForm(Form $form): Form
// {
// return $form
// ->statePath('filters') // Store form state in 'filters'
// ->schema([
// Select::make('plant')
// ->label('Select 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,callable $set) {
// session(['selected_plant' => $state]); // fixed typo
// //$this->dispatch('cumulativeChart'); // custom Livewire event
// // Reset success_status whenever plant changes
// $set('success_status', null);
// session()->forget('success_status');
// }),
// // Select::make('success_status')
// // ->label('Select Status')
// // ->options([
// // 'Ok' => 'Ok',
// // 'Not Ok' => 'Not Ok',
// // ])
// // ->reactive()
// // ->afterStateUpdated(function ($state) {
// // session(['success_status' => $state]);
// // }),
// DatePicker::make('created_from')
// ->label('Created From')
// ->reactive()
// ->afterStateUpdated(function ($state,callable $set) {
// session(['from_date' => $state]);
// }),
// DatePicker::make('created_to')
// ->label('Created To')
// ->reactive()
// ->afterStateUpdated(function ($state,callable $set) {
// session(['to_date' => $state]);
// }),
// ]);
// }
public static function getNavigationLabel(): string
{
return 'Production Line Count';
}
// public static function getNavigationLabel(): string
// {
// return 'Production Line Count';
// }
// public function getHeading(): string
// {
// return 'Production Line Count';
// }
// public function getWidgets(): array
// {
// $widgets = [];
// if (CumulativeChart::canView()) {
// $widgets[] = CumulativeChart::class;
// }
// return $widgets;
// }
// public static function canAccess(): bool
// {
// return Auth::check() && Auth::user()->can('view production line count dashboard');
// }
public function getHeading(): string
{
return 'Production Line Count';
return '';
}
public function getWidgets(): array
public static function getNavigationLabel(): string
{
$widgets = [];
if (CumulativeChart::canView()) {
$widgets[] = CumulativeChart::class;
}
return $widgets;
}
public static function canAccess(): bool
{
return Auth::check() && Auth::user()->can('view production line count dashboard');
return 'Welcome';
}
}

View File

@@ -1,23 +1,124 @@
<?php
namespace App\Filament\Pages;
use Filament\Pages\Page;
use App\Filament\Widgets\CumulativeChart;
use App\Filament\Widgets\ProductionQuantityStat;
use Filament\Forms\Components\Select;
use Filament\Forms\Components\TextInput;
use Filament\Forms\Form;
use Filament\Pages\Dashboard\Concerns\HasFiltersForm;
use Filament\Tables\Filters\SelectFilter;
use Illuminate\Support\Facades\DB;
use App\Models\Plant;
use Filament\Facades\Filament;
use Filament\Forms\Components\DatePicker;
use Filament\Widgets\Widget;
use Illuminate\Support\Facades\Auth;
use Filament\Pages\Page;
use Filament\Forms\Concerns\InteractsWithForms;
class Welcome extends Page
{
protected static ?string $navigationIcon = 'heroicon-s-gift'; // 'heroicon-o-document-text';
protected static string $view = 'filament.pages.welcome';
public function getHeading(): string
protected static ?string $navigationIcon = 'heroicon-o-document-text';
use HasFiltersForm;
use InteractsWithForms;
protected static ?string $navigationGroup = 'Production DashBoard';
protected static ?string $slug = 'production-line-count';
public function mount(): void
{
return '';
session()->forget(['selected_plant']);
// session()->forget(['from_date']);
// session()->forget(['to_date']);
$this->filtersForm->fill([
'plant' => null,
// 'from_date' => null,
// 'to_date' => null,
// 'success_status' => null
]);
}
// public static function canAccess(): bool
public function filtersForm(Form $form): Form
{
return $form
->statePath('filters')
->schema([
Select::make('plant')
->label('Select 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,callable $set) {
session(['selected_plant' => $state]);
//$this->dispatch('cumulativeChart'); // custom Livewire event
// Reset success_status whenever plant changes
// $set('success_status', null);
// session()->forget('success_status');
}),
// Select::make('success_status')
// ->label('Select Status')
// ->options([
// 'Ok' => 'Ok',
// 'Not Ok' => 'Not Ok',
// ])
// ->reactive()
// ->afterStateUpdated(function ($state) {
// session(['success_status' => $state]);
// }),
// DatePicker::make('created_from')
// ->label('Created From')
// ->reactive()
// ->afterStateUpdated(function ($state,callable $set) {
// session(['from_date' => $state]);
// }),
// DatePicker::make('created_to')
// ->label('Created To')
// ->reactive()
// ->afterStateUpdated(function ($state,callable $set) {
// session(['to_date' => $state]);
// }),
]);
}
public static function getNavigationLabel(): string
{
return 'Production Line Count';
}
public function getHeading(): string
{
return 'Production Line Count';
}
// public function getWidgets(): array
// {
// return Auth::check() && Auth::user()->can('view welcome page');
// $widgets = [];
// if (CumulativeChart::canView()) {
// $widgets[] = CumulativeChart::class;
// }
// return $widgets;
// }
public static function canAccess(): bool
{
return Auth::check() && Auth::user()->can('view production line count dashboard');
}
}

View File

@@ -19,6 +19,7 @@ use Filament\Tables\Actions\ImportAction;
use Filament\Tables\Table;
use Illuminate\Database\Eloquent\Builder;
use Illuminate\Database\Eloquent\SoftDeletingScope;
use Illuminate\Validation\Rule;
class CharacteristicApproverMasterResource extends Resource
{
@@ -83,7 +84,7 @@ class CharacteristicApproverMasterResource extends Resource
$set('updated_by', Filament::auth()->user()?->name);
}),
Forms\Components\TextInput::make('machine_name')
->label('Machine')
->label('Machine Name')
->columnSpan(1)
->reactive()
->required()
@@ -101,7 +102,7 @@ class CharacteristicApproverMasterResource extends Resource
$set('updated_by', Filament::auth()->user()?->name);
}),
Forms\Components\Select::make('approver_type')
->label('Request Type')
->label('Approver Type')
->columnSpan(1)
->reactive()
->nullable()
@@ -130,7 +131,7 @@ class CharacteristicApproverMasterResource extends Resource
// return optional(CharacteristicApproverMaster::latest()->first())->approver_type ?? null;
})
->afterStateUpdated(function ($state, callable $set) {
$set('characteristic_field', null);
$set('characteristic_field', 'NIL');
$set('updated_by', Filament::auth()->user()?->name);
}),
Forms\Components\TextInput::make('characteristic_field')
@@ -149,6 +150,14 @@ class CharacteristicApproverMasterResource extends Resource
$set('characteristic_field', 'NIL');
}
$set('updated_by', Filament::auth()->user()?->name);
})
->rule(function (callable $get) {
return Rule::unique('characteristic_approver_masters', 'characteristic_field')
->where('plant_id', $get('plant_id'))
->where('machine_id', $get('machine_id'))
->where('approver_type', trim($get('approver_type')))
->where('machine_name', trim($get('machine_name')))
->ignore($get('id'));
}),
Section::make('Approver - 1')
// ->description('Prevent abuse by limiting the number of requests per period')
@@ -168,7 +177,6 @@ class CharacteristicApproverMasterResource extends Resource
->required()
->suffixIcon('heroicon-m-envelope')
->suffixIconColor('primary')
->email()
->afterStateUpdated(function ($state, callable $set) {
$set('updated_by', Filament::auth()->user()?->name);
}),
@@ -205,7 +213,6 @@ class CharacteristicApproverMasterResource extends Resource
->reactive()
->suffixIcon('heroicon-m-envelope')
->suffixIconColor('primary')
->email()
->afterStateUpdated(function ($state, callable $set) {
$set('updated_by', Filament::auth()->user()?->name);
}),
@@ -238,7 +245,6 @@ class CharacteristicApproverMasterResource extends Resource
->reactive()
->suffixIcon('heroicon-m-envelope')
->suffixIconColor('primary')
->email()
->afterStateUpdated(function ($state, callable $set) {
$set('updated_by', Filament::auth()->user()?->name);
}),
@@ -284,7 +290,7 @@ class CharacteristicApproverMasterResource extends Resource
return ($currentPage - 1) * $perPage + $rowLoop->iteration;
}),
Tables\Columns\TextColumn::make('plant.name')
->label('Plant')
->label('Plant Name')
->alignCenter()
->searchable()
->sortable(),
@@ -298,6 +304,11 @@ class CharacteristicApproverMasterResource extends Resource
->alignCenter()
->searchable()
->sortable(),
Tables\Columns\TextColumn::make('machine_name')
->label('Machine Name')
->alignCenter()
->searchable()
->sortable(),
Tables\Columns\TextColumn::make('characteristic_field')
->label('Master Characteristic Field')
->alignCenter()
@@ -305,11 +316,6 @@ class CharacteristicApproverMasterResource extends Resource
->formatStateUsing(fn (string $state): string => strtoupper(__($state)))
->extraAttributes(['class' => 'uppercase'])
->sortable(),
Tables\Columns\TextColumn::make('machine_name')
->label('Machine Name')
->alignCenter()
->searchable()
->sortable(),
Tables\Columns\TextColumn::make('name1')
->label('Approver Name 1')
->alignCenter()

View File

@@ -19,12 +19,13 @@ use Filament\Tables\Actions\ImportAction;
use Filament\Tables\Table;
use Illuminate\Database\Eloquent\Builder;
use Illuminate\Database\Eloquent\SoftDeletingScope;
use Illuminate\Validation\Rule;
class ConfigurationResource extends Resource
{
protected static ?string $model = Configuration::class;
protected static ?string $navigationIcon = 'heroicon-o-rectangle-stack';
protected static ?string $navigationIcon = 'heroicon-s-cog';
protected static ?string $navigationGroup = 'Master Entries';
@@ -107,7 +108,16 @@ class ConfigurationResource extends Resource
->required(),
Forms\Components\TextInput::make('c_value')
->label('Value')
->required(),
->required()
->rule(function (callable $get) {
return Rule::unique('configurations', 'c_value')
->where('plant_id', $get('plant_id'))
->where('line_id', $get('line_id'))
->where('c_type', $get('c_type'))
->where('c_group', $get('c_group'))
->where('c_name', $get('c_name'))
->ignore($get('id')); // Ignore current record during updates
}),
Forms\Components\TextInput::make('id')
->hidden()
->readOnly(),

View File

@@ -0,0 +1,181 @@
<?php
namespace App\Filament\Resources;
use App\Filament\Resources\DuplicateStockResource\Pages;
use App\Models\DuplicateStock;
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 DuplicateStockResource extends Resource
{
protected static ?string $model = DuplicateStock::class;
protected static ?string $navigationIcon = 'heroicon-o-rectangle-stack';
protected static ?string $navigationGroup = 'Cycle Count Software';
public static function form(Form $form): Form
{
return $form
->schema([
Forms\Components\Select::make('stock_data_master_id')
->relationship('stockDataMaster', 'id')
->required(),
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('stockDataMaster.plant.name')
->label('Plant Name')
->alignCenter()
->searchable()
->sortable(),
Tables\Columns\TextColumn::make('stockDataMaster.stickerMaster.item.code')
->label('Item Code')
->alignCenter()
->searchable()
->sortable(),
Tables\Columns\TextColumn::make('stockDataMaster.location')
->label('Location')
->alignCenter()
->searchable()
->sortable(),
Tables\Columns\TextColumn::make('stockDataMaster.bin')
->label('Bin')
->alignCenter()
->searchable()
->sortable(),
Tables\Columns\TextColumn::make('stockDataMaster.serial_number')
->label('Serial Number')
->alignCenter()
->searchable()
->sortable(),
Tables\Columns\TextColumn::make('stockDataMaster.batch')
->label('Batch')
->alignCenter()
->searchable()
->sortable(),
Tables\Columns\TextColumn::make('stockDataMaster.quantity')
->label('Quantity')
->alignCenter()
->searchable()
->sortable(),
Tables\Columns\TextColumn::make('stockDataMaster.doc_no')
->label('Document Number')
->alignCenter()
->searchable()
->sortable(),
Tables\Columns\TextColumn::make('stockDataMaster.type')
->label('Type')
->alignCenter()
->searchable()
->formatStateUsing(fn ($state) => match ($state) {
'0' => 'FG',
'1' => 'NON-FG',
default => '-',
})
->sortable(),
Tables\Columns\TextColumn::make('stockDataMaster.motor_scanned_status')
->label('Motor Scanned Status')
->alignCenter()
->searchable()
->sortable(),
Tables\Columns\TextColumn::make('stockDataMaster.pump_scanned_status')
->label('Pump Scanned Status')
->alignCenter()
->searchable()
->sortable(),
Tables\Columns\TextColumn::make('stockDataMaster.capacitor_scanned_status')
->label('Capacitor Scanned Status')
->alignCenter()
->searchable()
->sortable(),
Tables\Columns\TextColumn::make('stockDataMaster.scanned_status_set')
->label('Scanned Status Set')
->alignCenter()
->searchable()
->sortable(),
Tables\Columns\TextColumn::make('stockDataMaster.scanned_status')
->label('Scanned Status')
->alignCenter()
->searchable()
->sortable(),
Tables\Columns\TextColumn::make('created_at')
->dateTime()
->sortable()
->toggleable(isToggledHiddenByDefault: true),
Tables\Columns\TextColumn::make('updated_at')
->dateTime()
->sortable()
->toggleable(isToggledHiddenByDefault: true),
Tables\Columns\TextColumn::make('deleted_at')
->dateTime()
->sortable()
->toggleable(isToggledHiddenByDefault: true),
])
->filters([
Tables\Filters\TrashedFilter::make(),
])
->actions([
Tables\Actions\ViewAction::make(),
Tables\Actions\EditAction::make(),
])
->bulkActions([
Tables\Actions\BulkActionGroup::make([
Tables\Actions\DeleteBulkAction::make(),
Tables\Actions\ForceDeleteBulkAction::make(),
Tables\Actions\RestoreBulkAction::make(),
]),
]);
}
public static function getRelations(): array
{
return [
//
];
}
public static function getPages(): array
{
return [
'index' => Pages\ListDuplicateStocks::route('/'),
'create' => Pages\CreateDuplicateStock::route('/create'),
'view' => Pages\ViewDuplicateStock::route('/{record}'),
'edit' => Pages\EditDuplicateStock::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\DuplicateStockResource\Pages;
use App\Filament\Resources\DuplicateStockResource;
use Filament\Actions;
use Filament\Resources\Pages\CreateRecord;
class CreateDuplicateStock extends CreateRecord
{
protected static string $resource = DuplicateStockResource::class;
}

View File

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

View File

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

View File

@@ -3,6 +3,7 @@
namespace App\Filament\Resources;
use AlperenErsoy\FilamentExport\Actions\FilamentExportBulkAction;
use App\Filament\Exports\AxnExporter;
use App\Filament\Exports\InvoiceValidationExporter;
use App\Filament\Imports\InvoiceValidationImporter;
use App\Filament\Resources\InvoiceValidationResource\Pages;
@@ -1134,13 +1135,20 @@ class InvoiceValidationResource extends Resource
->visible(function () {
return Filament::auth()->user()->can('view import invoice');
}),
ExportAction::make()
ExportAction::make('invoice_export')
->label('Export Invoices')
->color('warning')
->exporter(InvoiceValidationExporter::class)
->visible(function () {
return Filament::auth()->user()->can('view export invoice');
}),
ExportAction::make('axn_export')
->label('Export Asn')
->color('warning')
->exporter(AxnExporter::class)
->visible(function () {
return Filament::auth()->user()->can('view export asn invoice');
}),
])
->filters([

View File

@@ -48,10 +48,12 @@ class ItemResource extends Resource
Section::make('')
->schema([
Forms\Components\Select::make('plant_id')
->label('Plant Name')
->relationship('plant', 'name')
->required()
// ->preload()
// ->nullable(),
->searchable()
->reactive()
->options(function (callable $get) {
$userHas = Filament::auth()->user()->plant_id;
@@ -191,7 +193,7 @@ class ItemResource extends Resource
return ($currentPage - 1) * $perPage + $rowLoop->iteration;
}),
Tables\Columns\TextColumn::make('plant.name')
->label('Plant')
->label('Plant Name')
->alignCenter()
->sortable()
->searchable(),
@@ -230,8 +232,7 @@ class ItemResource extends Resource
->label('Updated At')
->dateTime()
->alignCenter()
->sortable()
->toggleable(isToggledHiddenByDefault: true),
->sortable(),
Tables\Columns\TextColumn::make('deleted_at')
->label('Deleted At')
->dateTime()
@@ -246,13 +247,21 @@ class ItemResource extends Resource
->label('Advanced Filters')
->form([
Select::make('Plant')
->label('Select 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();
// 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('items', function ($query) {
$query->whereNotNull('id');
})->orderBy('code')->pluck('name', 'id')->toArray();
}
})
->searchable()
->reactive()
->afterStateUpdated(function ($state, callable $set, callable $get): void {
$set('code', null);
@@ -319,12 +328,24 @@ class ItemResource extends Resource
}
if (! empty($data['uom'])) {
if ($data['uom'] == 'empty') {
$query->where(function ($q) {
$q->where('uom', '')->orWhereNull('uom');
});
} else {
$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'].'%');
}
}
if (! empty($data['created_from'])) {
$query->where('created_at', '>=', $data['created_from']);
@@ -356,11 +377,11 @@ class ItemResource extends Resource
}
if (! empty($data['uom'])) {
$indicators[] = 'UOM: '.$data['uom'];
$indicators[] = ($data['uom'] == 'empty') ? "UOM: ''" : 'UOM: '.$data['uom'];
}
if (! empty($data['category'])) {
$indicators[] = 'Category: '.$data['category'];
$indicators[] = ($data['category'] == 'empty') ? "Category: ''" : 'Category: '.$data['category'];
}
if (! empty($data['created_from'])) {

View File

@@ -42,9 +42,10 @@ class MotorTestingMasterResource extends Resource
return $form
->schema([
Forms\Components\Select::make('plant_id')
->label('Plant')
->label('Plant Name')
->relationship('plant', 'name')
->required()
->searchable()
->reactive()
->options(function (callable $get) {
$userHas = Filament::auth()->user()->plant_id;
@@ -64,6 +65,8 @@ class MotorTestingMasterResource extends Resource
} else {
$set('mTmError', null);
}
$set('updated_by', Filament::auth()->user()?->name);
})
->extraAttributes(fn ($get) => [
'class' => $get('mTmError') ? 'border-red-500' : '',
@@ -74,6 +77,9 @@ class MotorTestingMasterResource extends Resource
->label('Routine Test Time')
->default('00:40:00')
->required()
->afterStateUpdated(function (callable $set, callable $get, ?string $state) {
$set('updated_by', Filament::auth()->user()?->name);
})
->reactive(),
Forms\Components\Select::make('item_id')
->label('Item Code')
@@ -84,13 +90,27 @@ class MotorTestingMasterResource extends Resource
return [];
}
if (! $get('id')) {
// whereHas
return Item::where('plant_id', $plantId)->whereDoesntHave('motorTestingMasters')->pluck('code', 'id');
} else {
$itemId = MotorTestingMaster::where('id', $get('id'))->first()?->item_id;
return Item::where('plant_id', $plantId)
->pluck('code', 'id')
->toArray();
->where(function ($query) use ($itemId) {
$query->whereDoesntHave('motorTestingMasters')
->orWhere('id', $itemId);
})
->pluck('code', 'id');
}
// return Item::where('plant_id', $plantId)->pluck('code', 'id')->toArray();
})
->required()
->searchable()
->reactive()
->afterStateUpdated(function (callable $set, callable $get, ?string $state) {
$set('updated_by', Filament::auth()->user()?->name);
})
->rule(function (callable $get) {
return Rule::unique('motor_testing_masters', 'item_id')
->where('plant_id', $get('plant_id'))
@@ -98,7 +118,7 @@ class MotorTestingMasterResource extends Resource
}),
Forms\Components\TextInput::make('subassembly_code')
->label('Subassembly Code')
->required()
// ->required()
->placeholder('Scan the valid code')
->reactive()
->alphaNum()
@@ -122,6 +142,8 @@ class MotorTestingMasterResource extends Resource
}
$set('iCodeError', null);
}
$set('updated_by', Filament::auth()->user()?->name);
})
->extraAttributes(fn ($get) => [
'class' => $get('iCodeError') ? 'border-red-500' : '',
@@ -138,6 +160,9 @@ class MotorTestingMasterResource extends Resource
->selectablePlaceholder(false)
->default(1)
->required()
->afterStateUpdated(function (callable $set, callable $get, ?string $state) {
$set('updated_by', Filament::auth()->user()?->name);
})
->reactive(),
Forms\Components\Select::make('phase')
->label('Phase')
@@ -159,35 +184,57 @@ class MotorTestingMasterResource extends Resource
})
->selectablePlaceholder(false)
->afterStateUpdated(function ($state, callable $set, callable $get) {
if ($state == 'Single' && $get('connection') == 'Star-Delta') {
$set('phase', 'Three');
}
$set('updated_by', Filament::auth()->user()?->name);
})
->default('Single')
->required()
->reactive(),
Forms\Components\TextInput::make('hp')
->label('HP')
->required(),
->required()
->afterStateUpdated(function (callable $set, callable $get, ?string $state) {
$set('updated_by', Filament::auth()->user()?->name);
}),
Forms\Components\TextInput::make('kw')
->label('KW')
->required(),
->required()
->afterStateUpdated(function (callable $set, callable $get, ?string $state) {
$set('updated_by', Filament::auth()->user()?->name);
}),
Forms\Components\TextInput::make('volt')
->label('Volt')
->required(),
->required()
->afterStateUpdated(function (callable $set, callable $get, ?string $state) {
$set('updated_by', Filament::auth()->user()?->name);
}),
Forms\Components\TextInput::make('current')
->label('Current')
->required(),
->required()
->afterStateUpdated(function (callable $set, callable $get, ?string $state) {
$set('updated_by', Filament::auth()->user()?->name);
}),
Forms\Components\TextInput::make('rpm')
->label('RPM')
->required(),
->required()
->afterStateUpdated(function (callable $set, callable $get, ?string $state) {
$set('updated_by', Filament::auth()->user()?->name);
}),
Forms\Components\TextInput::make('torque')
->label('Torque')
->required(),
->required()
->afterStateUpdated(function (callable $set, callable $get, ?string $state) {
$set('updated_by', Filament::auth()->user()?->name);
}),
Forms\Components\TextInput::make('frequency')
->label('Frequency')
->required(),
->required()
->afterStateUpdated(function (callable $set, callable $get, ?string $state) {
$set('updated_by', Filament::auth()->user()?->name);
}),
Forms\Components\Select::make('connection')
->label('Connection')
->selectablePlaceholder(false)
@@ -210,12 +257,17 @@ class MotorTestingMasterResource extends Resource
if ($state == 'Star-Delta') {
$set('phase', 'Three');
}
$set('updated_by', Filament::auth()->user()?->name);
})
->required()
->default('Star')
->reactive(),
Forms\Components\TextInput::make('ins_res_limit')
->label('Insulation Resistance Limit')
->afterStateUpdated(function (callable $set, callable $get, ?string $state) {
$set('updated_by', Filament::auth()->user()?->name);
})
->required(),
Forms\Components\Select::make('ins_res_type')
->label('Insulation Resistance Type')
@@ -236,55 +288,106 @@ class MotorTestingMasterResource extends Resource
->toArray();
}
})
->required(),
->required()
->afterStateUpdated(function (callable $set, callable $get, ?string $state) {
$set('updated_by', Filament::auth()->user()?->name);
}),
Forms\Components\TextInput::make('res_ry_ll')
->label('Resistance RY LL')
->required(),
->required()
->afterStateUpdated(function (callable $set, callable $get, ?string $state) {
$set('updated_by', Filament::auth()->user()?->name);
}),
Forms\Components\TextInput::make('res_ry_ul')
->label('Resistance RY UL')
->required(),
->required()
->afterStateUpdated(function (callable $set, callable $get, ?string $state) {
$set('updated_by', Filament::auth()->user()?->name);
}),
Forms\Components\TextInput::make('res_yb_ll')
->label('Resistance YB LL')
->required(),
->required()
->afterStateUpdated(function (callable $set, callable $get, ?string $state) {
$set('updated_by', Filament::auth()->user()?->name);
}),
Forms\Components\TextInput::make('res_yb_ul')
->label('Resistance YB UL')
->required(),
->required()
->afterStateUpdated(function (callable $set, callable $get, ?string $state) {
$set('updated_by', Filament::auth()->user()?->name);
}),
Forms\Components\TextInput::make('res_br_ll')
->label('Resistance BR LL')
->required(),
->required()
->afterStateUpdated(function (callable $set, callable $get, ?string $state) {
$set('updated_by', Filament::auth()->user()?->name);
}),
Forms\Components\TextInput::make('res_br_ul')
->label('Resistance BR UL')
->required(),
->required()
->afterStateUpdated(function (callable $set, callable $get, ?string $state) {
$set('updated_by', Filament::auth()->user()?->name);
}),
Forms\Components\TextInput::make('lock_volt_limit')
->label('Lock Volt Limit')
->required(),
->required()
->afterStateUpdated(function (callable $set, callable $get, ?string $state) {
$set('updated_by', Filament::auth()->user()?->name);
}),
Forms\Components\TextInput::make('leak_cur_limit')
->label('Leakage Current Limit')
->required(),
->required()
->afterStateUpdated(function (callable $set, callable $get, ?string $state) {
$set('updated_by', Filament::auth()->user()?->name);
}),
Forms\Components\TextInput::make('lock_cur_ll')
->label('Lock Current LL')
->required(),
->required()
->afterStateUpdated(function (callable $set, callable $get, ?string $state) {
$set('updated_by', Filament::auth()->user()?->name);
}),
Forms\Components\TextInput::make('lock_cur_ul')
->label('Lock Current UL')
->required(),
->required()
->afterStateUpdated(function (callable $set, callable $get, ?string $state) {
$set('updated_by', Filament::auth()->user()?->name);
}),
Forms\Components\TextInput::make('noload_cur_ll')
->label('No Load Current LL')
->required(),
->required()
->afterStateUpdated(function (callable $set, callable $get, ?string $state) {
$set('updated_by', Filament::auth()->user()?->name);
}),
Forms\Components\TextInput::make('noload_cur_ul')
->label('No Load Current UL')
->required(),
->required()
->afterStateUpdated(function (callable $set, callable $get, ?string $state) {
$set('updated_by', Filament::auth()->user()?->name);
}),
Forms\Components\TextInput::make('noload_pow_ll')
->label('No Load Power LL')
->required(),
->required()
->afterStateUpdated(function (callable $set, callable $get, ?string $state) {
$set('updated_by', Filament::auth()->user()?->name);
}),
Forms\Components\TextInput::make('noload_pow_ul')
->label('No Load Power UL')
->required(),
->required()
->afterStateUpdated(function (callable $set, callable $get, ?string $state) {
$set('updated_by', Filament::auth()->user()?->name);
}),
Forms\Components\TextInput::make('noload_spd_ll')
->label('No Load Speed LL')
->required(),
->required()
->afterStateUpdated(function (callable $set, callable $get, ?string $state) {
$set('updated_by', Filament::auth()->user()?->name);
}),
Forms\Components\TextInput::make('noload_spd_ul')
->label('No Load Speed UL')
->required(),
->required()
->afterStateUpdated(function (callable $set, callable $get, ?string $state) {
$set('updated_by', Filament::auth()->user()?->name);
}),
Forms\Components\Hidden::make('created_by')
->default(fn () => Filament::auth()->user()?->name)
->required(),
@@ -311,7 +414,7 @@ class MotorTestingMasterResource extends Resource
return ($currentPage - 1) * $perPage + $rowLoop->iteration;
}),
Tables\Columns\TextColumn::make('plant.name')
->label('Plant')
->label('Plant Name')
->searchable()
->alignCenter()
->sortable(),
@@ -458,17 +561,26 @@ class MotorTestingMasterResource extends Resource
->label('Advanced Filters')
->form([
Select::make('Plant')
->label('Select Plant')
->label('Search by Plant Name')
->nullable()
->searchable()
->reactive()
// ->options(function () {
// return 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::orderBy('code')->pluck('name', 'id')->toArray();
if ($userHas && strlen($userHas) > 0) {
return Plant::where('id', $userHas)->pluck('name', 'id')->toArray();
} else {
return Plant::whereHas('motorTestingMasters', function ($query) {
$query->whereNotNull('id');
})->orderBy('code')->pluck('name', 'id');
}
// return ($userHas && strlen($userHas) > 0) ? Plant::where('id', $userHas)->pluck('name', 'id')->toArray() : Plant::orderBy('code')->pluck('name', 'id')->toArray();
})
->reactive()
->afterStateUpdated(function ($state, callable $set, callable $get) {
$set('Item', null);
$set('isi_type', null);
@@ -681,7 +793,7 @@ class MotorTestingMasterResource extends Resource
$indicators = [];
if (! empty($data['Plant'])) {
$indicators[] = 'Plant: '.Plant::where('id', $data['Plant'])->value('name');
$indicators[] = 'Plant Name: '.Plant::where('id', $data['Plant'])->value('name');
} else {
$userHas = Filament::auth()->user()->plant_id;

View File

@@ -0,0 +1,284 @@
<?php
namespace App\Filament\Resources;
use App\Filament\Exports\NotInStockExporter;
use App\Filament\Imports\NotInStockImporter;
use App\Filament\Resources\NotInStockResource\Pages;
use App\Models\NotInStock;
use App\Models\StickerMaster;
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 NotInStockResource extends Resource
{
protected static ?string $model = NotInStock::class;
protected static ?string $navigationIcon = 'heroicon-o-rectangle-stack';
protected static ?string $navigationGroup = 'Cycle Count Software';
public static function form(Form $form): Form
{
return $form
->schema([
Forms\Components\Select::make('plant_id')
->label('Plant')
->reactive()
->relationship('plant', 'name')
->required(),
Forms\Components\Select::make('sticker_master_id')
->label('Item Code')
->reactive()
->required()
->searchable()
->options(function ($get) {
if (! $get('plant_id')) {
return [];
}
return StickerMaster::with('item')
->where('plant_id', $get('plant_id'))
->get()
->pluck('item.code', 'id')
->toArray();
}),
Forms\Components\TextInput::make('location')
->label('Location'),
Forms\Components\TextInput::make('bin')
->label('Bin'),
Forms\Components\TextInput::make('serial_number')
->label('Serial Number'),
Forms\Components\TextInput::make('batch')
->label('Batch'),
Forms\Components\TextInput::make('quantity')
->label('Quantity'),
Forms\Components\TextInput::make('doc_no')
->label('Doc No'),
Forms\Components\Select::make('type')
->label('Type')
->options([
'0' => 'FG',
'1' => 'NON-FG',
]),
Forms\Components\TextInput::make('motor_scanned_status')
->label('Motor Scanned Status'),
Forms\Components\TextInput::make('pump_scanned_status')
->label('Pump Scanned Status'),
Forms\Components\TextInput::make('capacitor_scanned_status')
->label('Capacitor Scanned Status'),
Forms\Components\TextInput::make('scanned_status_set')
->label('Scanned Status Set'),
Forms\Components\TextInput::make('panel_box_item_code')
->label('Panel Box Item Code'),
Forms\Components\TextInput::make('panel_box_supplier')
->label('Panel Box Supplier'),
Forms\Components\TextInput::make('panel_box_sno')
->label('Panel Box Sno'),
Forms\Components\TextInput::make('scanned_status')
->label('Scanned Status'),
Forms\Components\TextInput::make('scanned_quantity')
->label('Scanned Quantity'),
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('stickerMaster.item.code')
->label('Item Code')
->alignCenter()
->searchable()
->sortable(),
Tables\Columns\TextColumn::make('type')
->label('Type')
->alignCenter()
->searchable()
->formatStateUsing(fn ($state) => match ($state) {
'0' => 'FG',
'1' => 'NON-FG',
default => '-',
})
->sortable(),
Tables\Columns\TextColumn::make('location')
->label('Location')
->alignCenter()
->searchable()
->sortable(),
Tables\Columns\TextColumn::make('bin')
->label('Bin')
->alignCenter()
->searchable()
->sortable(),
Tables\Columns\TextColumn::make('serial_number')
->label('Serial Number')
->alignCenter()
->searchable()
->sortable(),
Tables\Columns\TextColumn::make('batch')
->label('Batch')
->alignCenter()
->searchable()
->sortable(),
Tables\Columns\TextColumn::make('quantity')
->label('Quantity')
->alignCenter()
->searchable()
->sortable(),
Tables\Columns\TextColumn::make('doc_no')
->label('Document Number')
->alignCenter()
->searchable()
->sortable(),
Tables\Columns\TextColumn::make('motor_scanned_status')
->label('Motor Scanned Status')
->alignCenter()
->searchable()
->sortable(),
Tables\Columns\TextColumn::make('pump_scanned_status')
->label('Pump Scanned Status')
->alignCenter()
->searchable()
->sortable(),
Tables\Columns\TextColumn::make('capacitor_scanned_status')
->label('Capacitor Scanned Status')
->alignCenter()
->searchable()
->sortable(),
Tables\Columns\TextColumn::make('scanned_status_set')
->label('Scanned Status Set')
->alignCenter()
->searchable()
->sortable(),
Tables\Columns\TextColumn::make('panel_box_item_code')
->label('Panel Box Item Code')
->alignCenter()
->searchable()
->sortable(),
Tables\Columns\TextColumn::make('panel_box_supplier')
->label('Panel Box Supplier')
->alignCenter()
->searchable()
->sortable(),
Tables\Columns\TextColumn::make('panel_box_sno')
->label('Panel Box Serial Number')
->alignCenter()
->searchable()
->sortable(),
Tables\Columns\TextColumn::make('scanned_status')
->label('Scanned Status')
->alignCenter()
->searchable()
->sortable(),
Tables\Columns\TextColumn::make('scanned_quantity')
->label('Scanned Quantity')
->alignCenter()
->searchable()
->sortable(),
Tables\Columns\TextColumn::make('created_at')
->label('Created At')
->alignCenter()
->dateTime()
->sortable()
->toggleable(isToggledHiddenByDefault: true),
Tables\Columns\TextColumn::make('updated_at')
->label('Updated At')
->alignCenter()
->dateTime()
->sortable()
->toggleable(isToggledHiddenByDefault: true),
Tables\Columns\TextColumn::make('deleted_at')
->label('Deleted At')
->alignCenter()
->dateTime()
->sortable()
->toggleable(isToggledHiddenByDefault: true),
])
->filters([
Tables\Filters\TrashedFilter::make(),
])
->actions([
Tables\Actions\ViewAction::make(),
Tables\Actions\EditAction::make(),
])
->bulkActions([
Tables\Actions\BulkActionGroup::make([
Tables\Actions\DeleteBulkAction::make(),
Tables\Actions\ForceDeleteBulkAction::make(),
Tables\Actions\RestoreBulkAction::make(),
]),
])
->headerActions([
ImportAction::make()
->label('Import Not In Stock')
->color('warning')
->importer(NotInStockImporter::class)
->visible(function () {
return Filament::auth()->user()->can('view import not in stock');
}),
ExportAction::make()
->label('Export Not In Stock')
->color('warning')
->exporter(NotInStockExporter::class)
->visible(function () {
return Filament::auth()->user()->can('view export not in stock');
}),
]);
}
public static function getRelations(): array
{
return [
//
];
}
public static function getPages(): array
{
return [
'index' => Pages\ListNotInStocks::route('/'),
'create' => Pages\CreateNotInStock::route('/create'),
'view' => Pages\ViewNotInStock::route('/{record}'),
'edit' => Pages\EditNotInStock::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\NotInStockResource\Pages;
use App\Filament\Resources\NotInStockResource;
use Filament\Actions;
use Filament\Resources\Pages\CreateRecord;
class CreateNotInStock extends CreateRecord
{
protected static string $resource = NotInStockResource::class;
}

View File

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

View File

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

View File

@@ -9,6 +9,7 @@ use App\Models\Item;
use App\Models\Line;
use App\Models\Plant;
use App\Models\ProcessOrder;
use App\Models\ProductCharacteristicsMaster;
use Closure;
use Filament\Facades\Filament;
use Filament\Forms;
@@ -74,6 +75,7 @@ class ProcessOrderResource extends Resource
$set('process_order', null);
$set('coil_number', '0');
$set('order_quantity', '0');
$set('updated_order_quantity', '0');
$set('received_quantity', '0');
$set('scrap_quantity', '0');
$set('sfg_number', null);
@@ -113,6 +115,7 @@ class ProcessOrderResource extends Resource
$set('process_order', null);
$set('coil_number', '0');
$set('order_quantity', '0');
$set('updated_order_quantity', '0');
$set('received_quantity', '0');
$set('scrap_quantity', '0');
$set('sfg_number', null);
@@ -128,10 +131,14 @@ class ProcessOrderResource extends Resource
->reactive()
->options(function (callable $get) {
$plantId = $get('plant_id');
if (empty($plantId)) {
// $lineId = $get('line_id');
if (empty($plantId)) {// || empty($lineId)
return [];
}
// $availItems = ProductCharacteristicsMaster::where('plant_id', $plantId)->where('line_id', $lineId)->pluck('item_id', 'item_id')->toArray();
// return Item::where('plant_id', $plantId)->whereIn('id', $availItems)->pluck('code', 'id');
return Item::where('plant_id', $plantId)->pluck('code', 'id');
})
->disabled(fn (Get $get) => ! empty($get('id')))
@@ -141,6 +148,7 @@ class ProcessOrderResource extends Resource
$set('process_order', null);
$set('coil_number', '0');
$set('order_quantity', '0');
$set('updated_order_quantity', '0');
$set('received_quantity', '0');
$set('scrap_quantity', '0');
$set('sfg_number', null);
@@ -217,6 +225,7 @@ class ProcessOrderResource extends Resource
$plantId = $get('plant_id');
$set('coil_number', '0');
$set('order_quantity', '0');
$set('updated_order_quantity', '0');
$set('received_quantity', '0');
$set('scrap_quantity', '0');
$set('sfg_number', null);
@@ -280,10 +289,10 @@ class ProcessOrderResource extends Resource
->required()
->reactive()
->numeric()
->readOnly(fn ($get) => ($get('process_order') == null))
->readOnly(fn ($get) => (trim($get('process_order')) == null || trim($get('process_order')) == ''))
->afterStateUpdated(function ($state, $set, callable $get, $livewire) {
$plantId = $get('plant_id');
$processOrder = $get('process_order');
$processOrder = trim($get('process_order'));
// $coilNo = $get('coil_number');
if (! $plantId) {
$set('poPlantError', 'Please select a plant first.');
@@ -319,22 +328,37 @@ class ProcessOrderResource extends Resource
function (callable $get) {
return Rule::unique('process_orders', 'coil_number')
->where('plant_id', $get('plant_id'))
->where('process_order', $get('process_order'))
->where('process_order', trim($get('process_order')))
->ignore($get('id'));
},
function (callable $get): Closure {
return function (string $attribute, $value, Closure $fail) use ($get) {
$rework = $get('rework_status');
if ($value && Str::contains($value, '.') && $rework == 0) {
$plantId = $get('plant_id');
$processOrder = trim($get('process_order'));
if ($value && Str::contains($value, '.')) {
if ($rework == 0) {
$fail("Rework status should be 'Yes' for rework coil number '{$value}'!");
}
} elseif ($value > 1) {
$prevCoilNo = (string) ($value - 1);
$existPrevCoil = ProcessOrder::where('plant_id', $plantId)
->where('process_order', $processOrder)
->where('coil_number', $prevCoilNo)
->first();
if (! $existPrevCoil) {
$fail("Previous coil number '{$prevCoilNo}' not exist against plant and process order!");
}
}
};
},
])
// ->rule(function (callable $get) {
// return Rule::unique('process_orders', 'coil_number')
// ->where('plant_id', $get('plant_id'))
// ->where('process_order', $get('process_order'))
// ->where('process_order', trim($get('process_order')))
// ->ignore($get('id'));
// })
->extraAttributes(fn ($get) => [
@@ -348,15 +372,17 @@ class ProcessOrderResource extends Resource
->required()
->reactive()
->numeric()
->readOnly(fn ($get) => ($get('process_order') == null))
->readOnly(fn ($get) => (trim($get('process_order')) == null || trim($get('process_order')) == ''))
->afterStateUpdated(function (callable $set, callable $get, ?string $state) {
$plantId = $get('plant_id');
$itemId = $get('item_id');
$processOrder = trim($get('process_order'));
$set('received_quantity', '0');
// $set('updated_order_quantity', $state);
$set('scrap_quantity', '0');
if (! $plantId || ! $itemId || ! $processOrder) {
$set('order_quantity', '0');
$set('updated_order_quantity', '0');
}
$query = ProcessOrder::where('plant_id', $plantId)
@@ -372,13 +398,175 @@ class ProcessOrderResource extends Resource
}
$set('updated_by', Filament::auth()->user()?->name);
}),
Forms\Components\TextInput::make('updated_order_quantity')
->label('Updated Order Quantity')
->required()
->readOnly(fn ($get) => (trim($get('process_order')) == null || trim($get('process_order')) == '' || trim($get('order_quantity')) == '' || trim($get('order_quantity')) == null))
->reactive()
->rules([
function (callable $get): Closure {
return function (string $attribute, $value, Closure $fail) use ($get) {
$plantId = $get('plant_id');
$processOrder = trim($get('process_order'));
$receivedQty = $get('received_quantity');
$currentId = $get('id');
$orderQty = (float) $get('order_quantity');
$updatedQty = (float) $value;
$allowedVariance = $orderQty * 0.10;
$maxAllowed = $orderQty + $allowedVariance;
$minAllowed = $orderQty - $allowedVariance;
if ($updatedQty > $maxAllowed || $updatedQty < $minAllowed) {
$fail('Quantity can vary by ±10% of the order quantity.');
}
$otherReceivedQty = ProcessOrder::where('plant_id', $plantId)
->where('process_order', $processOrder)
->when($currentId, fn ($q) => $q->where('id', '!=', $currentId))
->sum('received_quantity');
$currentReceivedQty = (float) $get('received_quantity');
$totalReceivedQty = $otherReceivedQty + $currentReceivedQty;
if ($updatedQty < $totalReceivedQty) {
$fail("You cannot set quantity below received quantity ({$totalReceivedQty}).");
}
};
},
]),
Forms\Components\TextInput::make('received_quantity')
->label('Received Quantity')
->default('0.000')
->required()
->reactive()
->numeric()
->readOnly(fn ($get) => ($get('process_order') == null))
->maxValue(fn (Get $get) => $get('order_quantity') ?? PHP_INT_MAX)
->readOnly(fn ($get) => (trim($get('process_order')) == null || trim($get('process_order')) == ''))
->rule(function (callable $get) {
return function (string $attribute, $value, Closure $fail) use ($get) {
$rework = $get('rework_status');
$plantId = $get('plant_id');
$lineId = $get('line_id');
$itemId = $get('item_id');
$processOrder = trim($get('process_order'));
$coilNo = trim($get('coil_number'));
$orderExist = ProcessOrder::where('plant_id', $plantId)
->where('process_order', $processOrder)
->where('item_id', $itemId)->latest()->first();
if ($orderExist) {
// $orderQty = $orderExist->order_quantity ?? 0;
$orderQty = $orderExist->updated_order_quantity ?? 0;
$alreadyReceived = ProcessOrder::where('plant_id', $plantId)
->where('process_order', $processOrder)
->where('item_id', $itemId)
->sum('received_quantity');
$total = $alreadyReceived + $value;
if ($rework == 1) {
if ($coilNo && Str::contains($coilNo, '.')) {
$coilMain = explode('.', $coilNo)[0];
$existingCoil = ProcessOrder::where('plant_id', $plantId)
->where('process_order', $processOrder)
->where('line_id', $lineId)
->where('coil_number', $coilMain)
->first();
$existPrevCoil = ProcessOrder::where('plant_id', $plantId)
->where('process_order', $processOrder)
->where('item_id', $itemId)
->where('coil_number', $coilNo)
->first();
if ($existPrevCoil && $existPrevCoil->received_quantity < $value) {
$fail('Rework received quantity should not exceed exist received quantity!');
return;
}
if ($existingCoil && $existingCoil->rework_status == 1 && $total > $orderQty) {
$fail("Rework received quantity should not exceed exist order quantity! Already Exist Total Received Qty = '{$alreadyReceived}'.");
}
} else {
if ($coilNo > 1) {
$prevCoilNo = (string) ($coilNo - 1);
$existPrevCoil = ProcessOrder::where('plant_id', $plantId)
->where('process_order', $processOrder)
->where('coil_number', $prevCoilNo)
->first();
if (! $existPrevCoil) {
return;
}
}
$existingCoil = ProcessOrder::where('plant_id', $plantId)
->where('process_order', $processOrder)
->where('line_id', $lineId)
->where('coil_number', $coilNo)
->first();
if (! $existingCoil) {
return;
}
$existPrevCoil = ProcessOrder::where('plant_id', $plantId)
->where('process_order', $processOrder)
->where('item_id', $itemId)
->where('coil_number', $coilNo)
->first();
if ($existPrevCoil && $existPrevCoil->received_quantity < $value) {
$fail('Rework received quantity should not exceed exist received quantity!');
return;
}
}
} else {
if ($coilNo && Str::contains($coilNo, '.')) {
return;
}
$existing = ProcessOrder::where('plant_id', $plantId)
->where('process_order', $processOrder)
->where('coil_number', $coilNo)
->first();
if ($existing) {
if ($existing->received_quantity < $value) {
$fail('Received quantity should not exceed exist received quantity!'); // Exist Received Qty = '{$existing->received_quantity}'.
}
return;
}
if ($coilNo > 1) {
$prevCoilNo = (string) ($coilNo - 1);
$existPrevCoil = ProcessOrder::where('plant_id', $plantId)
->where('process_order', $processOrder)
->where('coil_number', $prevCoilNo)
->first();
if (! $existPrevCoil) {
return;
}
}
if ($total > $orderQty) {
$fail("Received quantity should not exceed exist order quantity! Already Exist Total Received Qty = '{$alreadyReceived}'.");
}
}
}
};
})
->afterStateUpdated(function (callable $set, callable $get, ?string $state) {
$set('scrap_quantity', '0');
$set('updated_by', Filament::auth()->user()?->name);
@@ -387,7 +575,7 @@ class ProcessOrderResource extends Resource
->label('Scrap Quantity')
->default('0.000')
->required()
->readOnly(fn ($get) => ($get('rework_status') == 0 || $get('process_order') == null))
->readOnly(fn ($get) => ($get('rework_status') == 0 || trim($get('process_order')) == null || trim($get('process_order')) == ''))
->reactive()
->numeric()
->afterStateUpdated(function (callable $set, callable $get, ?string $state) {
@@ -414,7 +602,7 @@ class ProcessOrderResource extends Resource
Forms\Components\TextInput::make('sfg_number')
->label('SFG Number')
->reactive()
->readOnly(fn ($get) => ($get('process_order') == null))
->readOnly(fn ($get) => (trim($get('process_order')) == null || trim($get('process_order')) == ''))
->afterStateUpdated(function ($state, $set, callable $get, $livewire) {
$plantId = $get('plant_id');
$sfgNo = $get('sfg_number');
@@ -448,7 +636,8 @@ class ProcessOrderResource extends Resource
Forms\Components\TextInput::make('machine_name')
->label('Machine Name')
->reactive()
->readOnly(fn ($get) => ($get('process_order') == null))
->maxLength(18)
->readOnly(fn ($get) => (trim($get('process_order')) == null || trim($get('process_order')) == ''))
->afterStateUpdated(function (callable $set, callable $get, ?string $state) {
$set('updated_by', Filament::auth()->user()?->name);
}),
@@ -539,6 +728,7 @@ class ProcessOrderResource extends Resource
if ($uploaded instanceof TemporaryUploadedFile) {
$originalName = $uploaded->getClientOriginalName();
$path = 'uploads/ProcessOrder/'.$originalName;
$processOrder = trim($get('process_order'));
// Check if file already exists
if (Storage::disk('local')->exists($path)) {
@@ -576,34 +766,34 @@ class ProcessOrderResource extends Resource
}
// Get the value of process_order field
$processOrder = $get('process_order');
if ($batchId != $processOrder) {
Notification::make()
->title('Mismatch')
->body("Batch ID ($batchId) does not match Process Order ($processOrder)")
->danger()
->send();
return;
}
// if ($batchId != $processOrder) {
// Notification::make()
// ->title('Mismatch')
// ->body("Batch ID ($batchId) does not match Process Order ($processOrder)")
// ->danger()
// ->send();
if ($batchId == $processOrder) {
// return;
// }
// if ($batchId == $processOrder) {
// If batch matches, store the PDF permanently
$storedPath = $uploaded->storeAs(
'uploads/ProcessOrder',
$originalName,
$processOrder,
'local'
);
Notification::make()
->title('Success')
->body("Batch ID matches Process Order: $batchId. PDF uploaded successfully.")
->body("Process Order: $processOrder. PDF uploaded successfully.")
->success()
->send();
return;
}
// }
}
} else {
Notification::make()
@@ -621,7 +811,7 @@ class ProcessOrderResource extends Resource
return Filament::auth()->user()->can('view process order packing slip');
})
->action(function ($get, callable $set) {
$equipmentNumber = $get('process_order');
$equipmentNumber = trim($get('process_order'));
$set('updated_by', Filament::auth()->user()?->name);
if (! $equipmentNumber) {
@@ -720,6 +910,11 @@ class ProcessOrderResource extends Resource
->alignCenter()
->searchable()
->sortable(),
Tables\Columns\TextColumn::make('updated_order_quantity')
->label('Updated Order Quantity')
->alignCenter()
->searchable()
->sortable(),
Tables\Columns\TextColumn::make('received_quantity')
->label('Received Quantity')
->alignCenter()
@@ -1064,7 +1259,7 @@ class ProcessOrderResource extends Resource
->options(function (callable $get) {
$plantId = $get('plant');
$itemId = $get('Item');
$processOrder = $get('process_order');
$processOrder = trim($get('process_order'));
if (empty($plantId) || empty($itemId) || empty($processOrder)) {
return [];
@@ -1081,7 +1276,7 @@ class ProcessOrderResource extends Resource
->afterStateUpdated(function ($state, callable $set, callable $get) {
$plantId = $get('plant');
$itemId = $get('Item');
$processOrder = $get('process_order');
$processOrder = trim($get('process_order'));
if (! $plantId || ! $itemId || ! $processOrder || ! $state) {
$set('received_quantity', null);

View File

@@ -3,10 +3,28 @@
namespace App\Filament\Resources\ProcessOrderResource\Pages;
use App\Filament\Resources\ProcessOrderResource;
use App\Models\ProcessOrder;
use Filament\Actions;
use Filament\Facades\Filament;
use Filament\Notifications\Notification;
use Filament\Resources\Pages\CreateRecord;
class CreateProcessOrder extends CreateRecord
{
protected static string $resource = ProcessOrderResource::class;
protected function afterCreate(): void
{
$plantId = $this->data['plant_id'];
$processOrder = $this->data['process_order'];
$updatedQty = (float) $this->data['updated_order_quantity'];
ProcessOrder::where('plant_id', $plantId)
->where('process_order', $processOrder)
->update([
'updated_order_quantity' => $updatedQty,
'updated_by' => Filament::auth()->user()->name,
]);
}
}

View File

@@ -3,13 +3,78 @@
namespace App\Filament\Resources\ProcessOrderResource\Pages;
use App\Filament\Resources\ProcessOrderResource;
use App\Models\ProcessOrder;
use Filament\Actions;
use Filament\Facades\Filament;
use Filament\Notifications\Notification;
use Filament\Resources\Pages\EditRecord;
class EditProcessOrder extends EditRecord
{
protected static string $resource = ProcessOrderResource::class;
protected function beforeSave(): void
{
$plantId = $this->data['plant_id'] ?? null;
$processOrder = $this->data['process_order'] ?? null;
$extraQty = (float) ($this->data['updated_order_quantity'] ?? 0);
$extraQtyRaw = $this->data['updated_order_quantity'] ?? '';
if (!preg_match('/^\d+(\.\d{1,3})?$/', $extraQtyRaw)) {
Notification::make()
->title('Invalid Quantity')
->body('Only positive numbers with up to 3 decimal places are allowed.')
->danger()
->send();
$this->halt(); // stop save
}
if ($extraQty < 0)
{
Notification::make()
->title('Invalid Quantity')
->body('Negative values are not allowed.')
->danger()
->send();
$this->halt();
}
if ($extraQty > 0) {
$order = ProcessOrder::where('plant_id', $plantId)
->where('process_order', $processOrder)
->first();
if ($order) {
$baseQty = (float) $order->order_quantity;
$maxAllowed = $baseQty * 0.10;
$maxFinalQty = $baseQty + $maxAllowed;
if ($extraQty > $maxFinalQty) {
Notification::make()
->title('Limit Exceeded')
->body("You can only increase the order by 10% (Max allowed: {$maxFinalQty}).")
->danger()
->send();
$this->halt(); // stops save
}
ProcessOrder::where('plant_id', $plantId)
->where('process_order', $processOrder)
->update([
'updated_order_quantity' => $extraQty,
'updated_by' => Filament::auth()->user()?->name,
]);
}
}
}
protected function getHeaderActions(): array
{
return [

View File

@@ -0,0 +1,603 @@
<?php
namespace App\Filament\Resources;
use App\Filament\Exports\ProductionCharacteristicExporter;
use App\Filament\Imports\ProductionCharacteristicImporter;
use App\Filament\Resources\ProductionCharacteristicResource\Pages;
use App\Filament\Resources\ProductionCharacteristicResource\RelationManagers;
use App\Models\Item;
use App\Models\Line;
use App\Models\Machine;
use App\Models\Plant;
use App\Models\ProductCharacteristicsMaster;
use App\Models\ProductionCharacteristic;
use Filament\Tables\Actions\ExportAction;
use Filament\Tables\Actions\ImportAction;
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\Forms\Get;
use Str;
use Filament\Forms\Components\DateTimePicker;
use Filament\Forms\Components\Select;
use Filament\Forms\Components\TextInput;
use Filament\Tables\Filters\Filter;
class ProductionCharacteristicResource extends Resource
{
protected static ?string $model = ProductionCharacteristic::class;
protected static ?string $navigationIcon = 'heroicon-o-rectangle-stack';
protected static ?string $navigationGroup = 'Production';
public static function form(Form $form): Form
{
return $form
->schema([
Forms\Components\Select::make('plant_id')
->label('Plant Name')
->nullable()
->searchable()
->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();
})
->disabled(fn (Get $get) => ! empty($get('id')))
->default(function () {
$userHas = Filament::auth()->user()->plant_id;
return ($userHas && strlen($userHas) > 0) ? $userHas : optional(ProductionCharacteristic::latest()->first())->plant_id;
})
->afterStateUpdated(function ($state, $set, callable $get) {
$plantId = $get('plant_id');
$set('line_id', null);
$set('item_id', null);
$set('machine_id', null);
$set('production_order', null);
$set('serial_number', null);
$set('observed_value', null);
$set('status', 'NotOk');
$set('updated_by', Filament::auth()->user()?->name);
if (! $plantId) {
$set('poPlantError', 'Please select a plant first.');
}
})
->extraAttributes(fn ($get) => [
'class' => $get('poPlantError') ? 'border-red-500' : '',
])
->hint(fn ($get) => $get('poPlantError') ? $get('poPlantError') : null)
->hintColor('danger')
->required(),
Forms\Components\Select::make('line_id')
->label('Line Name')
->nullable()
->searchable()
->reactive()
->options(function (callable $get) {
if (! $get('plant_id')) {
return [];
}
return Line::where('plant_id', $get('plant_id'))
->pluck('name', 'id')
->toArray();
})
->disabled(fn (Get $get) => ! empty($get('id')))
->afterStateUpdated(function ($state, $set, callable $get) {
$plantId = $get('plant_id');
$set('item_id', null);
$set('machine_id', null);
$set('production_order', null);
$set('serial_number', null);
$set('observed_value', null);
$set('status', 'NotOk');
$set('updated_by', Filament::auth()->user()?->name);
if (! $plantId) {
$set('line_id', null);
$set('poPlantError', 'Please select a plant first.');
}
})
->required(),
Forms\Components\Select::make('item_id')
->label('Item Code')
->nullable()
->searchable()
->reactive()
->options(function (callable $get) {
if (! $get('plant_id') || ! $get('line_id')) {
return [];
}
return Item::where('plant_id', $get('plant_id'))
->pluck('code', 'id')
->toArray();
})
->disabled(fn (Get $get) => ! empty($get('id')))
->afterStateUpdated(function ($state, $set, callable $get) {
$plantId = $get('plant_id');
$set('machine_id', null);
$set('production_order', null);
$set('serial_number', null);
$set('observed_value', null);
$set('status', 'NotOk');
$set('updated_by', Filament::auth()->user()?->name);
if (! $plantId) {
$set('item_id', null);
$set('poPlantError', 'Please select a plant first.');
}
})
->required(),
Forms\Components\Select::make('machine_id')
->label('Work Center')
->nullable()
->searchable()
->reactive()
->options(function (callable $get) {
if (! $get('plant_id') || ! $get('line_id') || ! $get('item_id')) {
return [];
}
return Machine::where('plant_id', $get('plant_id'))
->where('line_id', $get('line_id'))
->pluck('work_center', 'id')
->toArray();
})
->disabled(fn (Get $get) => ! empty($get('id')))
->afterStateUpdated(function ($state, $set, callable $get) {
$plantId = $get('plant_id');
$set('production_order', null);
$set('serial_number', null);
$set('observed_value', null);
$set('status', 'NotOk');
$set('updated_by', Filament::auth()->user()?->name);
if (! $plantId) {
$set('machine_id', null);
$set('poPlantError', 'Please select a plant first.');
}
})
->required(),
Forms\Components\TextInput::make('production_order')
->label('Production Order'),
Forms\Components\TextInput::make('serial_number')
->label('Serial Number'),
Forms\Components\TextInput::make('characteristic_name')
->label('Characteristic Name'),
Forms\Components\TextInput::make('observed_value')
->label('Observed Value'),
Forms\Components\Select::make('status')
->label('Status')
->options([
'Ok' => 'Ok',
'NotOk' => 'Not Ok',
'ConditionallyAccepted' => 'Conditionally Accepted',
])
->reactive(),
Forms\Components\TextInput::make('inspection_status')
->label('Inspection Status'),
Forms\Components\TextInput::make('remark')
->label('Remark')
->reactive()
->required(fn ($get) => $get('status') == 'ConditionallyAccepted')
->visible(fn ($get) => $get('status') == 'ConditionallyAccepted'),
Forms\Components\Hidden::make('created_by')
->label('Created By'),
Forms\Components\Hidden::make('updated_by')
->label('Updated By'),
]);
}
public static function table(Table $table): Table
{
return $table
->columns([
Tables\Columns\TextColumn::make('No.')
->label('No.')
->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')
->searchable()
->alignCenter()
->sortable(),
Tables\Columns\TextColumn::make('line.name')
->label('Line Name')
->searchable()
->alignCenter()
->sortable(),
Tables\Columns\TextColumn::make('item.code')
->label('Item Code')
->searchable()
->alignCenter()
->sortable(),
Tables\Columns\TextColumn::make('item.description')
->label('Item Description')
->searchable()
->alignCenter()
->sortable(),
Tables\Columns\TextColumn::make('machine.work_center')
->label('Work Center')
->searchable()
->alignCenter()
->sortable(),
Tables\Columns\TextColumn::make('production_order')
->label('Production Order')
->searchable()
->alignCenter()
->sortable(),
Tables\Columns\TextColumn::make('serial_number')
->label('Serial Number')
->searchable()
->alignCenter()
->sortable(),
Tables\Columns\TextColumn::make('characteristic_name')
->label('Characteristic Name')
->searchable()
->alignCenter()
->sortable(),
Tables\Columns\TextColumn::make('machine.name')
->label('Spec. Value')
// ->searchable()
->formatStateUsing(function ($record) {
$specVal = ProductCharacteristicsMaster::where('plant_id', $record->plant_id)->where('item_id', $record->item_id)->where('line_id', $record->line_id)->where('machine_id', $record->machine_id)->first();
// return $record?->plant_id.'-'.$record?->item_id.'-'.$record->line_id.'-'.$record?->machine_id;
return $specVal?->lower.' - '.$specVal?->upper;
})
->alignCenter()
->sortable(),
Tables\Columns\TextColumn::make('observed_value')
->label('Observed Value')
->searchable()
->alignCenter()
->sortable(),
Tables\Columns\TextColumn::make('status')
->label('Status')
->searchable()
// ->formatStateUsing(function ($record) {
// return empty($record->status == 'Ok') ? 'Ok' : 'Not Ok';
// })
->color(fn (string $state): string => match ($state) {
'Ok' => 'success',
'Not Ok' => 'danger',
'NotOk' => 'danger',
'ConditionallyAccepted' => 'success',
default => 'gray',
})
->alignCenter()
->sortable(),
// Tables\Columns\TextColumn::make('inspection_status')
// ->label('Inspection Status')
// ->searchable()
// ->color(fn (string $state): string => match ($state) {
// 'Ok' => 'success',
// 'Not Ok' => 'danger',
// 'NotOk' => 'danger',
// default => 'gray',
// })
// ->alignCenter()
// ->sortable(),
Tables\Columns\TextColumn::make('remark')
->label('Remark')
->searchable()
->alignCenter()
->sortable(),
Tables\Columns\TextColumn::make('created_at')
->label('Created At')
->alignCenter()
->dateTime()
->sortable()
->toggleable(isToggledHiddenByDefault: true),
Tables\Columns\TextColumn::make('updated_at')
->label('Updated At')
->alignCenter()
->dateTime()
->sortable()
->toggleable(isToggledHiddenByDefault: true),
Tables\Columns\TextColumn::make('deleted_at')
->label('Deleted At')
->alignCenter()
->dateTime()
->sortable()
->toggleable(isToggledHiddenByDefault: true),
])
->filters([
Tables\Filters\TrashedFilter::make(),
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('productionCharacteristics', function ($query) {
$query->whereNotNull('id');
})->orderBy('code')->pluck('name', '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) {
$set('Item', null);
$set('Line', null);
}),
Select::make('Line')
->label('Search by Line Name')
->nullable()
->searchable()
->reactive()
->options(function (callable $get) {
$plantId = $get('Plant');
if (empty($plantId)) {
return [];
}
return Line::whereHas('productionCharacteristics', function ($query) use ($plantId) {
if ($plantId) {
$query->where('plant_id', $plantId);
}
})->pluck('name', 'id');
})
->afterStateUpdated(function ($state, callable $set, callable $get) {
$set('process_order', null);
}),
Select::make('Item')
->label('Search by Item Code')
->nullable()
->searchable()
->reactive()
->options(function (callable $get) {
$plantId = $get('Plant');
if (empty($plantId)) {
return [];
}
return Item::whereHas('productionCharacteristics', function ($query) use ($plantId) {
if ($plantId) {
$query->where('plant_id', $plantId);
}
})->pluck('code', 'id');
})
->afterStateUpdated(function ($state, callable $set, callable $get) {
$set('production_order', null);
}),
Select::make('Machine')
->label('Search by Work Center')
->nullable()
->searchable()
->reactive()
->options(function (callable $get) {
$plantId = $get('Plant');
$lineId = $get('Line');
if (empty($plantId)) {
return [];
}
return Machine::whereHas('productionCharacteristics', function ($query) use ($plantId, $lineId) {
if ($plantId) {
$query->where('plant_id', $plantId)->where('line_id', $lineId);
}
})->pluck('work_center', 'id');
})
->afterStateUpdated(function ($state, callable $set, callable $get) {
$set('production_order', null);
}),
TextInput::make('production_order')
->label('Production Order')
->reactive()
->placeholder('Enter Production Order')
->afterStateUpdated(function ($state, callable $set, callable $get) {
$set('serial_number', null);
}),
TextInput::make('serial_number')
->label('Serial Number')
->reactive()
->placeholder('Enter Serial Number'),
Select::make('status')
->label('Search by Status')
->nullable()
->searchable()
->reactive()
->options([
'Ok' => 'Ok',
'NotOk' => 'Not Ok',
'ConditionallyAccepted' => 'Conditionally Accepted',
]),
DateTimePicker::make(name: '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) {
// Hide all records initially if no filters are applied
if (empty($data['Plant']) && empty($data['Line']) && empty($data['Item']) && empty($data['production_order']) && Str::length($data['serial_number']) <= 0 && ($data['status'] == null || $data['status'] == '') && empty($data['created_from']) && empty($data['created_to'])) {
return $query->whereRaw('1 = 0');
}
if (! empty($data['Plant'])) {
$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['Line'])) {
$query->where('line_id', $data['Line']);
}
if (! empty($data['Item'])) {
$query->where('item_id', $data['Item']);
}
if (! empty($data['Machine'])) {
$query->where('machine_id', $data['Machine']);
}
if (! empty($data['production_order'])) {
$query->where('production_order', 'like', '%'.$data['production_order'].'%');
}
if (Str::length($data['serial_number']) > 0) {
// $query->where('machine_name', $data['machine_name']);
$query->where('serial_number', 'like', '%'.$data['serial_number'].'%');
}
if ($data['status'] != null && $data['status'] != '') {
$query->where('status', $data['status']);
}
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 Name: '.Plant::where('id', $data['Plant'])->value('name');
} else {
$userHas = Filament::auth()->user()->plant_id;
if ($userHas && strlen($userHas) > 0) {
return 'Plant Name: Choose plant to filter records.';
}
}
if (! empty($data['Line'])) {
$indicators[] = 'Line Name: '.Line::where('id', $data['Line'])->value('name');
}
if (! empty($data['Item'])) {
$indicators[] = 'Item Code: '.Item::where('id', $data['Item'])->value('code');
}
if (! empty($data['Machine'])) {
$indicators[] = 'Machine: '.Machine::where('id', $data['Machine'])->value('work_center');
}
if (! empty($data['production_order'])) {
$indicators[] = 'Production Order: '.$data['production_order'];
}
if (Str::length($data['serial_number']) > 0) {
$indicators[] = 'Serial Number: '.$data['serial_number'];
}
// if ($data['status'] != null && $data['status'] != '') {
// $indicators[] = ($data['status'] == 'Ok') ? 'Status: Ok' : 'Status: Not Ok';
// }
if ($data['status'] != null && $data['status'] != '') {
if ($data['status'] == 'Ok') {
$indicators[] = 'Status: Ok';
} elseif ($data['status'] == 'NotOk') {
$indicators[] = 'Status: Not Ok';
} elseif ($data['status'] == 'ConditionallyAccepted') {
$indicators[] = 'Status: Conditionally Accepted';
}
}
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 Production Characteristics')
->color('warning')
->importer(ProductionCharacteristicImporter::class)
->visible(function () {
return Filament::auth()->user()->can('view import production characteristics');
}),
ExportAction::make()
->label('Export Production Characteristics')
->color('warning')
->exporter(ProductionCharacteristicExporter::class)
->visible(function () {
return Filament::auth()->user()->can('view export production characteristics');
}),
]);
}
public static function getRelations(): array
{
return [
//
];
}
public static function getPages(): array
{
return [
'index' => Pages\ListProductionCharacteristics::route('/'),
'create' => Pages\CreateProductionCharacteristic::route('/create'),
'view' => Pages\ViewProductionCharacteristic::route('/{record}'),
'edit' => Pages\EditProductionCharacteristic::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\ProductionCharacteristicResource\Pages;
use App\Filament\Resources\ProductionCharacteristicResource;
use Filament\Actions;
use Filament\Resources\Pages\CreateRecord;
class CreateProductionCharacteristic extends CreateRecord
{
protected static string $resource = ProductionCharacteristicResource::class;
}

View File

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

View File

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

View File

@@ -92,7 +92,12 @@ class QualityValidationResource extends Resource
->hint(fn ($get) => $get('pqPlantError') ? $get('pqPlantError') : null)
->hintColor('danger'),
Forms\Components\Hidden::make('plant')
->default(fn () => session('last_selected_plant_id')),
->default(fn () => session('last_selected_plant_id'))
->afterStateHydrated(function ($state, $set) {
if (!$state && request()->has('plant_id')) {
$set('plant_id', request()->get('plant_id'));
}
}),
Forms\Components\Select::make('line_id')
->label('Line Name')
@@ -129,7 +134,12 @@ class QualityValidationResource extends Resource
->hint(fn ($get) => $get('pqLineError') ? $get('pqLineError') : null)
->hintColor('danger'),
Forms\Components\Hidden::make('line')
->default(fn () => session('last_selected_line')),
->default(fn () => session('last_selected_line'))
->afterStateHydrated(function ($state, $set) {
if (!$state && request()->has('line_id')) {
$set('line_id', request()->get('line_id'));
}
}),
Forms\Components\Hidden::make('sticker_master_id')
// ->relationship('stickerMaster', 'id')
->required(),
@@ -166,7 +176,12 @@ class QualityValidationResource extends Resource
->required(),
Forms\Components\Hidden::make('production')
->default(fn () => session('last_selected_production')),
->default(fn () => session('last_selected_production'))
->afterStateHydrated(function ($state, $set) {
if (!$state && request()->has('production_order')) {
$set('production_order', request()->get('production_order'));
}
}),
Forms\Components\Hidden::make('operator_id')
->required()
@@ -202,6 +217,7 @@ class QualityValidationResource extends Resource
Forms\Components\TextInput::make('item_id')
->label('Item Code')
// ->id('item_id')
->placeholder('Scan the valid QR code')
->reactive()
->required()
@@ -568,10 +584,18 @@ class QualityValidationResource extends Resource
})
->extraAttributes(fn ($get) => [
'class' => $get('validationError') ? 'border-red-500' : '',
'id' => 'item_id',
'onkeydown' => "if (event.key === 'Enter') { event.preventDefault(); event.stopPropagation(); return false; }",
])
->extraAttributes([
'onkeydown' => "if (event.key === 'Enter') { event.preventDefault(); return false; }",
])
// ->extraAttributes(fn ($get) => [
// 'class' => $get('validationError') ? 'border-red-500' : '',
// ])
// ->extraAttributes([
// 'onkeydown' => "if (event.key == 'Enter') { event.preventDefault(); return false; }",
// ])
// ->extraAttributes([
// 'id' => 'item_id'
// ])
->hint(fn ($get) => $get('validationError') ? $get('validationError') : null)
->hintColor('danger'),
@@ -2378,6 +2402,7 @@ class QualityValidationResource extends Resource
}
$expectedValue = $stickerMaster->part_validation1;
$mExpectedValue = $expectedValue ?? null;
if ($state == null || trim($state) == '') {
$set('part_validation1_error', null);
@@ -2398,10 +2423,11 @@ class QualityValidationResource extends Resource
$emails = $mailData['emails'];
$mUserName = Filament::auth()->user()->name;
if (! empty($emails)) {
// Mail::to($emails)->send(new InvalidSerialMail($serNo, $invoiceNumber, $mPlantName, $mInvoiceType));
Mail::to($emails)->send(
new InvalidQualityMail($state, $mPorder, $mPlantName, $mLinePart, $mUserName, 'InvalidPartNumber')
new InvalidQualityMail($state, $mPorder, $mPlantName, $mLinePart, $mUserName, $mExpectedValue, 'InvalidPartNumber')
);
} else {
\Log::warning("No recipients found for plant {$mPlantName}, module Serial, rule invalid_serial.");
@@ -2475,6 +2501,7 @@ class QualityValidationResource extends Resource
}
$expectedValue = $stickerMaster->part_validation2;
$mExpectedValue = $expectedValue ?? null;
if ($state == null || trim($state) == '') {
$set('part_validation2_error', null);
@@ -2492,10 +2519,11 @@ class QualityValidationResource extends Resource
$emails = $mailData['emails'];
$mUserName = Filament::auth()->user()->name;
if (! empty($emails)) {
// Mail::to($emails)->send(new InvalidSerialMail($serNo, $invoiceNumber, $mPlantName, $mInvoiceType));
Mail::to($emails)->send(
new InvalidQualityMail($state, $mPorder, $mPlantName, $mLinePart, $mUserName, 'InvalidPartNumber2')
new InvalidQualityMail($state, $mPorder, $mPlantName, $mLinePart, $mUserName, $mExpectedValue, 'InvalidPartNumber2')
);
} else {
\Log::warning("No recipients found for plant {$mPlantName}, module Serial, rule invalid_serial.");
@@ -2576,6 +2604,7 @@ class QualityValidationResource extends Resource
}
$expectedValue = $stickerMaster->part_validation3;
$mExpectedValue = $expectedValue ?? null;
if ($state == $expectedValue) {
$set('part_validation3_error', null);
@@ -2590,7 +2619,7 @@ class QualityValidationResource extends Resource
if (! empty($emails)) {
// Mail::to($emails)->send(new InvalidSerialMail($serNo, $invoiceNumber, $mPlantName, $mInvoiceType));
Mail::to($emails)->send(
new InvalidQualityMail($state, $mPorder, $mPlantName, $mLinePart, $mUserName, 'InvalidPartNumber3')
new InvalidQualityMail($state, $mPorder, $mPlantName, $mLinePart, $mUserName, $mExpectedValue, 'InvalidPartNumber3')
);
} else {
\Log::warning("No recipients found for plant {$mPlantName}, module Serial, rule invalid_serial.");
@@ -2663,6 +2692,7 @@ class QualityValidationResource extends Resource
}
$expectedValue = $stickerMaster->part_validation4;
$mExpectedValue = $expectedValue ?? null;
// If input is empty, reset the error
if ($state == null || trim($state) == '') {
@@ -2681,10 +2711,11 @@ class QualityValidationResource extends Resource
$emails = $mailData['emails'];
$mUserName = Filament::auth()->user()->name;
if (! empty($emails)) {
// Mail::to($emails)->send(new InvalidSerialMail($serNo, $invoiceNumber, $mPlantName, $mInvoiceType));
Mail::to($emails)->send(
new InvalidQualityMail($state, $mPorder, $mPlantName, $mLinePart, $mUserName, 'InvalidPartNumber4')
new InvalidQualityMail($state, $mPorder, $mPlantName, $mLinePart, $mUserName, $mExpectedValue, 'InvalidPartNumber4')
);
} else {
\Log::warning("No recipients found for plant {$mPlantName}, module Serial, rule invalid_serial.");
@@ -2823,12 +2854,31 @@ class QualityValidationResource extends Resource
Forms\Components\TextInput::make('id')
->hidden()
->readOnly(),
Forms\Components\View::make('components.production-checklist-wrapper')
->visible(fn ($livewire) => $livewire->showChecklist)
->statePath('checklist')
->viewData(fn ($livewire) => [
'existingRecords' => $livewire->existingRecords->toArray(),
'data' => $livewire->data,
'showChecklist' => $livewire->showChecklist,
]),
// Forms\Components\View::make('components.production-checklist-wrapper')
// ->statePath('checklist')
// ->key('checklist-view')
// ->viewData(fn ($livewire) => [
// 'existingRecords' => is_array($livewire->existingRecords)
// ? $livewire->existingRecords
// : $livewire->existingRecords->toArray(),
// 'showChecklist' => $livewire->showChecklist,
// ]),
]);
}
public static function getMailData($plantId)
{
$globalEmails = AlertMailRule::where('plant', 0)
->where('module', 'QualityValidation')
->where('rule_name', 'QualityMail')
@@ -3240,7 +3290,6 @@ class QualityValidationResource extends Resource
Tables\Actions\ViewAction::make(),
Tables\Actions\EditAction::make(),
])
->bulkActions([
Tables\Actions\BulkActionGroup::make([
Tables\Actions\DeleteBulkAction::make(),

View File

@@ -3,18 +3,50 @@
namespace App\Filament\Resources\QualityValidationResource\Pages;
use App\Filament\Resources\QualityValidationResource;
use App\Livewire\ProductionCheckList;
use App\Models\ProductCharacteristicsMaster;
use App\Models\ProductionCharacteristic;
use App\Models\QualityValidation;
use Filament\Actions;
use Filament\Forms\Components\Component;
use Filament\Resources\Pages\CreateRecord;
use Illuminate\Validation\ValidationException;
use Filament\Actions\Action;
use Filament\Notifications\Notification;
class CreateQualityValidation extends CreateRecord
{
protected static string $resource = QualityValidationResource::class;
public $showChecklist = false;
public $checklist;
public $skipChecklistValidation = false;
public bool $shouldSkipChecklist = false;
public $existingRecords = [];
protected $listeners = [
'checklistUpdated' => 'setChecklist',
'checklist-cancelled' => 'handleChecklistCancel',
'checklist-saved' => 'checkListSaved',
'trigger-create' => 'doCreate',
];
public function setChecklist($checklist)
{
$this->data['checklist'] = $checklist;
}
public function doCreate()
{
$this->create();
}
public function mount(): void
{
parent::mount();
session()->forget([
'last_selected_plant_id',
'last_selected_line',
@@ -22,6 +54,68 @@ class CreateQualityValidation extends CreateRecord
]);
}
public function handleChecklistCancel()
{
$this->skipChecklistValidation = true;
$this->showChecklist = false;
}
protected function mutateFormDataBeforeCreate(array $data): array
{
if ($this->shouldSkipChecklist) {
return $data;
}
if ($this->checkIfHasCharacteristics($data)) {
$this->showChecklist = true;
$this->halt();
}
return $data;
}
protected function checkIfHasCharacteristics(array $data)
{
$plantId = $data['plant_id'] ?? null;
$itemCode = $data['item_id'] ?? null;
$lineId = $data['line_id'] ?? null;
if (!$plantId || !$itemCode || !$lineId) {
return false;
}
$item = \App\Models\Item::where('code', $itemCode)
->where('plant_id', $plantId)
->first();
if (!$item) {
$this->existingRecords = collect();
return false;
}
$this->existingRecords = ProductCharacteristicsMaster::where('plant_id', $plantId)
->where('item_id', $item->id)
->where('line_id', $lineId)
->get();
}
public function checkListSaved()
{
$this->showChecklist = false;
$plantId = $this->data['plant_id'] ?? null;
$lineId = $this->data['line_id'] ?? null;
$productionOrder = $this->data['production_order'] ?? null;
return redirect()->to(
static::getResource()::getUrl('create', [
'plant_id' => $this->data['plant_id'] ?? null,
'line_id' => $this->data['line_id'] ?? null,
'production_order' => $this->data['production_order'] ?? null,
])
);
}
protected function beforeCreate(): void
{
@@ -98,10 +192,43 @@ class CreateQualityValidation extends CreateRecord
$errors['part_validation5_error'] = ['Fix the errors before submitting.'];
}
if (!empty($errors)) {
throw ValidationException::withMessages($errors);
}
$this->checkExisting();
$checklist = $this->data['data']['checklist'] ?? [];
if (count($this->existingRecords) > 0){
$this->showChecklist = true;
$this->halt();
}
else{
$this->showChecklist = false;
}
}
public function checkExisting()
{
$plant_id = $this->data['plant_id'] ?? null;
$item_code = $this->data['item_id'] ?? null;
$line_id = $this->data['line_id'] ?? null;
$item = \App\Models\Item::where('code', $item_code)->where('plant_id', $plant_id)->first();
if (!$item) {
$this->existingRecords = collect();
return;
}
$item_id = $item->id;
$this->existingRecords = ProductCharacteristicsMaster::where('plant_id', $plant_id)
->where('item_id', $item_id)
->where('line_id', $line_id)
->get();
}
protected function afterCreate(): void
@@ -110,6 +237,37 @@ class CreateQualityValidation extends CreateRecord
$plant = $this->form->getState()['plant'] ?? null;
$line = $this->form->getState()['line'] ?? null;
$production = $this->form->getState()['production'] ?? null;
// $this->skipChecklistValidation = false;
// $this->showChecklist = false;
// $this->checklist = [];
// $this->form->fill();
// reset checklist
$this->checklist = [];
$this->skipChecklistValidation = false;
$this->showChecklist = false;
$this->form->fill([]);
$this->data = [];
$this->resetValidation();
$this->resetErrorBag();
$this->form->fill([
'plant_id' => null,
'line_id' => null,
'production_order' => null,
]);
// $this->dispatch('focus-item-id');
session()->flash('focus_item_id_after_redirect', true);
logger('Focus flag set in session');
if ($plant) {
session(['last_selected_plant_id' => $plant]);
}
@@ -121,13 +279,14 @@ class CreateQualityValidation extends CreateRecord
}
}
protected function getRedirectUrl(): string
{
//return $this->getResource()::getUrl('create'); // Stay on Create Page after saving
//return $this->getResource()::getUrl('create'); // Stay on Create Page after savin
return $this->getResource()::getUrl('create', [
'plant_id' => $this->data['plant_id'] ?? null,
'line_id' => $this->data['line_id'] ?? null,
'production_order' => $this->data['production_order'] ?? null,
]);
}

View File

@@ -10,6 +10,8 @@ class EditQualityValidation extends EditRecord
{
protected static string $resource = QualityValidationResource::class;
public bool $showChecklist = false;
protected function getHeaderActions(): array
{
return [

View File

@@ -10,6 +10,8 @@ class ListQualityValidations extends ListRecords
{
protected static string $resource = QualityValidationResource::class;
public bool $showChecklist = false;
protected function getHeaderActions(): array
{
return [

View File

@@ -10,6 +10,8 @@ class ViewQualityValidation extends ViewRecord
{
protected static string $resource = QualityValidationResource::class;
public bool $showChecklist = false;
protected function getHeaderActions(): array
{
return [

View File

@@ -12,7 +12,10 @@ use App\Models\RequestCharacteristic;
use Closure;
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\Forms\Set;
@@ -20,6 +23,7 @@ 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;
@@ -170,6 +174,9 @@ class RequestCharacteristicResource extends Resource
Forms\Components\TextInput::make('aufnr')
->label('Job Number')
->reactive()
->numeric()
->minlength(7)
->maxlength(10)
->required(function (callable $get) {
$item = $get('item_id');
if ($item) {
@@ -870,7 +877,8 @@ class RequestCharacteristicResource extends Resource
Tables\Columns\TextColumn::make('work_flow_id')
->label('Work Flow ID')
->alignCenter()
->searchable(), // isIndividual: true
->searchable()
->sortable(), // isIndividual: true
Tables\Columns\TextColumn::make('plant.name')
->label('Plant Name')
->alignCenter()
@@ -1029,21 +1037,19 @@ class RequestCharacteristicResource extends Resource
}
return match ($state) {
'Sent' => 'Sent-Mail1',
'Sent-Mail2' => 'Sent-Mail2',
'Sent-Mail3' => 'Sent-Mail3',
'Sent' => 'Sent-M1',
'Sent-Mail2' => 'Sent-M2',
'Sent-Mail3' => 'Sent-M3',
default => '-',
};
})
->sortable()
->toggleable(isToggledHiddenByDefault: true),
->sortable(),
Tables\Columns\TextColumn::make('trigger_at')
->label('Trigger At')
->dateTime()
->alignCenter()
->searchable()
->sortable()
->toggleable(isToggledHiddenByDefault: true),
->sortable(),
Tables\Columns\TextColumn::make('created_at')
->label('Created At')
->dateTime()
@@ -1079,7 +1085,165 @@ class RequestCharacteristicResource extends Resource
->searchPlaceholder('Search Work Flow ID')
->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('requestCharacteristics', function ($query) {
$query->whereNotNull('id');
})->orderBy('code')->pluck('name', '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): void {
$set('machine', null);
$set('item_id', null);
// $set('aufnr', null);
}),
Select::make('machine')
->label('Search by Work Center')
->nullable()
->searchable()
->reactive()
->options(function (callable $get) {
$plantId = $get('Plant');
if (empty($plantId)) {
return [];
}
return Machine::whereHas('requestCharacteristics', function ($query) use ($plantId) {
if ($plantId) {
$query->where('plant_id', $plantId);
}
})->pluck('work_center', 'id');
})
->afterStateUpdated(function ($state, callable $set, callable $get): void {
// $set('item_id', null);
// $set('aufnr', null);
}),
Select::make('item_id')
->label('Search by Item Code')
->nullable()
->searchable()
->reactive()
->options(function (callable $get) {
$plantId = $get('Plant');
if (empty($plantId)) {
return [];
}
return Item::whereHas('requestCharacteristics', function ($query) use ($plantId) {
if ($plantId) {
$query->where('plant_id', $plantId);
}
})->pluck('code', 'id');
})
->afterStateUpdated(function ($state, callable $set, callable $get): void {
// $set('aufnr', null);
}),
TextInput::make('aufnr')
->label('Job Number')
->placeholder('Enter Job Number')
->numeric()
->minlength(7)
->maxlength(10),
DateTimePicker::make(name: '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) {
// 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['created_from']) && empty($data['created_to'])) {
return $query->whereRaw('1 = 0');
}
if (! empty($data['Plant'])) { // $plant = $data['Plant'] ?? null
$query->where('plant_id', $data['Plant']);
} else {
$userHas = Filament::auth()->user()->plant_id;
if ($userHas && strlen($userHas) > 0) {
return $query->whereRaw('1 = 0');
}
}
if (! empty($data['machine'])) {
$query->where('machine_id', $data['machine']);
}
if (! empty($data['item_id'])) {
$query->where('item_id', $data['item_id']);
}
if (! empty($data['aufnr'])) {
$query->where('aufnr', 'like', '%'.$data['aufnr'].'%');
}
if (! empty($data['created_from'])) {
$query->where('created_at', '>=', $data['created_from']);
}
if (! empty($data['created_to'])) {
$query->where('created_at', '<=', $data['created_to']);
}
})
->indicateUsing(function (array $data) {
$indicators = [];
if (! empty($data['Plant'])) {
$indicators[] = 'Plant 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['machine'])) {
$indicators[] = 'Work Center: '.Machine::where('id', $data['machine'])->value('work_center');
}
if (! empty($data['item_id'])) {
$indicators[] = 'Item Code: '.Item::where('id', $data['item_id'])->value('code');
}
if (! empty($data['aufnr'])) {
$indicators[] = 'Job No: '.$data['aufnr'];
}
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(),

View File

@@ -49,7 +49,9 @@ class StickerMasterResource extends Resource
return $form
->schema([
Forms\Components\Select::make('plant_id')
->label('Plant Name')
->relationship('plant', 'name')
->searchable()
->reactive()
->nullable()
->options(function (callable $get) {
@@ -188,7 +190,7 @@ class StickerMasterResource extends Resource
->hintColor('danger'),
Forms\Components\TextInput::make('item_description')
->label('Description')
->label('Item Description')
->required()
->afterStateHydrated(function ($component, $state, Get $get, Set $set) {
if ($get('id')) {
@@ -529,7 +531,7 @@ class StickerMasterResource extends Resource
return ($currentPage - 1) * $perPage + $rowLoop->iteration;
}),
Tables\Columns\TextColumn::make('plant.name')
->label('Plant')
->label('Plant Name')
->alignCenter()
->sortable(),
Tables\Columns\TextColumn::make('item.code')
@@ -537,6 +539,19 @@ class StickerMasterResource extends Resource
->alignCenter()
->sortable()
->searchable(),
Tables\Columns\TextColumn::make('item.description')
->label('Item Description')
->alignCenter()
->sortable()
->searchable()
->toggleable(isToggledHiddenByDefault: true),
Tables\Columns\TextColumn::make('item.uom')
->label('Unit of Measure')
->default('-')
->alignCenter()
->sortable()
->searchable()
->toggleable(isToggledHiddenByDefault: true),
Tables\Columns\CheckboxColumn::make('serial_number_motor')
->label('Serial Number Motor')
->disabled(true)
@@ -692,12 +707,19 @@ class StickerMasterResource extends Resource
->label('Advanced Filters')
->form([
Select::make('Plant')
->label('Select 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();
// 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('stickersMasters', function ($query) {
$query->whereNotNull('id');
})->orderBy('code')->pluck('name', 'id')->toArray();
}
})
->searchable()
->reactive()
@@ -810,7 +832,7 @@ class StickerMasterResource extends Resource
$indicators = [];
if (! empty($data['Plant'])) {
$indicators[] = 'Plant: '.Plant::where('id', $data['Plant'])->value('name');
$indicators[] = 'Plant Name: '.Plant::where('id', $data['Plant'])->value('name');
} else {
$userHas = Filament::auth()->user()->plant_id;

View File

@@ -0,0 +1,600 @@
<?php
namespace App\Filament\Resources;
use App\Filament\Exports\StockDataMasterExporter;
use App\Filament\Imports\StockDataMasterImporter;
use App\Filament\Resources\StockDataMasterResource\Pages;
use App\Models\Item;
use App\Models\Plant;
use App\Models\StickerMaster;
use App\Models\StockDataMaster;
use Filament\Facades\Filament;
use Filament\Forms;
use Filament\Forms\Components\DateTimePicker;
use Filament\Forms\Components\Radio;
use Filament\Forms\Components\Select;
use Filament\Forms\Components\TextInput;
use Filament\Forms\Form;
use Filament\Notifications\Notification;
use Filament\Resources\Resource;
use Filament\Tables;
use Filament\Tables\Actions\ExportAction;
use Filament\Tables\Actions\ImportAction;
use Filament\Tables\Filters\Filter;
use Filament\Tables\Table;
use Illuminate\Database\Eloquent\Builder;
use Illuminate\Database\Eloquent\SoftDeletingScope;
class StockDataMasterResource extends Resource
{
protected static ?string $model = StockDataMaster::class;
protected static ?string $navigationIcon = 'heroicon-o-rectangle-stack';
protected static ?string $navigationGroup = 'Cycle Count Software';
public static function form(Form $form): Form
{
return $form
->schema([
Forms\Components\Select::make('plant_id')
->label('Plant')
->reactive()
->relationship('plant', 'name')
->required(),
Forms\Components\Select::make('sticker_master_id')
->label('Item Code')
->reactive()
->required()
->searchable()
->options(function ($get) {
if (! $get('plant_id')) {
return [];
}
return StickerMaster::with('item')
->where('plant_id', $get('plant_id'))
->get()
->pluck('item.code', 'id')
->toArray();
}),
Forms\Components\TextInput::make('location')
->label('Location'),
Forms\Components\TextInput::make('bin')
->label('Bin'),
Forms\Components\TextInput::make('serial_number')
->label('Serial Number'),
Forms\Components\TextInput::make('batch')
->label('Batch'),
Forms\Components\TextInput::make('quantity')
->label('Quantity'),
Forms\Components\TextInput::make('doc_no')
->label('Doc No'),
Forms\Components\Select::make('type')
->label('Type')
->options([
'0' => 'FG',
'1' => 'NON-FG',
]),
Forms\Components\TextInput::make('motor_scanned_status')
->label('Motor Scanned Status'),
Forms\Components\TextInput::make('pump_scanned_status')
->label('Pump Scanned Status'),
Forms\Components\TextInput::make('capacitor_scanned_status')
->label('Capacitor Scanned Status'),
Forms\Components\TextInput::make('scanned_status_set')
->label('Scanned Status Set'),
Forms\Components\TextInput::make('panel_box_item_code')
->label('Panel Box Item Code'),
Forms\Components\TextInput::make('panel_box_supplier')
->label('Panel Box Supplier'),
Forms\Components\TextInput::make('panel_box_sno')
->label('Panel Box Sno'),
Forms\Components\TextInput::make('scanned_status')
->label('Scanned Status'),
Forms\Components\TextInput::make('scanned_quantity')
->label('Scanned Quantity'),
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('stickerMaster.item.code')
->label('Item Code')
->alignCenter()
->searchable()
->sortable(),
Tables\Columns\TextColumn::make('type')
->label('Type')
->alignCenter()
->searchable()
->formatStateUsing(fn ($state) => match ($state) {
'0' => 'FG',
'1' => 'NON-FG',
default => '-',
})
->sortable(),
Tables\Columns\TextColumn::make('location')
->label('Location')
->alignCenter()
->searchable()
->sortable(),
Tables\Columns\TextColumn::make('bin')
->label('Bin')
->alignCenter()
->searchable()
->sortable(),
Tables\Columns\TextColumn::make('serial_number')
->label('Serial Number')
->alignCenter()
->searchable()
->sortable(),
Tables\Columns\TextColumn::make('batch')
->label('Batch')
->alignCenter()
->searchable()
->sortable(),
Tables\Columns\TextColumn::make('quantity')
->label('Quantity')
->alignCenter()
->searchable()
->sortable(),
Tables\Columns\TextColumn::make('doc_no')
->label('Document Number')
->alignCenter()
->searchable()
->sortable(),
Tables\Columns\TextColumn::make('motor_scanned_status')
->label('Motor Scanned Status')
->alignCenter()
->searchable()
->sortable()
->visible(fn ($livewire) => ($livewire->tableFilters['advanced_filters']['type'] ?? null) != '1'),
Tables\Columns\TextColumn::make('pump_scanned_status')
->label('Pump Scanned Status')
->alignCenter()
->searchable()
->sortable()
->visible(fn ($livewire) => ($livewire->tableFilters['advanced_filters']['type'] ?? null) != '1'),
Tables\Columns\TextColumn::make('capacitor_scanned_status')
->label('Capacitor Scanned Status')
->alignCenter()
->searchable()
->sortable()
->visible(fn ($livewire) => ($livewire->tableFilters['advanced_filters']['type'] ?? null) != '1'),
Tables\Columns\TextColumn::make('scanned_status_set')
->label('Scanned Status Set')
->alignCenter()
->searchable()
->sortable()
->visible(fn ($livewire) => ($livewire->tableFilters['advanced_filters']['type'] ?? null) != '1'),
Tables\Columns\TextColumn::make('panel_box_item_code')
->label('Panel Box Item Code')
->alignCenter()
->searchable()
->sortable()
->visible(fn ($livewire) => ($livewire->tableFilters['advanced_filters']['type'] ?? null) != '1'),
Tables\Columns\TextColumn::make('panel_box_supplier')
->label('Panel Box Supplier')
->alignCenter()
->searchable()
->sortable()
->visible(fn ($livewire) => ($livewire->tableFilters['advanced_filters']['type'] ?? null) != '1'),
Tables\Columns\TextColumn::make('panel_box_sno')
->label('Panel Box Serial Number')
->alignCenter()
->searchable()
->sortable()
->visible(fn ($livewire) => ($livewire->tableFilters['advanced_filters']['type'] ?? null) != '1'),
Tables\Columns\TextColumn::make('scanned_status')
->label('Scanned Status')
->alignCenter()
->searchable()
->sortable(),
Tables\Columns\TextColumn::make('scanned_quantity')
->label('Scanned Quantity')
->alignCenter()
->searchable()
->sortable(),
Tables\Columns\TextColumn::make('system_stock')
->label('System Stock')
->alignCenter()
->getStateUsing(fn ($record) => $record->quantity),
Tables\Columns\TextColumn::make('scanned_stock')
->label('Scanned Stock')
->alignCenter()
->getStateUsing(fn ($record) => $record->scanned_quantity),
Tables\Columns\TextColumn::make('duplicate_stock')
->label('Duplicate Stock')
->alignCenter()
->getStateUsing(function ($record) {
return \App\Models\DuplicateStock::where('stock_data_master_id', $record->id)->count();
}),
Tables\Columns\TextColumn::make('not_in_stock')
->label('Not In Stock')
->alignCenter()
->getStateUsing(function ($record) {
return \App\Models\NotInStock::where('serial_number', $record->serial_number)
->where('plant_id', $record->plant_id)
->count();
}),
Tables\Columns\TextColumn::make('physical_stock')
->label('Physical Stock')
->alignCenter()
->getStateUsing(function ($record) {
$duplicate = \App\Models\DuplicateStock::where('stock_data_master_id', $record->id)->count();
$notInStock = \App\Models\NotInStock::where('serial_number', $record->serial_number)
->where('plant_id', $record->plant_id)
->count();
$scanned = $record->scanned_quantity ?? 0;
return $scanned + $duplicate + $notInStock;
}),
Tables\Columns\TextColumn::make('stock_difference')
->label('Stock Difference Count')
->alignCenter()
->getStateUsing(function ($record) {
$duplicate = \App\Models\DuplicateStock::where('stock_data_master_id', $record->id)->count();
$notInStock = \App\Models\NotInStock::where('serial_number', $record->serial_number)
->where('plant_id', $record->plant_id)
->count();
$scanned = (int) $record->scanned_quantity;
$physicalStock = $scanned + $duplicate + $notInStock;
$systemStock = (int) $record->quantity;
$difference = $physicalStock - $systemStock;
return max($difference, 0); // prevents negative values
}),
Tables\Columns\TextColumn::make('created_at')
->label('Created At')
->alignCenter()
->dateTime()
->sortable()
->toggleable(isToggledHiddenByDefault: true),
Tables\Columns\TextColumn::make('updated_at')
->label('Updated At')
->alignCenter()
->dateTime()
->sortable()
->toggleable(isToggledHiddenByDefault: true),
Tables\Columns\TextColumn::make('deleted_at')
->label('Deleted At')
->alignCenter()
->dateTime()
->sortable()
->toggleable(isToggledHiddenByDefault: true),
])
->filters([
Tables\Filters\TrashedFilter::make(),
Filter::make('advanced_filters')
->label('Advanced Filters')
->form([
Radio::make('type')
->label('Stock Type')
->options([
'0' => 'FG',
'1' => 'NON-FG',
])
->inline()
->default('0')
->nullable(),
Select::make('Plant')
->label('Select Plant')
->nullable()
->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('stockDataMasters', function ($query) {
$query->whereNotNull('id');
})->orderBy('code')->pluck('name', 'id');
}
})
->reactive()
->afterStateUpdated(function ($state, callable $set, callable $get): void {
$set('sticker_master_id', null);
$set('updated_by', null);
}),
TextInput::make('location')
->label('Location')
->placeholder(placeholder: 'Enter Location'),
TextInput::make('serial_number')
->label('Serial Number')
->placeholder(placeholder: 'Enter Serial Number'),
Select::make('sticker_master_id')
->label('Search by Item Code')
->nullable()
->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('stockDataMasters');
})->pluck('code', 'id');
})
->searchable()
->reactive(),
Select::make('scanned_status')
->label('Scanned Status')
->nullable()
->options([
'Scanned' => 'Scanned',
'Pending' => 'Pending',
])
->searchable()
->reactive(),
Select::make('updated_by')
->label('Created By')
->nullable()
->options(function (callable $get) {
$plantId = $get('Plant');
if (! $plantId) {
return StockDataMaster::whereNotNull('updated_by')->select('updated_by')->distinct()->pluck('updated_by', 'updated_by');
} else {
return StockDataMaster::where('plant_id', $plantId)->whereNotNull('updated_by')->select('updated_by')->distinct()->pluck('updated_by', 'updated_by');
}
})
->searchable()
->reactive(),
DateTimePicker::make(name: 'created_from')
->label('Created From')
->placeholder(placeholder: 'Select From DateTime')
->reactive()
->native(false),
DateTimePicker::make('created_to')
->label('Created To')
->placeholder(placeholder: 'Select To DateTime')
->reactive()
->native(false),
])
->query(function ($query, array $data) {
if (! isset($data['type']) && (empty($data['Plant']) && empty($data['location']) && empty($data['serial_number']) && empty($data['created_from']) && empty($data['created_to']) && empty($data['updated_by']) && empty($data['scanned_status']) && empty($data['sticker_master_id']))) {
if (empty($data['type'])) {
Notification::make()
->title('Please, choose valid type to filter.')
->danger()
->send();
}
return $query->whereRaw('1 = 0');
}
if ($data['type'] != '') {
if ($data['type'] == '0') {
$query->where('type', '0');
if (! empty($data['scanned_status'])) {
if ($data['scanned_status'] == 'Scanned') {
$query->whereNotNull('scanned_status')
->where('scanned_status', '!=', '');
} elseif ($data['scanned_status'] == 'Pending') {
$query->where(function ($query) {
$query->whereNull('scanned_status')
->orWhere('scanned_status', '!=', 'Scanned');
});
}
}
} elseif ($data['type'] == '1') {
$query->where('type', '1')
->whereNotNull('quantity');
if ($data['scanned_status']) {
if ($data['scanned_status'] == 'Scanned') {
$query->whereNotNull('scanned_status')
->where('scanned_status', '!=', '');
} elseif ($data['scanned_status'] == 'Pending') {
$query->where(function ($q) {
$q->whereNull('scanned_status')
->orWhere('scanned_status', '!=', 'Scanned');
});
}
}
}
} else {
if ($data['scanned_status']) {
if ($data['scanned_status'] == 'Scanned') {
$query->whereNotNull('scanned_status')
->where('scanned_status', '!=', '');
} elseif ($data['scanned_status'] == 'Pending') {
$query->where(function ($q) {
$q->whereNull('scanned_status')
->orWhere('scanned_status', '!=', 'Scanned');
});
}
}
}
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['location'])) {
$query->where('location', 'like', '%'.$data['location'].'%');
}
if (! empty($data['serial_number'])) {
$query->where('serial_number', 'like', '%'.$data['serial_number'].'%');
}
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['sticker_master_id'])) {
$stickerMasterIds = StickerMaster::where('item_id', $data['sticker_master_id'])
->pluck('id')
->toArray();
if (! empty($stickerMasterIds)) {
$query->whereIn('sticker_master_id', $stickerMasterIds);
}
}
})
->indicateUsing(function (array $data) {
$indicators = [];
if (! empty($data['Plant'])) {
$indicators[] = 'Plant: '.Plant::where('id', $data['Plant'])->value('name');
} else {
$userHas = Filament::auth()->user()->plant_id;
if ($userHas && strlen($userHas) > 0) {
return 'Plant: Choose plant to filter records.';
}
}
if (! empty($data['location'])) {
$indicators[] = 'Location: '.$data['location'];
}
if (! empty($data['serial_number'])) {
$indicators[] = 'Serial Number: '.$data['serial_number'];
}
if (! empty($data['sticker_master_id'])) {
$itemCode = Item::find($data['sticker_master_id'])->code ?? 'Unknown';
$indicators[] = 'Item Code: '.$itemCode;
}
if (! empty($data['updated_by'])) {
$indicators[] = 'Created By: '.$data['updated_by'];
}
if (! empty($data['created_from'])) {
$indicators[] = 'From: '.$data['created_from'];
}
if (! empty($data['created_to'])) {
$indicators[] = 'To: '.$data['created_to'];
}
if (! empty($data['scanned_status'])) {
$indicators[] = 'Scanned Status: '.$data['scanned_status'];
}
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 Stock Data')
->color('warning')
->importer(StockDataMasterImporter::class)
->visible(function () {
return Filament::auth()->user()->can('view import stock data master');
}),
ExportAction::make()
->label('Export Stock Data')
->color('warning')
->exporter(StockDataMasterExporter::class)
->visible(function () {
return Filament::auth()->user()->can('view export stock data master');
}),
]);
}
public static function getRelations(): array
{
return [
//
];
}
public static function getPages(): array
{
return [
'index' => Pages\ListStockDataMasters::route('/'),
'create' => Pages\CreateStockDataMaster::route('/create'),
'view' => Pages\ViewStockDataMaster::route('/{record}'),
'edit' => Pages\EditStockDataMaster::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\StockDataMasterResource\Pages;
use App\Filament\Resources\StockDataMasterResource;
use Filament\Actions;
use Filament\Resources\Pages\CreateRecord;
class CreateStockDataMaster extends CreateRecord
{
protected static string $resource = StockDataMasterResource::class;
}

View File

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

View File

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

View File

@@ -56,8 +56,9 @@ class TestingPanelReadingResource extends Resource
return $form
->schema([
Forms\Components\Select::make('plant_id')
->label('Plant')
->label('Plant Name')
->relationship('plant', 'name')
->searchable()
->required()
->reactive()
->options(function (callable $get) {
@@ -73,17 +74,19 @@ class TestingPanelReadingResource extends Resource
$plantId = $get('plant_id');
if (! $plantId) {
$set('line_id', null);
$set('item_id', null);
$set('motor_testing_master_id', null);
$set('machine_id', null);
$set('tPrError', 'Please select a plant first.');
return;
} else {
$set('line_id', null);
$set('item_id', null);
$set('motor_testing_master_id', null);
$set('machine_id', null);
$set('tPrError', null);
}
$set('updated_by', Filament::auth()->user()?->name);
})
->extraAttributes(fn ($get) => [
'class' => $get('tPrError') ? 'border-red-500' : '',
@@ -91,8 +94,9 @@ class TestingPanelReadingResource extends Resource
->hint(fn ($get) => $get('tPrError') ? $get('tPrError') : null)
->hintColor('danger'),
Forms\Components\Select::make('line_id')
->label('Line')
->label('Line Name')
->relationship('line', 'name')
->searchable()
->options(function (callable $get) {
$plantId = $get('plant_id');
if (! $plantId) {
@@ -109,10 +113,14 @@ class TestingPanelReadingResource extends Resource
->disabled(fn (Get $get) => ! empty($get('id')))
->required()
->reactive()
->afterStateUpdated(fn (callable $set) => $set('item_id', null)),
->afterStateUpdated(function (callable $set, callable $get, ?string $state) {
$set('motor_testing_master_id', null);
$set('updated_by', Filament::auth()->user()?->name);
}),
Forms\Components\Select::make('machine_id')
->label('Machine')
->relationship('machine', 'name')
->label('Work Center')
->relationship('machine', 'work_center')
->searchable()
->options(function (callable $get) {
$lineId = $get('line_id');
if (! $lineId) {
@@ -121,7 +129,7 @@ class TestingPanelReadingResource extends Resource
// Only show machines for the selected line
return Machine::where('line_id', $lineId)
->pluck('name', 'id')
->pluck('work_center', 'id')
->toArray();
})
->default(function () {
@@ -129,7 +137,10 @@ class TestingPanelReadingResource extends Resource
})
->disabled(fn (Get $get) => ! empty($get('id')))
->required()
->reactive(),
->reactive()
->afterStateUpdated(function (callable $set, callable $get, ?string $state) {
$set('updated_by', Filament::auth()->user()?->name);
}),
Forms\Components\Select::make('motor_testing_master_id')
->label('Item Code')
// ->relationship('motorTestingMaster', 'item.code')
@@ -163,101 +174,234 @@ class TestingPanelReadingResource extends Resource
// )
->required()
->searchable()
->reactive(),
->reactive()
->afterStateUpdated(function (callable $set, callable $get, ?string $state) {
$set('updated_by', Filament::auth()->user()?->name);
}),
Forms\Components\TextInput::make('output')
->label('Output')
->required(),
->required()
->afterStateUpdated(function (callable $set, callable $get, ?string $state) {
$set('updated_by', Filament::auth()->user()?->name);
}),
Forms\Components\TextInput::make('serial_number')
->label('Serial Number')
->required(),
->required()
->afterStateUpdated(function (callable $set, callable $get, ?string $state) {
$set('updated_by', Filament::auth()->user()?->name);
}),
Forms\Components\TextInput::make('winded_serial_number')
->label('Winded Serial Number'),
->label('Winded Serial Number')
->afterStateUpdated(function (callable $set, callable $get, ?string $state) {
$set('updated_by', Filament::auth()->user()?->name);
}),
Forms\Components\TextInput::make('before_fr_volt')
->label('Before FR Volt'),
->label('Before FR Volt')
->afterStateUpdated(function (callable $set, callable $get, ?string $state) {
$set('updated_by', Filament::auth()->user()?->name);
}),
Forms\Components\TextInput::make('before_fr_cur')
->label('Before FR Current'),
->label('Before FR Current')
->afterStateUpdated(function (callable $set, callable $get, ?string $state) {
$set('updated_by', Filament::auth()->user()?->name);
}),
Forms\Components\TextInput::make('before_fr_pow')
->label('Before FR Power'),
->label('Before FR Power')
->afterStateUpdated(function (callable $set, callable $get, ?string $state) {
$set('updated_by', Filament::auth()->user()?->name);
}),
Forms\Components\TextInput::make('before_fr_res_ry')
->label('Before FR Resistance RY'),
->label('Before FR Resistance RY')
->afterStateUpdated(function (callable $set, callable $get, ?string $state) {
$set('updated_by', Filament::auth()->user()?->name);
}),
Forms\Components\TextInput::make('before_fr_res_yb')
->label('Before FR Resistance YB'),
->label('Before FR Resistance YB')
->afterStateUpdated(function (callable $set, callable $get, ?string $state) {
$set('updated_by', Filament::auth()->user()?->name);
}),
Forms\Components\TextInput::make('before_fr_res_br')
->label('Before FR Resistance BR'),
->label('Before FR Resistance BR')
->afterStateUpdated(function (callable $set, callable $get, ?string $state) {
$set('updated_by', Filament::auth()->user()?->name);
}),
Forms\Components\TextInput::make('before_fr_ir')
->label('Before FR IR'),
->label('Before FR IR')
->afterStateUpdated(function (callable $set, callable $get, ?string $state) {
$set('updated_by', Filament::auth()->user()?->name);
}),
Forms\Components\TextInput::make('before_fr_ir_r')
->label('Before FR IR R'),
->label('Before FR IR R')
->afterStateUpdated(function (callable $set, callable $get, ?string $state) {
$set('updated_by', Filament::auth()->user()?->name);
}),
Forms\Components\TextInput::make('before_fr_ir_y')
->label('Before FR IR Y'),
->label('Before FR IR Y')
->afterStateUpdated(function (callable $set, callable $get, ?string $state) {
$set('updated_by', Filament::auth()->user()?->name);
}),
Forms\Components\TextInput::make('before_fr_ir_b')
->label('Before FR IR B'),
->label('Before FR IR B')
->afterStateUpdated(function (callable $set, callable $get, ?string $state) {
$set('updated_by', Filament::auth()->user()?->name);
}),
Forms\Components\TextInput::make('before_fr_freq')
->label('Before FR Frequency'),
->label('Before FR Frequency')
->afterStateUpdated(function (callable $set, callable $get, ?string $state) {
$set('updated_by', Filament::auth()->user()?->name);
}),
Forms\Components\TextInput::make('before_fr_speed')
->label('Before FR Speed'),
->label('Before FR Speed')
->afterStateUpdated(function (callable $set, callable $get, ?string $state) {
$set('updated_by', Filament::auth()->user()?->name);
}),
Forms\Components\TextInput::make('after_fr_vol')
->label('After FR Volt'),
->label('After FR Volt')
->afterStateUpdated(function (callable $set, callable $get, ?string $state) {
$set('updated_by', Filament::auth()->user()?->name);
}),
Forms\Components\TextInput::make('after_fr_cur')
->label('After FR Current'),
->label('After FR Current')
->afterStateUpdated(function (callable $set, callable $get, ?string $state) {
$set('updated_by', Filament::auth()->user()?->name);
}),
Forms\Components\TextInput::make('after_fr_pow')
->label('After FR Power'),
->label('After FR Power')
->afterStateUpdated(function (callable $set, callable $get, ?string $state) {
$set('updated_by', Filament::auth()->user()?->name);
}),
Forms\Components\TextInput::make('after_fr_ir_hot')
->label('After FR IR Hot'),
->label('After FR IR Hot')
->afterStateUpdated(function (callable $set, callable $get, ?string $state) {
$set('updated_by', Filament::auth()->user()?->name);
}),
Forms\Components\TextInput::make('after_fr_ir_hot_r')
->label('After FR IR Hot R'),
->label('After FR IR Hot R')
->afterStateUpdated(function (callable $set, callable $get, ?string $state) {
$set('updated_by', Filament::auth()->user()?->name);
}),
Forms\Components\TextInput::make('after_fr_ir_hot_y')
->label('After FR IR Hot Y'),
->label('After FR IR Hot Y')
->afterStateUpdated(function (callable $set, callable $get, ?string $state) {
$set('updated_by', Filament::auth()->user()?->name);
}),
Forms\Components\TextInput::make('after_fr_ir_hot_b')
->label('After FR IR Hot B'),
->label('After FR IR Hot B')
->afterStateUpdated(function (callable $set, callable $get, ?string $state) {
$set('updated_by', Filament::auth()->user()?->name);
}),
Forms\Components\TextInput::make('after_fr_ir_cool')
->label('After FR IR Cool'),
->label('After FR IR Cool')
->afterStateUpdated(function (callable $set, callable $get, ?string $state) {
$set('updated_by', Filament::auth()->user()?->name);
}),
Forms\Components\TextInput::make('after_fr_ir_cool_r')
->label('After FR IR Cool R'),
->label('After FR IR Cool R')
->afterStateUpdated(function (callable $set, callable $get, ?string $state) {
$set('updated_by', Filament::auth()->user()?->name);
}),
Forms\Components\TextInput::make('after_fr_ir_cool_y')
->label('After FR IR Cool Y'),
->label('After FR IR Cool Y')
->afterStateUpdated(function (callable $set, callable $get, ?string $state) {
$set('updated_by', Filament::auth()->user()?->name);
}),
Forms\Components\TextInput::make('after_fr_ir_cool_b')
->label('After FR IR Cool B'),
->label('After FR IR Cool B')
->afterStateUpdated(function (callable $set, callable $get, ?string $state) {
$set('updated_by', Filament::auth()->user()?->name);
}),
Forms\Components\TextInput::make('after_fr_freq')
->label('After FR Frequency'),
->label('After FR Frequency')
->afterStateUpdated(function (callable $set, callable $get, ?string $state) {
$set('updated_by', Filament::auth()->user()?->name);
}),
Forms\Components\TextInput::make('after_fr_speed')
->label('After FR Speed'),
->label('After FR Speed')
->afterStateUpdated(function (callable $set, callable $get, ?string $state) {
$set('updated_by', Filament::auth()->user()?->name);
}),
Forms\Components\TextInput::make('after_fr_leak_cur')
->label('After FR Leak Current'),
->label('After FR Leak Current')
->afterStateUpdated(function (callable $set, callable $get, ?string $state) {
$set('updated_by', Filament::auth()->user()?->name);
}),
Forms\Components\TextInput::make('locked_rt_volt')
->label('Locked RT Volt'),
->label('Locked RT Volt')
->afterStateUpdated(function (callable $set, callable $get, ?string $state) {
$set('updated_by', Filament::auth()->user()?->name);
}),
Forms\Components\TextInput::make('locked_rt_cur')
->label('Locked RT Current'),
->label('Locked RT Current')
->afterStateUpdated(function (callable $set, callable $get, ?string $state) {
$set('updated_by', Filament::auth()->user()?->name);
}),
Forms\Components\TextInput::make('locked_rt_pow')
->label('Locked RT Power'),
->label('Locked RT Power')
->afterStateUpdated(function (callable $set, callable $get, ?string $state) {
$set('updated_by', Filament::auth()->user()?->name);
}),
Forms\Components\TextInput::make('no_load_pickup_volt')
->label('No Load Pickup Volt'),
->label('No Load Pickup Volt')
->afterStateUpdated(function (callable $set, callable $get, ?string $state) {
$set('updated_by', Filament::auth()->user()?->name);
}),
Forms\Components\TextInput::make('room_temperature')
->label('Room Temperature'),
->label('Room Temperature')
->afterStateUpdated(function (callable $set, callable $get, ?string $state) {
$set('updated_by', Filament::auth()->user()?->name);
}),
Forms\Components\TextInput::make('hv_test')
->label('High Voltage Test'),
->label('High Voltage Test')
->afterStateUpdated(function (callable $set, callable $get, ?string $state) {
$set('updated_by', Filament::auth()->user()?->name);
}),
Forms\Components\TextInput::make('batch_number')
->label('Batch Number'),
->label('Batch Number')
->afterStateUpdated(function (callable $set, callable $get, ?string $state) {
$set('updated_by', Filament::auth()->user()?->name);
}),
Forms\Components\TextInput::make('batch_count')
->label('Batch Count')
->default('0'),
->default('0')
->afterStateUpdated(function (callable $set, callable $get, ?string $state) {
$set('updated_by', Filament::auth()->user()?->name);
}),
Forms\Components\TextInput::make('result')
->label('Result'),
->label('Result')
->afterStateUpdated(function (callable $set, callable $get, ?string $state) {
$set('updated_by', Filament::auth()->user()?->name);
}),
Forms\Components\TextInput::make('remark')
->label('Remark'),
->label('Remark')
->afterStateUpdated(function (callable $set, callable $get, ?string $state) {
$set('updated_by', Filament::auth()->user()?->name);
}),
Forms\Components\TextInput::make('rework_count')
->label('Rework Count')
->default('0'),
->default('0')
->afterStateUpdated(function (callable $set, callable $get, ?string $state) {
$set('updated_by', Filament::auth()->user()?->name);
}),
Forms\Components\TextInput::make('update_count')
->label('Update Count')
->default('0'),
->default('0')
->afterStateUpdated(function (callable $set, callable $get, ?string $state) {
$set('updated_by', Filament::auth()->user()?->name);
}),
Forms\Components\TextInput::make('output_flag')
->label('Output Flag')
->default('0'),
->default('0')
->afterStateUpdated(function (callable $set, callable $get, ?string $state) {
$set('updated_by', Filament::auth()->user()?->name);
}),
Forms\Components\TextInput::make('tested_by')
->label('Tested By'),
->label('Tested By')
->default(fn () => Filament::auth()->user()?->name)
->required(),
Forms\Components\TextInput::make('updated_by')
->label('Updated By'),
->label('Updated By')
->default(fn () => Filament::auth()->user()?->name)
->required(),
Forms\Components\TextInput::make('id')
->hidden()
->readOnly(),
@@ -283,17 +427,20 @@ class TestingPanelReadingResource extends Resource
return ($currentPage - 1) * $perPage + $rowLoop->iteration;
}),
Tables\Columns\TextColumn::make('plant.name')
->label('Plant')
->label('Plant Name')
->alignCenter(),
Tables\Columns\TextColumn::make('line.name')
->label('Line')
->label('Line Name')
->alignCenter(),
Tables\Columns\TextColumn::make('machine.name')
->label('Machine')
Tables\Columns\TextColumn::make('machine.work_center')
->label('Work Center')
->alignCenter(),
Tables\Columns\TextColumn::make('motorTestingMaster.item.code')
->label('Item Code')
->alignCenter(),
Tables\Columns\TextColumn::make('motorTestingMaster.subassembly_code')
->label('Subassembly Code')
->alignCenter(),
Tables\Columns\TextColumn::make('motorTestingMaster.item.description')
->label('Model')
->alignCenter(),
@@ -477,13 +624,22 @@ class TestingPanelReadingResource extends Resource
->label('Advanced Filters')
->form([
Select::make('Plant')
->label('Select Plant')
->label('Search by Plant Name')
->searchable()
->nullable()
->options(function () {
// return Plant::pluck('name', 'id');
$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('testingPanelReadings', function ($query) {
$query->whereNotNull('id');
})->orderBy('code')->pluck('name', 'id');
}
//return ($userHas && strlen($userHas) > 0) ? Plant::where('id', $userHas)->pluck('name', 'id')->toArray() : Plant::orderBy('code')->pluck('name', 'id')->toArray();
})
->reactive()
->afterStateUpdated(function ($state, callable $set, callable $get) {
@@ -492,7 +648,8 @@ class TestingPanelReadingResource extends Resource
}),
Select::make('Line')
->label('Select Line')
->label('Search by Line Name')
->searchable()
->nullable()
->options(function (callable $get) {
$plantId = $get('Plant');
@@ -507,11 +664,11 @@ class TestingPanelReadingResource extends Resource
->reactive()
->afterStateUpdated(function ($state, callable $set, callable $get) {
$set('item_code', null);
}),
Select::make('item_code')
->label('Item Code')
->label('Search by Item Code')
->searchable()
->nullable()
->options(function (callable $get) {
$plantId = $get('Plant');
if ($plantId) {
@@ -520,15 +677,20 @@ class TestingPanelReadingResource extends Resource
->pluck('code', 'id')
->toArray();
} else {
return Item::whereHas('motorTestingMasters')
->pluck('code', 'id')
->toArray();
return [];
// return Item::whereHas('motorTestingMasters')
// ->pluck('code', 'id')
// ->toArray();
}
// return [];
})
->reactive(),
->reactive()
->afterStateUpdated(function ($state, callable $set, callable $get) {
$set('item_description', null);
}),
Select::make('machine_name')
->label('Machine Name')
->label('Search by Work Center')
->searchable()
->nullable()
->options(function (callable $get) {
$plantId = $get('Plant');
$lineId = $get('Line');
@@ -539,30 +701,43 @@ class TestingPanelReadingResource extends Resource
return Machine::where('plant_id', $plantId)
->where('line_id', $lineId)
->pluck('name', 'id')
->pluck('work_center', 'id')
->toArray();
})
->reactive(),
TextInput::make('serial_number')
->label('Serial Number')
->reactive()
->placeholder(placeholder: 'Enter Serial Number'),
->placeholder('Enter Serial Number'),
Select::make('item_description')
->label('Model')
->searchable()
->options(function (callable $get) {
$plantId = $get('Plant');
$query = Item::query();
// $query = Item::query();
// if ($plantId) {
// $query->where('plant_id', $plantId);
// }
$plantId = $get('Plant');
if ($plantId) {
$query->where('plant_id', $plantId);
return Item::where('plant_id', $plantId)
->whereHas('motorTestingMasters')
->pluck('description', 'id')
->toArray();
} else {
return [];
// return Item::whereHas('motorTestingMasters')
// ->pluck('description', 'id')
// ->toArray();
}
return $query->pluck('description', 'description')->toArray();
//return $query->pluck('description', 'description')->toArray();
})
->reactive(),
->reactive()
->afterStateUpdated(function ($state, callable $set, callable $get) {
$set('item_code', null);
}),
Select::make('output')
->label('Output')
->searchable()
@@ -702,12 +877,23 @@ class TestingPanelReadingResource extends Resource
}
if (! empty($data['item_description'])) {
$item = Item::where('description', $data['item_description'])->first();
$itemId = $data['item_description']; // Item::where('description', $data['item_description'])->first()?->id ?? null;
if ($item) {
$query->whereHas('motorTestingMaster', function ($subQuery) use ($item) {
$subQuery->where('item_id', $item->id);
});
if ($itemId) { // $item
$mastId = MotorTestingMaster::where('item_id', $itemId)->first()?->id ?? null;
if ($mastId) { // $item
$motId = TestingPanelReading::where('motor_testing_master_id', $mastId)->first()?->id ?? null;
if ($motId) { // $item
$query->where('motor_testing_master_id', $mastId);
// $query->whereHas('motorTestingMaster', function ($subQuery) use ($itemId) {
// $subQuery->where('item_id', $itemId); //$item->id
// });
} else {
$query->whereRaw('1 = 0');
}
} else {
$query->whereRaw('1 = 0');
}
} else {
$query->whereRaw('1 = 0');
}
@@ -756,7 +942,7 @@ class TestingPanelReadingResource extends Resource
$indicators = [];
if (! empty($data['Plant'])) {
$indicators[] = 'Plant: '.Plant::where('id', $data['Plant'])->value('name');
$indicators[] = 'Plant Name: '.Plant::where('id', $data['Plant'])->value('name');
} else {
$userHas = Filament::auth()->user()->plant_id;
@@ -765,26 +951,27 @@ class TestingPanelReadingResource extends Resource
}
}
if (! empty($data['Line'])) {
$indicators[] = 'Line: '.Line::where('id', $data['Line'])->value('name');
$indicators[] = 'Line Name: '.Line::where('id', $data['Line'])->value('name');
}
if (! empty($data['item_code'])) {
$indicators[] = 'Item Code: '.Item::where('id', $data['item_code'])->value('code');
}
if (! empty($data['machine_name'])) {
$indicators[] = 'Machine: '.Machine::where('id', $data['machine_name'])->value('name');
$indicators[] = 'Work Center: '.Machine::where('id', $data['machine_name'])->value('work_center');
}
if (! empty($data['output'])) {
$indicators[] = 'Output: '.$data['output'];
}
if (! empty($data['item_description'])) {
$indicators[] = 'Model: '.$data['item_description'];
$item = Item::where('id', $data['item_description'])->first()?->description ?? null;
$indicators[] = 'Model: '.$item;
}
// if (!empty($data['phase'])) {
// $indicators[] = 'Phase: ' . $data['phase'];
// }
// if (!empty($data['connection'])) {
// $indicators[] = 'Connection: ' . $data['connection'];
// }
if (!empty($data['connection'])) {
$indicators[] = 'Connection: ' . $data['connection'];
}
if (! empty($data['remark'])) {
$indicators[] = 'Remark: '.$data['remark'];
}

View File

@@ -22,7 +22,7 @@ class TestingTempResource extends Resource
{
protected static ?string $model = TestingTemp::class;
protected static ?string $navigationIcon = 'heroicon-o-rectangle-stack';
protected static ?string $navigationIcon = 'heroicon-c-circle-stack';
protected static ?string $navigationGroup = 'IIOT Temp';
@@ -36,7 +36,7 @@ class TestingTempResource extends Resource
->required()
->searchable()
// ->preload()
// ->nullable(),
->nullable()
->reactive()
->columnSpan(1)
->options(function (callable $get) {
@@ -151,6 +151,7 @@ class TestingTempResource extends Resource
Forms\Components\Actions::make([
Action::make('uploadNow')
->label('Upload File')
->icon('heroicon-c-cloud-arrow-up')
->color('success')
->requiresConfirmation(function (callable $get) {
$filePath = $get('attachment');
@@ -231,6 +232,7 @@ class TestingTempResource extends Resource
Action::make('downloadAttachment')
->label('Download File')
->icon('heroicon-c-cloud-arrow-down')
->color('warning')
->requiresConfirmation(function (callable $get) {
$filePath = $get('selected_file');
@@ -281,6 +283,7 @@ class TestingTempResource extends Resource
Action::make('deleteAttachment')
->label('Delete File')
->icon('heroicon-c-trash')
->color('danger')
->requiresConfirmation(function (callable $get) {
$filePath = $get('selected_file');

View File

@@ -3,7 +3,6 @@
namespace App\Filament\Resources;
use App\Filament\Resources\VehicleEntryResource\Pages;
use App\Filament\Resources\VehicleEntryResource\RelationManagers;
use App\Models\Plant;
use App\Models\VehicleEntry;
use Carbon\Carbon;
@@ -20,7 +19,9 @@ class VehicleEntryResource extends Resource
{
protected static ?string $model = VehicleEntry::class;
protected static ?string $navigationIcon = 'heroicon-o-rectangle-stack';
protected static ?string $navigationIcon = 'heroicon-m-truck'; // heroicon-o-rectangle-stack
protected static ?string $navigationGroup = 'Vehicle';
public static function form(Form $form): Form
{

View File

@@ -2,6 +2,7 @@
namespace App\Http\Controllers;
use App\Models\ClassCharacteristic;
use App\Models\RequestCharacteristic;
use Carbon\Carbon;
use Illuminate\Http\Request;
@@ -58,8 +59,7 @@ class CharacteristicApprovalController extends Controller
}
}
foreach ($levels as $lvl => $column)
{
foreach ($levels as $lvl => $column) {
if ($record->$column == 'Hold') {
if ($lvl == $level) {
@@ -133,7 +133,6 @@ class CharacteristicApprovalController extends Controller
}
}
// foreach ($levels as $lvl => $column) {
// if ($record->$column == 'Hold') {
@@ -150,7 +149,6 @@ class CharacteristicApprovalController extends Controller
// }
// }
$allowedMailStatusByLevel = [
1 => 'Sent',
2 => 'Sent-Mail2',
@@ -161,12 +159,11 @@ class CharacteristicApprovalController extends Controller
if ($record->mail_status != $expectedMailStatus) {
return view('approval.approve-level', [
'status'=> $currentStatus,
'status' => $currentStatus,
'message' => 'Your approval time limit has expired.',
]);
}
return view('approval.reject-form', compact('id', 'level'));
}
@@ -209,7 +206,6 @@ class CharacteristicApprovalController extends Controller
}
}
// foreach ($levels as $lvl => $column) {
// if ($record->$column == 'Hold') {
@@ -236,7 +232,7 @@ class CharacteristicApprovalController extends Controller
if ($record->mail_status != $expectedMailStatus) {
return view('approval.approve-level', [
'status'=> $currentStatus,
'status' => $currentStatus,
'message' => 'Your approval time limit has expired.',
]);
}
@@ -384,6 +380,12 @@ class CharacteristicApprovalController extends Controller
$r->update($updateData);
}
// UPDATE class characteristics
// ClassCharacteristic::where('plant_id', $record->plant_id)
// ->where('machine_id', $record->machine_id)
// ->where('aufnr', $record->aufnr)
// ->update(['has_work_flow_id' => $record->work_flow_id]);
if ($returnView) {
return match ($status) {
'Approved' => view('approval.success'),

File diff suppressed because it is too large Load Diff

View File

@@ -627,7 +627,7 @@ class PdfController extends Controller
// 'coil_number' => $proOrdAgPlant->coil_number ?? "",
// 'order_quantity' => (string)$proOrdAgPlant->order_quantity ?? "",
'coil_number' => $currentCoil,
'order_quantity' => (string) $lastRecord->order_quantity ?? '0.000',
'order_quantity' => (string) $lastRecord->updated_order_quantity ?? '0.000',
'ok_quantity' => (string) $okQty ?? '0',
'not_ok_quantity' => (string) $notOkQty ?? '0',
'received_quantity' => (string) (($totalReceivedQty == 0) ? '0.000' : $totalReceivedQty) ?? '0.000',
@@ -686,7 +686,7 @@ class PdfController extends Controller
$itemCode = $data['item_code'] ?? '';
$lineName = $data['line_name'] ?? '';
$coilNo = $data['coil_number'] ?? '';
$orderQty = $data['order_quantity'] ?? 0;
$updatedOrderQty = $data['order_quantity'] ?? 0;
$receivedQty = $data['received_quantity'] ?? 0;
$scrapQty = $data['scrap_quantity'] ?? 0;
$sfgNo = $data['sfg_number'] ?? '';
@@ -728,6 +728,17 @@ class PdfController extends Controller
], 404);
}
if ($scrapQty == null || $scrapQty == '') {
$scrapQty = 0;
}
if ($rework == null || $rework == '' || ! $rework) {
return response()->json([
'status_code' => 'ERROR',
'status_description' => "Rework value can't be empty!",
], 404);
}
$line = Line::where('name', $lineName)->first();
if (! $line) {
@@ -861,7 +872,8 @@ class PdfController extends Controller
->where('item_id', $itemId)
->sum('received_quantity');
if ($orderQty == 0) {
$orderQty = 0;
if ($updatedOrderQty == 0) {
$orderExist = ProcessOrder::where('plant_id', $plantId)
->where('process_order', $processOrder)
->where('item_id', $itemId)->latest()->first();
@@ -869,6 +881,7 @@ class PdfController extends Controller
if ($orderExist) {
$orderQty = $orderExist->order_quantity ?? 0;
$updatedOrderQty = $orderExist->updated_order_quantity ?? 0;
} else {
return response()->json([
'status_code' => 'ERROR',
@@ -882,9 +895,11 @@ class PdfController extends Controller
// ->value('order_quantity') ?? 0;
if ($orderExist) {
$existOrderQty = $orderExist->order_quantity ?? 0;
// $existOrderQty = $orderExist->updated_order_quantity ?? 0;
$orderQty = $orderExist->order_quantity ?? 0;
$existUpdatedOrdQuan = $orderExist->updated_order_quantity ?? 0;
if ($existOrderQty != $orderQty) {
if ($existUpdatedOrdQuan != $updatedOrderQty) {
return response()->json([
'status_code' => 'ERROR',
'status_description' => "Order quantity doesn't equal to exist process order '{$processOrder}'",
@@ -895,20 +910,6 @@ class PdfController extends Controller
$total = $alreadyReceived + $receivedQty;
if ($total > $orderQty) {
return response()->json([
'status_code' => 'ERROR',
'status_description' => "Received quantity should not exceed order quantity! Order Qty = {$orderQty}, Already Received Qty = {$alreadyReceived}, Trying to Insert Qty = {$receivedQty}",
], 404);
}
if ($rework == null || $rework == '' || ! $rework) {
return response()->json([
'status_code' => 'ERROR',
'status_description' => "Rework value can't be empty!",
], 404);
}
if ($rework != 'Yes' && $rework != 'No') {
return response()->json([
'status_code' => 'ERROR',
@@ -949,6 +950,13 @@ class PdfController extends Controller
], 404);
}
if ($total > $updatedOrderQty) {
return response()->json([
'status_code' => 'ERROR',
'status_description' => "Rework received quantity should not exceed exist order quantity! Exist Order Qty = '{$updatedOrderQty}', Already Exist Total Received Qty = '{$alreadyReceived}', Trying to Insert Rework Received Qty = '{$receivedQty}'",
], 404);
}
$existingCoil = ProcessOrder::where('plant_id', $plantId)
->where('process_order', $processOrder)
->where('line_id', $lineNamePlantId)
@@ -964,6 +972,7 @@ class PdfController extends Controller
'item_id' => $itemId,
'coil_number' => $coilNo,
'order_quantity' => $orderQty,
'updated_order_quantity' => $updatedOrderQty,
'received_quantity' => $receivedQty,
'scrap_quantity' => $scrapQty,
'sfg_number' => $sfgNo,
@@ -994,7 +1003,7 @@ class PdfController extends Controller
]);
}
} else {
if ($coilNo >= 1) {
if ($coilNo > 1) {
$prevCoilNo = (string) ($coilNo - 1);
$existPrevCoil = ProcessOrder::where('plant_id', $plantId)
->where('process_order', $processOrder)
@@ -1004,7 +1013,7 @@ class PdfController extends Controller
if (! $existPrevCoil) {
return response()->json([
'status_code' => 'ERROR',
'status_description' => "Previouse coil number '{$prevCoilNo}' not exist against plant code '{$plantCode}' and process order '{$processOrder}'!",
'status_description' => "Previous coil number '{$prevCoilNo}' not exist against plant code '{$plantCode}' and process order '{$processOrder}'!",
], 404);
}
}
@@ -1022,6 +1031,19 @@ class PdfController extends Controller
], 404);
}
$existPrevCoil = ProcessOrder::where('plant_id', $plantId)
->where('process_order', $processOrder)
->where('item_id', $itemId)
->where('coil_number', $coilNo)
->first();
if ($existPrevCoil->received_quantity < $receivedQty) {
return response()->json([
'status_code' => 'ERROR',
'status_description' => "Rework received quantity should not exceed exist received quantity! Exist Received Qty = '{$existPrevCoil->received_quantity}', Trying to Insert Rework Received Qty = '{$receivedQty}'",
], 404);
}
$updated = ProcessOrder::where('plant_id', $plantId)
->where('process_order', $processOrder)
->where('line_id', $lineNamePlantId)
@@ -1070,7 +1092,7 @@ class PdfController extends Controller
], 404);
}
if ($coilNo >= 1) {
if ($coilNo > 1) {
$prevCoilNo = (string) ($coilNo - 1);
$existPrevCoil = ProcessOrder::where('plant_id', $plantId)
->where('process_order', $processOrder)
@@ -1080,11 +1102,18 @@ class PdfController extends Controller
if (! $existPrevCoil) {
return response()->json([
'status_code' => 'ERROR',
'status_description' => "Previouse coil number '{$prevCoilNo}' not exist against plant code '{$plantCode}' and process order '{$processOrder}'!",
'status_description' => "Previous coil number '{$prevCoilNo}' not exist against plant code '{$plantCode}' and process order '{$processOrder}'!",
], 404);
}
}
if ($total > $updatedOrderQty) {
return response()->json([
'status_code' => 'ERROR',
'status_description' => "Received quantity should not exceed exist order quantity! Exist Order Qty = '{$updatedOrderQty}', Already Exist Total Received Qty = '{$alreadyReceived}', Trying to Insert Received Qty = '{$receivedQty}'",
], 404);
}
ProcessOrder::Create(
[
'plant_id' => $plantId,
@@ -1093,6 +1122,7 @@ class PdfController extends Controller
'item_id' => $itemId,
'coil_number' => $coilNo,
'order_quantity' => $orderQty,
'updated_order_quantity' => $updatedOrderQty,
'received_quantity' => $receivedQty,
'scrap_quantity' => $scrapQty,
'sfg_number' => $sfgNo,

View File

@@ -3,7 +3,6 @@
namespace App\Http\Controllers;
use App\Models\Item;
use App\Models\MotorTestingMaster;
use App\Models\Plant;
use App\Models\StickerMaster;
use Illuminate\Http\Request;
@@ -32,54 +31,46 @@ class StickerMasterController extends Controller
$expectedUser = env('API_AUTH_USER');
$expectedPw = env('API_AUTH_PW');
$header_auth = $request->header('Authorization');
$expectedToken = $expectedUser . ':' . $expectedPw;
$expectedToken = $expectedUser.':'.$expectedPw;
if ("Bearer " . $expectedToken != $header_auth)
{
if ('Bearer '.$expectedToken != $header_auth) {
return response()->json([
'status_code' => 'ERROR',
'status_description' => 'Invalid authorization token!'
'status_description' => 'Invalid authorization token!',
], 403);
}
$plantCode = $request->header('plant-code');
$itemCode = $request->header('item-code');
if ($plantCode == null || $plantCode == '')
{
if ($plantCode == null || $plantCode == '') {
return response()->json([
'status_code' => 'ERROR',
'status_description' => "Plant code can't be empty!"
'status_description' => "Plant code can't be empty!",
], 400);
}
else if (Str::length($plantCode) < 4 || !is_numeric($plantCode) || !preg_match('/^[1-9]\d{3,}$/', $plantCode))
{
} elseif (Str::length($plantCode) < 4 || ! is_numeric($plantCode) || ! preg_match('/^[1-9]\d{3,}$/', $plantCode)) {
return response()->json([
'status_code' => 'ERROR',
'status_description' => "Invalid plant code found!"
'status_description' => 'Invalid plant code found!',
], 400);
}
else if ($itemCode == null || $itemCode == '')
{
} elseif ($itemCode == null || $itemCode == '') {
return response()->json([
'status_code' => 'ERROR',
'status_description' => "Item Code can't be empty!"
'status_description' => "Item Code can't be empty!",
], 400);
}
else if (Str::length($itemCode) < 6 || !ctype_alnum($itemCode))
{
} elseif (Str::length($itemCode) < 6 || ! ctype_alnum($itemCode)) {
return response()->json([
'status_code' => 'ERROR',
'status_description' => "Invalid item code found!"
'status_description' => 'Invalid item code found!',
], 400);
}
$plant = Plant::where('code', $plantCode)->first();
if (!$plant) {
if (! $plant) {
return response()->json([
'status_code' => 'ERROR',
'status_description' => "Plant not found!"
'status_description' => 'Plant not found!',
], 400);
}
@@ -87,51 +78,57 @@ class StickerMasterController extends Controller
$item = Item::where('code', $itemCode)->first();
if (!$item)
{
if (! $item) {
return response()->json([
'status_code' => 'ERROR',
'status_description' => "Item Code not found in item table!"
'status_description' => 'Item Code not found in item table!',
], 404);
}
$item = Item::where('plant_id', $plantId)->where('code', $itemCode)->first();
if (!$item)
{
if (! $item) {
return response()->json([
'status_code' => 'ERROR',
'status_description' => "Item Code not found in item table for the plant : '$plant->name'!"
'status_description' => "Item Code not found in item table for the plant : '$plant->name'!",
], 404);
}
$stickerMaster = StickerMaster::where('plant_id', $plantId)->where('item_id', $item->id)->first();
$itemId = $item->id;
if (!$stickerMaster)
{
$stickerMaster = StickerMaster::where('item_id', $itemId)->first();
if (! $stickerMaster) {
return response()->json([
'status_code' => 'ERROR',
'status_description' => "Item Code not found in sticker master table for the plant : '$plant->name'!"
'status_description' => 'Item Code not found in sticker master table!',
], 404);
}
$stickerMaster = StickerMaster::where('plant_id', $plantId)->where('item_id', $itemId)->first();
if (! $stickerMaster) {
return response()->json([
'status_code' => 'ERROR',
'status_description' => "Item Code not found in sticker master table for the plant : '$plant->name'!",
], 404);
}
$serial_number_motor = $stickerMaster->serial_number_motor ?? null;
$serial_number_pump = $stickerMaster->serial_number_pump ?? null;
if ($serial_number_motor != 1 && $serial_number_pump != 1) {
return response()->json([
'status_code' => 'ERROR',
'status_description' => "The Item Code '$itemCode' does not have serial pump or serial motor selected!"
'status_description' => "The Item Code '$itemCode' does not have serial pump or serial motor selected!",
], 400);
}
$serialInfo = [];
if ($serial_number_motor == 1 && $serial_number_pump == 1)
{
if ($serial_number_motor == 1 && $serial_number_pump == 1) {
$serialInfo[] = 'Serial Pump';
}
else
{
} else {
if ($serial_number_motor == 1) {
$serialInfo[] = 'Serial Motor';
}
@@ -144,6 +141,7 @@ class StickerMasterController extends Controller
'status_code' => 'SUCCESS',
'status_description' => implode(', ', $serialInfo),
];
return response()->json($output, 200);
}
@@ -155,54 +153,46 @@ class StickerMasterController extends Controller
$expectedUser = env('API_AUTH_USER');
$expectedPw = env('API_AUTH_PW');
$header_auth = $request->header('Authorization');
$expectedToken = $expectedUser . ':' . $expectedPw;
$expectedToken = $expectedUser.':'.$expectedPw;
if ("Bearer " . $expectedToken != $header_auth)
{
if ('Bearer '.$expectedToken != $header_auth) {
return response()->json([
'status_code' => 'ERROR',
'status_description' => 'Invalid authorization token!'
'status_description' => 'Invalid authorization token!',
], 403);
}
$plantCode = $request->header('plant-code');
$itemCode = $request->header('item-code');
if ($plantCode == null || $plantCode == '')
{
if ($plantCode == null || $plantCode == '') {
return response()->json([
'status_code' => 'ERROR',
'status_description' => "Plant code can't be empty!"
'status_description' => "Plant code can't be empty!",
], 400);
}
else if (Str::length($plantCode) < 4 || !is_numeric($plantCode) || !preg_match('/^[1-9]\d{3,}$/', $plantCode))
{
} elseif (Str::length($plantCode) < 4 || ! is_numeric($plantCode) || ! preg_match('/^[1-9]\d{3,}$/', $plantCode)) {
return response()->json([
'status_code' => 'ERROR',
'status_description' => "Invalid plant code found!"
'status_description' => 'Invalid plant code found!',
], 400);
}
else if ($itemCode == null || $itemCode == '')
{
} elseif ($itemCode == null || $itemCode == '') {
return response()->json([
'status_code' => 'ERROR',
'status_description' => "Item Code can't be empty!"
'status_description' => "Item Code can't be empty!",
], 400);
}
else if (Str::length($itemCode) < 6 || !ctype_alnum($itemCode))
{
} elseif (Str::length($itemCode) < 6 || ! ctype_alnum($itemCode)) {
return response()->json([
'status_code' => 'ERROR',
'status_description' => "Invalid item code found!"
'status_description' => 'Invalid item code found!',
], 400);
}
$plant = Plant::where('code', $plantCode)->first();
if (!$plant) {
if (! $plant) {
return response()->json([
'status_code' => 'ERROR',
'status_description' => "Plant not found!"
'status_description' => 'Plant not found!',
], 400);
}
@@ -210,48 +200,56 @@ class StickerMasterController extends Controller
$item = Item::where('code', $itemCode)->first();
if (!$item)
{
if (! $item) {
return response()->json([
'status_code' => 'ERROR',
'status_description' => "Item Code not found in item table!"
'status_description' => 'Item Code not found in item table!',
], 404);
}
$item = Item::where('plant_id', $plantId)->where('code', $itemCode)->first();
if (!$item)
{
if (! $item) {
return response()->json([
'status_code' => 'ERROR',
'status_description' => "Item Code not found in item table for the plant : '$plant->name'!"
'status_description' => "Item Code not found in item table for the plant : '$plant->name'!",
], 404);
}
$itemId = $item->id;
$description = $item ? $item->description : '';
$uom = $item ? $item->uom : '';
$category = $item ? $item->category : '';
// $category = $item ? $item->category : '';
$stickerMaster = StickerMaster::where('plant_id', $plantId)->where('item_id', $item->id)->first();
$stickerMaster = StickerMaster::where('item_id', $itemId)->first();
if (!$stickerMaster)
{
if (! $stickerMaster) {
return response()->json([
'status_code' => 'ERROR',
'status_description' => "Item Code not found in sticker master table for the plant : '$plant->name'!"
'status_description' => 'Item Code not found in sticker master table!',
], 404);
}
$stickerMaster = StickerMaster::where('plant_id', $plantId)->where('item_id', $itemId)->first();
if (! $stickerMaster) {
return response()->json([
'status_code' => 'ERROR',
'status_description' => "Item Code not found in sticker master table for the plant : '$plant->name'!",
], 404);
}
$output = [
"item_description" => $description ?? "",
"uom" => $uom ?? "",
"Part_Validation_1" => $stickerMaster?->laser_part_validation1 ?? "",
"Part_Validation_2" => $stickerMaster?->laser_part_validation2 ?? "",
"Part_Validation_3" => $stickerMaster?->laser_part_validation3 ?? "",
"Part_Validation_4" => $stickerMaster?->laser_part_validation4 ?? "",
"Part_Validation_5" => $stickerMaster?->laser_part_validation5 ?? "",
'item_description' => $description ?? '',
'uom' => $uom ?? '',
'Part_Validation_1' => $stickerMaster?->laser_part_validation1 ?? '',
'Part_Validation_2' => $stickerMaster?->laser_part_validation2 ?? '',
'Part_Validation_3' => $stickerMaster?->laser_part_validation3 ?? '',
'Part_Validation_4' => $stickerMaster?->laser_part_validation4 ?? '',
'Part_Validation_5' => $stickerMaster?->laser_part_validation5 ?? '',
];
return response()->json($output, 200);

View File

@@ -9,14 +9,7 @@ use App\Models\MotorTestingMaster;
use App\Models\Plant;
use App\Models\TestingPanelReading;
use App\Models\WorkGroupMaster;
use DB;
use Filament\Notifications\Notification;
use Illuminate\Http\Request;
use Mpdf\Mpdf;
use chillerlan\QRCode\QROptions;
use chillerlan\QRCode\Output\QROutputInterface;
use Mpdf\QrCode\Output;
use Mpdf\QrCode\QrCode;
use Str;
class TestingPanelController extends Controller
@@ -38,170 +31,148 @@ class TestingPanelController extends Controller
$expectedPw = env('API_AUTH_PW');
$header_auth = $request->header('Authorization');
$expectedToken = $expectedUser . ':' . $expectedPw;
$expectedToken = $expectedUser.':'.$expectedPw;
if ("Bearer " . $expectedToken != $header_auth)
{
if ('Bearer '.$expectedToken != $header_auth) {
return response()->json([
'status_code' => 'ERROR',
'status_description' => 'Invalid authorization token!'
'status_description' => 'Invalid authorization token!',
], 403);
}
$data = $request->all();
if ($data['plant_code'] == null || $data['plant_code'] == '')
{
if ($data['plant_code'] == null || $data['plant_code'] == '') {
// return response("ERROR: Please provide a valid plant code.", 400)
// ->header('Content-Type', 'text/plain');
return response()->json([
'status_code' => 'ERROR',
'status_description' => "Plant code can't be empty!"
'status_description' => "Plant code can't be empty!",
], 400);
}
else if (Str::length($data['plant_code']) < 4 || !is_numeric($data['plant_code']) || !preg_match('/^[1-9]\d{3,}$/', $data['plant_code']))//!ctype_digit($data['plant_code'])
{
} elseif (Str::length($data['plant_code']) < 4 || ! is_numeric($data['plant_code']) || ! preg_match('/^[1-9]\d{3,}$/', $data['plant_code'])) {// !ctype_digit($data['plant_code'])
return response()->json([
'status_code' => 'ERROR',
'status_description' => "Invalid plant code found!"
'status_description' => 'Invalid plant code found!',
], 400);
}
$plant = Plant::where('code', $data['plant_code'])->first();
if (!$plant) {
//return response("Plant not found.", 400)->header('Content-Type', 'text/plain');
if (! $plant) {
// return response("Plant not found.", 400)->header('Content-Type', 'text/plain');
return response()->json([
'status_code' => 'ERROR',
'status_description' => 'Plant not found!'
'status_description' => 'Plant not found!',
], 400);
}
$plantId = $plant->id;
if ($data['line_name'] == null || $data['line_name'] == '')
{
if ($data['line_name'] == null || $data['line_name'] == '') {
return response()->json([
'status_code' => 'ERROR',
'status_description' => "Group work center can't be empty!"
'status_description' => "Group work center can't be empty!",
], 400);
}
else if (Str::length($data['line_name']) < 0)
{
} elseif (Str::length($data['line_name']) < 0) {
return response()->json([
'status_code' => 'ERROR',
'status_description' => "Invalid group work center found!"
'status_description' => 'Invalid group work center found!',
], 400);
}
$gWorkCenter = WorkGroupMaster::where('name', $data['line_name'])->first();
if (!$gWorkCenter)
{
if (! $gWorkCenter) {
return response()->json([
'status_code' => 'ERROR',
'status_description' => 'Group work center not found!'
'status_description' => 'Group work center not found!',
], 400);
}
$gWorkCenter = WorkGroupMaster::where('name', $data['line_name'])->where('plant_id', $plantId)->first();
if (!$gWorkCenter)
{
//return response( "Line not found for the specified plant : {$data['plant_code']}",400)->header('Content-Type', 'text/plain');
if (! $gWorkCenter) {
// return response( "Line not found for the specified plant : {$data['plant_code']}",400)->header('Content-Type', 'text/plain');
return response()->json([
'status_code' => 'ERROR',
'status_description' => "Group work center not found for the specified plant : '{$data['plant_code']}'!"
'status_description' => "Group work center not found for the specified plant : '{$data['plant_code']}'!",
], 400);
}
$gWorkCenterId = $gWorkCenter->id;
if ($data['machine_name'] == null || $data['machine_name'] == '')
{
if ($data['machine_name'] == null || $data['machine_name'] == '') {
return response()->json([
'status_code' => 'ERROR',
'status_description' => "Work center can't be empty!"
'status_description' => "Work center can't be empty!",
], 400);
}
else if (Str::length($data['machine_name']) < 0)
{
} elseif (Str::length($data['machine_name']) < 0) {
return response()->json([
'status_code' => 'ERROR',
'status_description' => "Invalid work center found!"
'status_description' => 'Invalid work center found!',
], 400);
}
$machine = Machine::where('work_center', $data['machine_name'])->first();
if (!$machine)
{
if (! $machine) {
return response()->json([
'status_code' => 'ERROR',
'status_description' => 'Work center not found!'
'status_description' => 'Work center not found!',
], 400);
}
$machine = Machine::where('work_center', $data['machine_name'])->where('plant_id', $plantId)->first();
if (!$machine)
{
if (! $machine) {
return response()->json([
'status_code' => 'ERROR',
'status_description' => "Work center not found for the specified plant : '{$data['plant_code']}'!"
'status_description' => "Work center not found for the specified plant : '{$data['plant_code']}'!",
], 400);
}
$machine = Machine::where('work_center', $data['machine_name'])->where('work_group_master_id', $gWorkCenterId)->first();
if (!$machine)
{
if (! $machine) {
// return response("Machine not found for the specified line : {$data['line_name']}", 400)->header('Content-Type', 'text/plain');
return response()->json([
'status_code' => 'ERROR',
'status_description' => "Work center not found for the specified Group work center : '{$data['line_name']}'!"
'status_description' => "Work center not found for the specified Group work center : '{$data['line_name']}'!",
], 400);
}
$machine = Machine::where('work_center', $data['machine_name'])->where('plant_id', $plantId)->where('work_group_master_id', $gWorkCenterId)->first();
if (!$machine) {
if (! $machine) {
return response()->json([
'status_code' => 'ERROR',
'status_description' => "Work center not found for the specified Plant : '{$data['plant_code']}' and Group work center : '{$data['line_name']}'!"
'status_description' => "Work center not found for the specified Plant : '{$data['plant_code']}' and Group work center : '{$data['line_name']}'!",
], 400);
}
$lineId = $machine->line_id;
$machineId = $machine->id;
try
{
try {
$insertedSerials = [];
$missedItemCodes = [];
$duplicateItemCodes = [];
$existSnoCount = [];
if (!empty($data['item_codes']) && is_array($data['item_codes']))
{
foreach ($data['item_codes'] as $item)
{
if (! empty($data['item_codes']) && is_array($data['item_codes'])) {
foreach ($data['item_codes'] as $item) {
$code = $item['item_code'] ?? null;
// Check if item_code is present
if ($code == '' || $code == null)
{
if ($code == '' || $code == null) {
return response()->json([
'status_code' => 'ERROR',
'status_description' => "Item code can't be empty!"
'status_description' => "Item code can't be empty!",
], 400);
}
// Collect duplicates
if (isset($itemCodeCounts[$code]))
{
if (isset($itemCodeCounts[$code])) {
$itemCodeCounts[$code]++;
// Only add to duplicates array once
if ($itemCodeCounts[$code] == 2) {
$duplicateItemCodes[] = $code;
}
}
else
{
} else {
$itemCodeCounts[$code] = 1;
}
@@ -209,43 +180,41 @@ class TestingPanelController extends Controller
$query->where('code', $item['item_code']);
})->where('plant_id', $plantId)->first();
if (!$motorTestingMaster) {
if (! $motorTestingMaster) {
$missedItemCodes[] = $item['item_code'];
}
if (!empty($item['serial_numbers']) && is_array($item['serial_numbers'])) {
foreach ($item['serial_numbers'] as $serial)
{
if (! empty($item['serial_numbers']) && is_array($item['serial_numbers'])) {
foreach ($item['serial_numbers'] as $serial) {
$existSnoCount[] = $serial['serial_number'];
}
}
}
// If any duplicates found, return error
if (!empty($duplicateItemCodes)) {
if (! empty($duplicateItemCodes)) {
return response()->json([
'status_code' => 'ERROR',
'status_description' => 'Duplicate item codes found in request: ' . implode(', ', $duplicateItemCodes)
'status_description' => 'Duplicate item codes found in request: '.implode(', ', $duplicateItemCodes),
], 400);
}
$uniqueInvalidCodes = array_unique($missedItemCodes);
if (!empty($uniqueInvalidCodes)) {
if (! empty($uniqueInvalidCodes)) {
// return response("Item codes : ". implode(', ', $uniqueInvalidCodes)." not found in motor testing master for the specified plant {$plant->name}", 400)
// ->header('Content-Type', 'text/plain');
return response()->json([
'status_code' => 'ERROR',
'status_description' => "Item codes : ". implode(', ', $uniqueInvalidCodes)." not found in master for the specified plant : '{$plant->name}'!"
'status_description' => 'Item codes : '.implode(', ', $uniqueInvalidCodes)." not found in master for the specified plant : '{$plant->name}'!",
], 400);
}
$insertedSnoCount = [];
foreach ($data['item_codes'] as $item)
{
foreach ($data['item_codes'] as $item) {
$motorTestingMaster = MotorTestingMaster::whereHas('item', callback: function ($query) use ($item) {
$query->where('code', $item['item_code']);
@@ -253,11 +222,9 @@ class TestingPanelController extends Controller
$motorTestingMasterId = $motorTestingMaster->id;
if (!empty($item['serial_numbers']) && is_array($item['serial_numbers']))
{
foreach ($item['serial_numbers'] as $serial)
{
//For update_count calculation
if (! empty($item['serial_numbers']) && is_array($item['serial_numbers'])) {
foreach ($item['serial_numbers'] as $serial) {
// For update_count calculation
$updateCount = [
'plant_id' => $plantId,
'line_id' => $lineId,
@@ -277,17 +244,17 @@ class TestingPanelController extends Controller
$maxLength = TestingPanelReading::where($updateCount)->selectRaw('MAX(LENGTH(update_count)) as max_length')->value('max_length');
// Then, get all records with that length
$lastUpdateCount = TestingPanelReading::where($updateCount)->whereRaw('LENGTH(update_count) = ?', [$maxLength])->orderByDesc('update_count')->select('update_count')->first();//->get();
$lastUpdateCount = TestingPanelReading::where($updateCount)->whereRaw('LENGTH(update_count) = ?', [$maxLength])->orderByDesc('update_count')->select('update_count')->first(); // ->get();
$newUpdateCount = ($lastUpdateCount == null || $lastUpdateCount == '') ? 0 : (int)$lastUpdateCount?->update_count + 1;//$maxUpdateCount?->update_count
$newUpdateCount = ($lastUpdateCount == null || $lastUpdateCount == '') ? 0 : (int) $lastUpdateCount?->update_count + 1; // $maxUpdateCount?->update_count
$updateCountString = (string)$newUpdateCount;
$updateCountString = (string) $newUpdateCount;
$row = [
'plant_id' => $plantId,
'line_id' => $lineId,
'machine_id' => $machineId,
'motor_testing_master_id'=> $motorTestingMasterId,
'motor_testing_master_id' => $motorTestingMasterId,
'serial_number' => $serial['serial_number'] ?? null,
'winded_serial_number' => $serial['winded_serial_number'] ?? null,
'output' => $serial['output'] ?? null,
@@ -346,32 +313,27 @@ class TestingPanelController extends Controller
}
}
if (!empty($insertedSerials))
{
if(count($existSnoCount) == count($insertedSnoCount))
{
if (! empty($insertedSerials)) {
if (count($existSnoCount) == count($insertedSnoCount)) {
// $messages[] = "Inserted serial numbers are: " . implode(', ', $insertedSerials);
return response()->json([
'status_code' => 'SUCCESS',
'status_description' => 'Inserted serial numbers are: ' . implode(', ', $insertedSerials)
'status_description' => 'Inserted serial numbers are: '.implode(', ', $insertedSerials),
], 200);
}
else
{
$missingSno = array_diff($existSnoCount,$insertedSnoCount);
} else {
$missingSno = array_diff($existSnoCount, $insertedSnoCount);
return response()->json([
'status_code' => 'ERROR',
'status_description' => "Missed serial numbers are: " . implode(', ', $missingSno)
'status_description' => 'Missed serial numbers are: '.implode(', ', $missingSno),
], 400);
}
}
}
catch (\Exception $e)
{
} catch (\Exception $e) {
// return response($e->getMessage(), 500)->header('Content-Type', 'text/plain');
return response()->json([
'status_code' => 'ERROR',
'status_description' => 'Store testing panel readings internal server error : '.$e?->getCode()
'status_description' => 'Store testing panel readings internal server error : '.$e?->getCode(),
], 500);
}
}
@@ -384,14 +346,13 @@ class TestingPanelController extends Controller
$expectedUser = env('API_AUTH_USER');
$expectedPw = env('API_AUTH_PW');
$header_auth = $request->header('Authorization');
$expectedToken = $expectedUser . ':' . $expectedPw;
$expectedToken = $expectedUser.':'.$expectedPw;
//$data = $request->all();
if ("Bearer " . $expectedToken != $header_auth)
{
// $data = $request->all();
if ('Bearer '.$expectedToken != $header_auth) {
return response()->json([
'status_code' => 'ERROR',
'status_description' => 'Invalid authorization token!'
'status_description' => 'Invalid authorization token!',
], 403);
}
@@ -399,45 +360,46 @@ class TestingPanelController extends Controller
$itemCode = $request->header('item-code');
// $description = $item ? $item->description : '';
if ($plantCode == null || $plantCode == '')
{
if ($plantCode == null || $plantCode == '') {
// return response("ERROR: Plant Name can't be empty", 400)
// ->header('Content-Type', 'text/plain');
return response()->json([
'status_code' => 'ERROR',
'status_description' => "Plant code can't be empty!"
'status_description' => "Plant code can't be empty!",
], 400);
}
else if (Str::length($plantCode) < 4 || !is_numeric($plantCode) || !preg_match('/^[1-9]\d{3,}$/', $plantCode))
{
} elseif (Str::length($plantCode) < 4 || ! is_numeric($plantCode) || ! preg_match('/^[1-9]\d{3,}$/', $plantCode)) {
return response()->json([
'status_code' => 'ERROR',
'status_description' => "Invalid plant code found!"
'status_description' => 'Invalid plant code found!',
], 400);
}
else if($itemCode == null || $itemCode == '')
{
// return response("ERROR: OBD Number can't be empty", 400)
// ->header('Content-Type', 'text/plain');
} elseif ($itemCode == null || $itemCode == '' || ! $itemCode) {
return response()->json([
'status_code' => 'ERROR',
'status_description' => "Item Code can't be empty!"
], 400);
}
else if(Str::length($itemCode) < 6 || !ctype_alnum($itemCode))
{
'status_description' => "Item code can't be empty!",
], 404);
} elseif (Str::length($itemCode) < 6) {
return response()->json([
'status_code' => 'ERROR',
'status_description' => "Invalid item code found!"
], 400);
'status_description' => "Item code '{$itemCode}' should contain minimum 6 digits!",
], 404);
} elseif (! ctype_alnum($itemCode)) {
return response()->json([
'status_code' => 'ERROR',
'status_description' => "Item code '{$itemCode}' should contain only alpha-numeric values!",
], 404);
} elseif (! preg_match('/^[a-zA-Z1-9][a-zA-Z0-9]{5,}$/', $itemCode)) {
return response()->json([
'status_code' => 'ERROR',
'status_description' => "Item code '{$itemCode}' should not begin with '0'!",
], 404);
}
$plant = Plant::where('code', $plantCode)->first();
if (!$plant) {
if (! $plant) {
return response()->json([
'status_code' => 'ERROR',
'status_description' => "Plant not found!"
'status_description' => 'Plant not found!',
], 400);
}
@@ -445,72 +407,79 @@ class TestingPanelController extends Controller
$item = Item::where('code', $itemCode)->first();
if (!$item)
{
if (! $item) {
return response()->json([
'status_code' => 'ERROR',
'status_description' => "Item Code not found in item table!"
'status_description' => 'Item code not found in item table!',
], 404);
}
$item = Item::where('plant_id', $plantId)->where('code', $itemCode)->first();
if (!$item)
{
if (! $item) {
return response()->json([
'status_code' => 'ERROR',
'status_description' => "Item Code not found in item table for the plant : '$plant->name'!"
'status_description' => "Item code not found in item table for the plant : '$plant->name'!",
], 404);
}
// Get description or empty string if not found
$itemId = $item->id;
$description = $item ? $item->description : '';
$category = $item ? $item->category : '';
$motorTestingMaster = MotorTestingMaster::where('plant_id', $plantId)->where('item_id', $item->id)->first();
$motorTestingMaster = MotorTestingMaster::where('item_id', $itemId)->first();
if (!$motorTestingMaster)
{
if (! $motorTestingMaster) {
return response()->json([
'status_code' => 'ERROR',
'status_description' => "Item Code not found in motor testing master table for the plant : '$plant->name'!"
'status_description' => 'Item code not found in motor testing master table!',
], 404);
}
$motorTestingMaster = MotorTestingMaster::where('plant_id', $plantId)->where('item_id', $itemId)->first();
if (! $motorTestingMaster) {
return response()->json([
'status_code' => 'ERROR',
'status_description' => "Item code not found in motor testing master table for the plant : '$plant->name'!",
], 404);
}
$output = [
"mot_subassembly_code" => $motorTestingMaster->subassembly_code ?? "",
"mot_model_name" => $description,
"mot_non_isi_model" => $motorTestingMaster->isi_model ? "0" :"1",
"mot_phase" => $motorTestingMaster->phase ?? "",
"mot_hp" => $motorTestingMaster->hp ?? "",
"mot_kw" => $motorTestingMaster->kw ?? "",
"mot_volt" => $motorTestingMaster->volt ?? "",
"mot_cur" => $motorTestingMaster->current ?? "",
"mot_rpm" => $motorTestingMaster->rpm ?? "",
"mot_rate_torque_kg" => $motorTestingMaster->torque ?? "",
"mot_freq" => $motorTestingMaster->frequency ?? "",
"mot_conn" => $motorTestingMaster->connection ?? "",
"mot_ins_res_limit" => $motorTestingMaster->ins_res_limit ?? "",
"mot_ins_res_type" => $motorTestingMaster->ins_res_type ?? "",
"mot_category" => $category,
"mot_routine_test_time" => $motorTestingMaster->routine_test_time ?? "",
"mot_res_ry_ll" => $motorTestingMaster->res_ry_ll ?? "",
"mot_res_ry_ul" => $motorTestingMaster->res_ry_ul ?? "",
"mot_res_yb_ll" => $motorTestingMaster->res_yb_ll ?? "",
"mot_res_yb_ul" => $motorTestingMaster->res_yb_ul ?? "",
"mot_res_br_ll" => $motorTestingMaster->res_br_ll ?? "",
"mot_res_br_ul" => $motorTestingMaster->res_br_ul ?? "",
"mot_lock_volt_limit" => $motorTestingMaster->lock_volt_limit ?? "",
"mot_leak_cur_limit" => $motorTestingMaster->leak_cur_limit ?? "",
"mot_lock_cur_ll" => $motorTestingMaster->lock_cur_ll ?? "",
"mot_lock_cur_ul" => $motorTestingMaster->lock_cur_ul ?? "",
"mot_noload_cur_ll" => $motorTestingMaster->noload_cur_ll ?? "",
"mot_noload_cur_ul" => $motorTestingMaster->noload_cur_ul ?? "",
"mot_noload_pow_ll" => $motorTestingMaster->noload_pow_ll ?? "",
"mot_noload_pow_ul" => $motorTestingMaster->noload_pow_ul ?? "",
"mot_noload_spd_ll" => $motorTestingMaster->noload_spd_ll ?? "",
"mot_noload_spd_ul" => $motorTestingMaster->noload_spd_ul ?? ""
'mot_subassembly_code' => $motorTestingMaster->subassembly_code ?? '',
'mot_model_name' => ($itemCode == '123456') ? 'SAMPLE TYPE' : $description,
'mot_non_isi_model' => $motorTestingMaster->isi_model ? '0' : '1',
'mot_phase' => $motorTestingMaster->phase ?? '',
'mot_hp' => $motorTestingMaster->hp ?? '',
'mot_kw' => $motorTestingMaster->kw ?? '',
'mot_volt' => $motorTestingMaster->volt ?? '',
'mot_cur' => $motorTestingMaster->current ?? '',
'mot_rpm' => $motorTestingMaster->rpm ?? '',
'mot_rate_torque_kg' => $motorTestingMaster->torque ?? '',
'mot_freq' => $motorTestingMaster->frequency ?? '',
'mot_conn' => $motorTestingMaster->connection ?? '',
'mot_ins_res_limit' => $motorTestingMaster->ins_res_limit ?? '',
'mot_ins_res_type' => $motorTestingMaster->ins_res_type ?? '',
'mot_category' => $category,
'mot_routine_test_time' => $motorTestingMaster->routine_test_time ?? '',
'mot_res_ry_ll' => $motorTestingMaster->res_ry_ll ?? '',
'mot_res_ry_ul' => $motorTestingMaster->res_ry_ul ?? '',
'mot_res_yb_ll' => $motorTestingMaster->res_yb_ll ?? '',
'mot_res_yb_ul' => $motorTestingMaster->res_yb_ul ?? '',
'mot_res_br_ll' => $motorTestingMaster->res_br_ll ?? '',
'mot_res_br_ul' => $motorTestingMaster->res_br_ul ?? '',
'mot_lock_volt_limit' => $motorTestingMaster->lock_volt_limit ?? '',
'mot_leak_cur_limit' => $motorTestingMaster->leak_cur_limit ?? '',
'mot_lock_cur_ll' => $motorTestingMaster->lock_cur_ll ?? '',
'mot_lock_cur_ul' => $motorTestingMaster->lock_cur_ul ?? '',
'mot_noload_cur_ll' => $motorTestingMaster->noload_cur_ll ?? '',
'mot_noload_cur_ul' => $motorTestingMaster->noload_cur_ul ?? '',
'mot_noload_pow_ll' => $motorTestingMaster->noload_pow_ll ?? '',
'mot_noload_pow_ul' => $motorTestingMaster->noload_pow_ul ?? '',
'mot_noload_spd_ll' => $motorTestingMaster->noload_spd_ll ?? '',
'mot_noload_spd_ul' => $motorTestingMaster->noload_spd_ul ?? '',
];
return response()->json($output, 200);

View File

@@ -30,7 +30,7 @@ class UserController extends Controller
* Display the specified resource.
*/
// show(string $id)
public function get_testing_data(Request $request)
public function get_user_data(Request $request)
{
$expectedUser = env('API_AUTH_USER');
$expectedPw = env('API_AUTH_PW');

View File

@@ -0,0 +1,268 @@
<?php
namespace App\Livewire;
use App\Mail\InvalidQualityMail;
use App\Models\AlertMailRule;
use App\Models\Item;
use App\Models\Line;
use App\Models\Plant;
use App\Models\ProductCharacteristicsMaster;
use App\Models\ProductionCharacteristic;
use App\Models\QualityValidation;
use Filament\Facades\Filament;
use Filament\Notifications\Notification;
use Illuminate\Support\Facades\Log;
use Illuminate\Support\Facades\Mail;
use Livewire\Component;
use Livewire\Attributes\On;
class ProductionCheckList extends Component
{
public $records = [];
public $existingRecords = [];
public bool $shouldSkipChecklist = false;
public array $checklist = [];
public $showChecklist = false;
public $skipChecklistValidation = false;
protected $listeners = ['focus-item-id' => 'handleFocus', 'trigger-create' => 'doCreate',];
public $data =
[
'item_id' => '',
'plant_id' => '',
];
public $data1 = [
'checklist' => [],
];
#[On('focus-item-id')]
public function handleFocus()
{
$this->dispatch('focus-input');
}
public function doCreate()
{
$this->create();
$this->shouldSkipChecklist = false;
}
public function mount($records = [])
{
$this->records = collect($records);
}
public function cancel()
{
$this->dispatch('checklist-cancelled');
}
public function saveChecklist()
{
if (empty($this->checklist) || count($this->checklist) != count($this->records)) {
Notification::make()
->title('Incomplete Checklist')
->body('Please complete all checklist fields before submitting.')
->danger()
->send();
return;
}
$item = Item::where('code', $this->data['item_id'])->first();
if (! $item) {
Notification::make()
->title('Invalid Item Code')
->body('Item not found for given code.')
->danger()
->send();
return;
}
$itemAgaPlant = Item::where('code', $this->data['item_id'])->where('plant_id', $this->data['plant_id'])->first();
$plant = Plant::find($this->data['plant_id']);
if (! $itemAgaPlant) {
Notification::make()
->title('Invalid Item Code')
->body("Item code '$this->data['item_id']' not found for given plant code '{$plant?->code}'.")
->danger()
->send();
return;
}
$itemId = $itemAgaPlant->id;
$exists = QualityValidation::where('plant_id', $this->data['plant_id'] ?? null)
->where('serial_number', $this->data['serial_number'] ?? null)
->first();
$plan = Plant::find($this->data['plant_id']);
if ($exists) {
Notification::make()
->title('Duplicate Serial Number')
->body("serial number {$this->data['serial_number']} already exists for the selected plant $plan->code.")
->danger()
->send();
return;
}
$qualityValidation = QualityValidation::create([
'plant_id' => $this->data['plant_id'] ?? null,
'line_id' => $this->data['line_id'] ?? null,
'sticker_master_id' => $this->data['sticker_master_id'] ?? null,
'production_order' => $this->data['production_order'] ?? null,
'serial_number_motor' => $this->data['serial_number_motor'] ?? null,
'serial_number_pump' => $this->data['serial_number_pump'] ?? null,
'serial_number_pumpset' => $this->data['serial_number_pumpset'] ?? null,
'pack_slip_motor' => $this->data['pack_slip_motor'] ?? null,
'pack_slip_pump' => $this->data['pack_slip_pump'] ?? null,
'pack_slip_pumpset' => $this->data['pack_slip_pumpset'] ?? null,
'name_plate_motor' => $this->data['name_plate_motor'] ?? null,
'name_plate_pump' => $this->data['name_plate_pump'] ?? null,
'name_plate_pumpset' => $this->data['name_plate_pumpset'] ?? null,
'tube_sticker_motor' => $this->data['tube_sticker_motor'] ?? null,
'tube_sticker_pump' => $this->data['tube_sticker_pump'] ?? null,
'tube_sticker_pumpset' => $this->data['tube_sticker_pumpset'] ?? null,
'warranty_card' => $this->data['warranty_card'] ?? null,
'part_validation1' => $this->data['part_validation1'] ?? null,
'part_validation2' => $this->data['part_validation2'] ?? null,
'part_validation3' => $this->data['part_validation3'] ?? null,
'part_validation4' => $this->data['part_validation4'] ?? null,
'part_validation5' => $this->data['part_validation5'] ?? null,
'operator_id' => $this->data['operator_id'] ?? null,
'uom' => $this->data['uom'] ?? null,
'serial_number' => $this->data['serial_number'] ?? null,
]);
if (! $qualityValidation || ! $qualityValidation->exists) {
Notification::make()
->title('Failed to save Quality Validation')
->body('Something went wrong while inserting data.')
->danger()
->send();
return;
}
$hasNotOk = collect($this->checklist)->contains(function ($val) {
return $val != 'ok';
});
$finalInspectionStatus = $hasNotOk ? 'NotOk' : 'Ok';
foreach ($this->checklist as $characteristicId => $value) {
$characteristic = ProductCharacteristicsMaster::find($characteristicId);
ProductionCharacteristic::create([
'plant_id' => $this->data['plant_id'] ?? null,
'item_id' => $itemId ?? null,
'line_id' => $this->data['line_id'] ?? null,
'machine_id' => $characteristic?->machine_id ?? null,
'production_order' => $this->data['production_order'] ?? null,
'serial_number' => $this->data['serial_number'] ?? null,
'characteristic_name' => $characteristic?->name ?? null,
'observed_value' => $this->data['observed_value'] ?? null,
'status' => $value == 'ok' ? 'Ok' : 'NotOk',
'inspection_status' => $finalInspectionStatus ?? null,
'created_by' => $this->data['operator_id'] ?? null,
]);
}
if ($finalInspectionStatus == 'NotOk') {
$mailData = \App\Filament\Resources\QualityValidationResource::getMailData($this->data['plant_id']);
$mPlantName = $mailData['plant_name'];
$emails = $mailData['emails'];
$mUserName = Filament::auth()->user()->name;
$itemCode = $this->data['item_id'] ?? null;
$sNo = $this->data['serial_number'] ?? null;
$mPorder = $this->data['production_order'] ?? null;
$mLinePart = Line::where('id', $this->data['line_id'] ?? null)
->value('name');
$mExpectedValue = null; // optional
$state = $itemCode . '|' . $sNo;
if (!empty($emails)) {
Mail::to($emails)->queue(
new InvalidQualityMail(
$state,
$mPorder,
$mPlantName,
$mLinePart,
$mUserName,
$mExpectedValue,
'FinalInspectionNotOk'
)
);
}
else {
\Log::warning("No emails configured for plant: {$mPlantName}");
}
}
$this->showChecklist = false;
$this->dispatch('checklist-saved');
}
public static function getMailData($plantId)
{
$globalEmails = AlertMailRule::where('plant', 0)
->where('module', 'QualityValidation')
->where('rule_name', 'QualityMail')
->where(fn ($q) => $q->whereNull('schedule_type')->orWhere('schedule_type', ''))
->pluck('email')
->toArray();
if (! empty($globalEmails)) {
return [
'plant_id' => 0,
'plant_name' => 'All Plants',
'emails' => $globalEmails,
];
}
$mPlantName = Plant::where('id', $plantId)->value('name');
$emails = AlertMailRule::where('plant', $plantId)
->where('module', 'QualityValidation')
->where('rule_name', 'QualityMail')
->where(fn ($q) => $q->whereNull('schedule_type')->orWhere('schedule_type', ''))
->pluck('email')
->toArray();
return [
'plant_id' => $plantId,
'plant_name' => $mPlantName,
'emails' => $emails,
];
}
public function updatedDataChecklist()
{
$this->dispatch('checklistUpdated', $this->data['checklist']);
}
public function render()
{
return view('livewire.production-check-list');
}
}

View File

@@ -0,0 +1,558 @@
<?php
namespace App\Livewire;
use App\Models\DuplicateStock;
use App\Models\Item;
use App\Models\NotInStock;
use App\Models\StickerMaster;
use App\Models\StockDataMaster;
use Filament\Notifications\Notification;
use Livewire\Component;
use Livewire\WithPagination;
class StockDataTable extends Component
{
public $invoiceData = [];
use WithPagination;
protected $paginationTheme = 'tailwind';
// public $invoiceRecords;
public $plantId = 0;
public $package = [];
public $scannedIds = [];
public $scannedRecords = [];
public $scannedSerials = [];
public $packageCount = 0;
public string $location = '';
public bool $completedInvoice = false;
public bool $isSerial = false;
public $isnonQuanSfg = false;
public bool $onCapFocus = false;
public bool $emptyInvoice = false;
public bool $hasSearched = false;
public bool $materialInvoice = false;
public bool $showCapacitorInput = false;
public bool $isSfg = false;
public $itemCode, $serialNumber, $serial_number;
public $scannedSfgData = [];
// protected $listeners = ['refreshInvoiceData' => 'loadData',];
protected $listeners = [
'refreshEmptyInvoice' => 'loadEmptyData',
'refreshInvoiceData' => 'loadData',
'refreshSfgData' => 'loadSfgData',
'refreshSfgNonData' => 'loadSfgNonQuanData',
'confirmStockUpdate',
'confirmSerialUpdate',
'confirmSerialFGUpdate',
'confirmDuplicateUpdate'
];
public $capacitorInput = '';
public $panel_box_supplier;
public $panel_box_code;
public $panel_box_serial_number;
public string $currentItemCode = '';
public string $currentSerialNumber = '';
public $stickerMasterId;
public $sNo;
public function confirmStockUpdate($plantId, $location, $bin, $stickerMasterId, $batch, $docNo, $quantity)
{
$record = NotInStock::where('plant_id', $plantId)
->where('location', $location)
->where('sticker_master_id', $stickerMasterId)
->where('doc_no', $docNo)
->where('bin', $bin)
->first();
if (!$record) {
NotInStock::create([
'plant_id' => $plantId,
'location' => $location,
'bin' => $bin,
'sticker_master_id' => $stickerMasterId,
'type' => '1',
'serial_number' => $this->serialNumber ?? null,
'batch' => $batch ?? null,
'doc_no' => $docNo ?? null,
'scanned_quantity' => $quantity ?? '0',
]);
Notification::make()
->title('Record inserted successfully in not in stock table.')
->success()
->send();
} else {
$record->update([
'scanned_quantity' => $record->scanned_quantity + $quantity,
'batch' => $batch ?? null,
'doc_no' => $docNo ?? null,
]);
Notification::make()
->title('Record updated in not in stock table.')
->success()
->send();
}
}
public function confirmSerialUpdate($plantId, $location, $bin, $serial_number, $stickerMasterId, $batch, $docNo, $quantity)
{
$sNo = $serial_number;
$record = NotInStock::where('plant_id', $plantId)
->where('location', $location)
->where('sticker_master_id', $stickerMasterId)
->where('serial_number', $sNo)
->where('bin', $bin)
->first();
if (!$record) {
NotInStock::create([
'plant_id' => $plantId,
'location' => $location,
'bin' => $bin,
'sticker_master_id' => $stickerMasterId,
'type' => '1',
'serial_number' => $sNo ?? null,
'batch' => $batch ?? null,
'doc_no' => $docNo ?? null,
'scanned_quantity' => $quantity ?? '1',
]);
Notification::make()
->title('Record inserted successfully in not in stock table.')
->success()
->send();
} else {
$record->update([
'batch' => $batch ?? null,
]);
Notification::make()
->title('Record updated in not in stock table.')
->success()
->send();
}
}
public function confirmDuplicateUpdate($plantId, $location, $bin, $serial_number, $stickerMasterId, $batch, $docNo, $quantity)
{
$sNo = $serial_number;
$stockRecord = StockDataMaster::where('serial_number', $sNo)
->where('plant_id', $plantId)
->first();
if (!$stockRecord) {
return;
}
$record = DuplicateStock::where('stock_data_master_id', $stockRecord->id)->first();
if (!$record) {
DuplicateStock::create([
'stock_data_master_id' => $stockRecord->id,
]);
Notification::make()
->title('Record inserted successfully in duplicate stock table.')
->success()
->send();
} else {
DuplicateStock::create([
'stock_data_master_id' => $stockRecord->id,
]);
Notification::make()
->title('Record inserted successfully in duplicate stock table.')
->success()
->send();
}
}
public function confirmSerialFGUpdate($plantId, $location, $bin, $serial_number, $stickerMasterId)
{
$sNo = $serial_number;
$record = NotInStock::where('plant_id', $plantId)
->where('location', $location)
->where('sticker_master_id', $stickerMasterId)
->where('serial_number', $sNo)
->where('bin', $bin)
->first();
if (!$record) {
NotInStock::create([
'plant_id' => $plantId,
'location' => $location,
'bin' => $bin,
'sticker_master_id' => $stickerMasterId,
'type' => '0',
'serial_number' => $sNo ?? null,
'batch' => $batch ?? null,
'doc_no' => $docNo ?? null,
'scanned_quantity' => $quantity ?? '1',
]);
Notification::make()
->title('Record inserted successfully in not in stock table.')
->success()
->send();
} else {
$record->update([
'batch' => $batch ?? null,
'doc_no' => $docNo ?? null,
]);
Notification::make()
->title('Record updated in not in stock table.')
->success()
->send();
}
}
public function loadCompletedData($location, $plantId, $isSerial)
{
$this->plantId = $plantId;
$this->location = $location;
$this->completedInvoice = true;
$this->isSerial = $isSerial;
$this->onCapFocus = false;
$this->emptyInvoice = false;
$this->hasSearched = false;
$this->materialInvoice = false;
$this->packageCount = 0;
// $this->showCapacitorInput = false;
$this->dispatch('focus-invoice-number');
}
public function loadEmptyData($location, $plantId)
{
$this->plantId = $plantId;
$this->location = $location;
$this->completedInvoice = false;
$this->onCapFocus = false;
$this->emptyInvoice = true;
$this->hasSearched = false;
$this->materialInvoice = false;
$this->packageCount = 0;
// $this->showCapacitorInput = false;
}
public function loadSfgData($location, $plantId, $itemCode,$docNo)
{
$this->isSfg = true;
$this->hasSearched = false;
// $this->materialInvoice = false;
// $this->completedInvoice = false;
// $this->emptyInvoice = false;
$item = Item::where('plant_id', $plantId)
->where('code', $itemCode)
->first();
$itemId = $item->id;
$stickerMaster = StickerMaster::where('plant_id', $plantId)
->where('item_id', $itemId)
->first();
$stickerMasterId = $stickerMaster->id;
$record = StockDataMaster::with('stickerMaster.item')
->where('plant_id', $plantId)
->where('location', $location)
->where('sticker_master_id', $stickerMasterId)
->where('doc_no', $docNo)
->where('type', '1')
->first();
if ($record) {
$itemCode = optional($record->stickerMaster->item)->code;
$foundIndex = null;
foreach ($this->scannedSfgData as $index => $row) {
if (
$row['location'] == $record->location &&
$row['doc_no'] == $record->doc_no &&
$row['item_code'] == $itemCode
) {
$foundIndex = $index;
break;
}
}
if ($foundIndex !== null) {
$this->scannedSfgData[$foundIndex]['scanned_quantity'] = $record->scanned_quantity;
} else {
if (count($this->scannedSfgData) >= 100) {
return;
}
$this->scannedSfgData[] = [
'serial_number' => $record->serial_number,
'bin' => $record->bin,
'item_code' => $itemCode,
'batch' => $record->batch,
'doc_no' => $record->doc_no,
'quantity' => $record->quantity,
'scanned_quantity' => $record->scanned_quantity,
'location' => $record->location,
'updated_by' => $record->updated_by,
];
}
}
}
public function loadSfgNonQuanData($location, $plantId, $serialNumber, $itemCode){
$this->isnonQuanSfg = true;
$record = StockDataMaster::with('stickerMaster.item')
->where('plant_id', $plantId)
->where('location', $location)
->where('serial_number', $serialNumber)
->whereHas('stickerMaster.item', function ($q) use ($itemCode) {
$q->where('code', $itemCode);
})
->where('type', '1')
->orderBy('updated_at', 'desc')
->first();
if ($record) {
// foreach ($this->scannedSerials as $row) {
// if ($row['serial_number'] == $serialNumber) {
// continue;
// }
// }
// $this->scannedSerials[] = [
array_unshift($this->scannedSerials, [
'location' => $record->location,
'bin' => $record->bin ?? '',
'item_code' => $record->stickerMaster->item->code ?? '',
'serial_number' => $serialNumber,
'batch' => $record->batch ?? '',
'doc_no' => $record->doc_no ?? '',
'quantity' => $record->quantity ?? '',
'scanned_quantity' => $record->scanned_quantity ?? '',
'updated_by' => $record->updated_by ?? '',
]);
// ];
}
}
public function loadData($location, $plantId, $itemCode, $serialNumber)
{
$this->location = $location;
$this->plantId = $plantId;
$this->itemCode = $itemCode;
$this->serialNumber = $serialNumber;
$this->completedInvoice = false;
$this->isSerial = true;
$this->emptyInvoice = false;
$this->hasSearched = true;
$this->materialInvoice = false;
$this->resetPage();
$this->packageCount = 0;
$item = Item::where('plant_id', $plantId)
->where('code', $this->itemCode)
->first();
$itemId = $item->id;
$stickerMaster = StickerMaster::where('plant_id', $plantId)
->where('item_id', $itemId)
->first();
$stickerMasterId = $stickerMaster->id;
$records = StockDataMaster::with('stickerMasterRelation')
->where('location', $this->location)
->where('type', '=', '0')
->where('plant_id', $this->plantId)
->where('sticker_master_id', $stickerMasterId)
->where('serial_number', $this->serialNumber)
->orderBy('updated_at', 'desc')
->limit(100)
->get();
foreach ($records as $record) {
if ($record->scanned_status == 'Scanned') {
if (!in_array($record->id, $this->scannedIds)) {
$this->scannedIds[] = $record->id;
}
}
}
$this->scannedIds = array_slice(array_unique($this->scannedIds), 0, 100);
$this->packageCount = $records->sum(function ($record) {
$sm = $record->stickerMasterRelation;
if (! $sm) {
return 0;
}
$stickCount = 0;
$scannedCount = 0;
if ($sm->tube_sticker_motor == 1 || $sm->tube_sticker_pump == 1 || $sm->tube_sticker_pumpset == 1) {
if ($sm->tube_sticker_motor == 1) {
$stickCount++;
if ($record->motor_scanned_status == 1) {
$scannedCount++;
}
}
if (
$sm->tube_sticker_pump == 1 ||
($sm->tube_sticker_pumpset != 1 &&
$sm->tube_sticker_pump != 1 &&
$sm->pack_slip_pump == 1)
) {
$stickCount++;
if ($record->pump_scanned_status == 1) {
$scannedCount++;
}
}
if ($sm->tube_sticker_pumpset == 1) {
$stickCount++;
if ($record->scanned_status_set == 1) {
$scannedCount++;
}
}
} elseif ($sm->pack_slip_motor == 1 || $sm->pack_slip_pump == 1 || $sm->pack_slip_pumpset == 1) {
if ($sm->pack_slip_motor == 1) {
$stickCount++;
if ($record->motor_scanned_status == 1) {
$scannedCount++;
}
}
if ($sm->pack_slip_pump == 1) {
$stickCount++;
if ($record->pump_scanned_status == 1) {
$scannedCount++;
}
}
if ($sm->pack_slip_pumpset == 1) {
$stickCount++;
if ($record->scanned_status_set == 1) {
$scannedCount++;
}
}
}
return max($stickCount - $scannedCount, 0);
});
// $this->dispatch(
// $onCapFocus ? 'focus-capacitor-input' : 'focus-serial-number'
// );
}
// public function getInvoiceRecordsProperty()
// {
// return StockDataMaster::with('stickerMasterRelation.item')
// ->where('plant_id', $this->plantId)
// ->where('location', $this->location)
// ->where('type', '=', '0')
// ->where('scanned_status', 'Scanned')
// // ->where(function ($query) {
// // $query->whereNull('scanned_status')
// // ->orWhere('scanned_status', 'Scanned');
// // })
// // ->when($this->hasSearched, function ($query) {
// // $query->where('invoice_number', $this->invoiceNumber)
// // ->where('plant_id', $this->plantId)
// // ->where('scanned_status', '=', '');
// // })
// ->orderBy('updated_at', 'desc')
// ->paginate(6);
// }
public function getInvoiceRecordsProperty()
{
if (empty($this->scannedIds)) {
return collect();
}
return StockDataMaster::with('stickerMasterRelation.item')
->whereIn('id', $this->scannedIds)
->orderBy('updated_at', 'desc')
->paginate(6);
}
public function render()
{
// return view('livewire.stock-data-table');
return view('livewire.stock-data-table', [
'records' => $this->invoiceRecords,
'scannedSfgData' => $this->scannedSfgData,
'scannedSerials' => $this->scannedSerials
]);
}
}

View File

@@ -28,10 +28,12 @@ class InvalidQualityMail extends Mailable
public $greeting;
public $subjectLine;
public $mExpectedValue;
public $mLinePart;
public $itemCode;
public function __construct($parNo, $mProdOrder, $mplantName, $mLinePart, $mUserName, $mailType = 'InvalidPartNumber')
public function __construct($parNo, $mProdOrder, $mplantName, $mLinePart, $mUserName, $mExpectedValue, $mailType = 'InvalidPartNumber')
{
$this->mPartNo = $parNo;
$this->mProdOrder = $mProdOrder;
@@ -39,6 +41,7 @@ class InvalidQualityMail extends Mailable
$this->mLinePart = $mLinePart;
$this->mUserName = $mUserName;
$this->mailType = $mailType;
$this->mExpectedValue = $mExpectedValue;
}
public function envelope(): Envelope
@@ -57,6 +60,12 @@ class InvalidQualityMail extends Mailable
case 'InvalidPartNumber5':
$this->subjectLine = "Quality Part Validation ({$this->mplantName})";
break;
case 'FinalInspectionNotOk':
$this->subjectLine = "Quality Part Validation Inspection Status ({$this->mplantName})";
break;
case 'InvalidTubeStickerPump':
$this->subjectLine = "Quality Part Validation ({$this->mplantName})";
break;
case 'InvalidPartNumber':
default:
$this->subjectLine = "Quality Part Validation ({$this->mplantName})";
@@ -80,6 +89,7 @@ class InvalidQualityMail extends Mailable
<b>Line Name:</b> {$this->mLinePart}<br>
<b>Production Order:</b> {$this->mProdOrder}<br>
<b>Scanned Part Number 2:</b> {$this->mPartNo}<br>
<b>Expected Scanned Part Number 2:</b> {$this->mExpectedValue}<br>
<b>Employee Code:</b> {$this->mUserName}<br>
";
break;
@@ -91,6 +101,7 @@ class InvalidQualityMail extends Mailable
<b>Line Name:</b> {$this->mLinePart}<br>
<b>Production Order:</b> {$this->mProdOrder}<br>
<b>Scanned Part Number 3:</b> {$this->mPartNo}<br>
<b>Expected Scanned Part Number 2:</b> {$this->mExpectedValue}<br>
<b>Employee Code:</b> {$this->mUserName}<br>
";
break;
@@ -102,6 +113,7 @@ class InvalidQualityMail extends Mailable
<b>Line Name:</b> {$this->mLinePart}<br>
<b>Production Order:</b> {$this->mProdOrder}<br>
<b>Scanned Part Number 4:</b> {$this->mPartNo}<br>
<b>Expected Scanned Part Number 2:</b> {$this->mExpectedValue}<br>
<b>Employee Code:</b> {$this->mUserName}<br>
";
break;
@@ -113,6 +125,52 @@ class InvalidQualityMail extends Mailable
<b>Line Name:</b> {$this->mLinePart}<br>
<b>Production Order:</b> {$this->mProdOrder}<br>
<b>Scanned Part Number 5:</b> {$this->mPartNo}<br>
<b>Expected Scanned Part Number 2:</b> {$this->mExpectedValue}<br>
<b>Employee Code:</b> {$this->mUserName}<br>
";
break;
case 'FinalInspectionNotOk':
$this->greeting = "
Dear Sir/Madam,<br><br>
Please note that the final inspection is not ok for scanned serial number.<br>
<b>Plant:</b> {$this->mplantName}<br>
<b>Line Name:</b> {$this->mLinePart}<br>
<b>Production Order:</b> {$this->mProdOrder}<br>
<b>Serial Number:</b> {$this->mPartNo}<br>
<b>Final Inspection :</b>Not OK<br>
<b>Employee Code:</b> {$this->mUserName}<br>
";
break;
case 'InvalidTubeStickerPump':
$this->greeting = "
Dear Sir/Madam,<br><br>
Please note that the scanned tube sticker pump serial number appears to be incorrect.<br>
<b>Plant:</b> {$this->mplantName}<br>
<b>Line Name:</b> {$this->mLinePart}<br>
<b>Production Order:</b> {$this->mProdOrder}<br>
<b>Scanned Tube Pump QR:</b> {$this->mPartNo}<br>
<b>Employee Code:</b> {$this->mUserName}<br>
";
break;
case 'InvalidTubeStickerMotor':
$this->greeting = "
Dear Sir/Madam,<br><br>
Please note that the scanned tube sticker motor serial number appears to be incorrect.<br>
<b>Plant:</b> {$this->mplantName}<br>
<b>Line Name:</b> {$this->mLinePart}<br>
<b>Production Order:</b> {$this->mProdOrder}<br>
<b>Scanned Tube Motor QR:</b> {$this->mPartNo}<br>
<b>Employee Code:</b> {$this->mUserName}<br>
";
break;
case 'InvalidTubeStickerPumpset':
$this->greeting = "
Dear Sir/Madam,<br><br>
Please note that the scanned tube sticker pumpset serial number appears to be incorrect.<br>
<b>Plant:</b> {$this->mplantName}<br>
<b>Line Name:</b> {$this->mLinePart}<br>
<b>Production Order:</b> {$this->mProdOrder}<br>
<b>Scanned Tube Pumpset QR:</b> {$this->mPartNo}<br>
<b>Employee Code:</b> {$this->mUserName}<br>
";
break;
@@ -125,6 +183,7 @@ class InvalidQualityMail extends Mailable
<b>Line Name:</b> {$this->mLinePart}<br>
<b>Production Order:</b> {$this->mProdOrder}<br>
<b>Scanned Part Number 1:</b> {$this->mPartNo}<br>
<b>Expected Scanned Part Number 1:</b> {$this->mExpectedValue}<br>
<b>Employee Code:</b> {$this->mUserName}<br>
";
break;

View File

@@ -0,0 +1,25 @@
<?php
namespace App\Models;
use Illuminate\Database\Eloquent\Model;
use Illuminate\Database\Eloquent\Relations\BelongsTo;
use Illuminate\Database\Eloquent\SoftDeletes;
class DuplicateStock extends Model
{
use SoftDeletes;
protected $fillable = [
'stock_data_master_id',
'created_at',
'updated_at',
'created_by',
'updated_by',
];
public function stockDataMaster(): BelongsTo
{
return $this->belongsTo(StockDataMaster::class);
}
}

View File

@@ -41,7 +41,7 @@ class Item extends Model
public function motorTestingMasters()
{
return $this->hasMany(MotorTestingMaster::class);
return $this->hasMany(MotorTestingMaster::class, 'item_id', 'id');
}
public function testingPanelReadings()
@@ -64,6 +64,21 @@ class Item extends Model
return $this->hasMany(CharacteristicValue::class);
}
public function ClassCharacteristics()
{
return $this->hasMany(ClassCharacteristic::class, 'item_id', 'id');
}
public function requestCharacteristics()
{
return $this->hasMany(RequestCharacteristic::class, 'item_id', 'id');
}
public function productionCharacteristics()
{
return $this->hasMany(ProductionCharacteristic::class, 'item_id', 'id');
}
public function weightValidations()
{
return $this->hasMany(WeightValidation::class);

View File

@@ -71,6 +71,11 @@ class Line extends Model
return $this->hasMany(CharacteristicValue::class);
}
public function productionCharacteristics()
{
return $this->hasMany(ProductionCharacteristic::class);
}
public function workGroup1()
{
return $this->belongsTo(WorkGroupMaster::class, 'work_group1_id', 'id');

View File

@@ -43,6 +43,21 @@ class Machine extends Model
return $this->hasMany(CharacteristicValue::class);
}
public function ClassCharacteristics()
{
return $this->hasMany(ClassCharacteristic::class, 'machine_id', 'id');
}
public function requestCharacteristics()
{
return $this->hasMany(RequestCharacteristic::class, 'machine_id', 'id');
}
public function productionCharacteristics()
{
return $this->hasMany(ProductionCharacteristic::class, 'machine_id', 'id');
}
public function testingPanelReadings()
{
return $this->hasMany(TestingPanelReading::class);

53
app/Models/NotInStock.php Normal file
View File

@@ -0,0 +1,53 @@
<?php
namespace App\Models;
use Illuminate\Database\Eloquent\Model;
use Illuminate\Database\Eloquent\Relations\BelongsTo;
use Illuminate\Database\Eloquent\SoftDeletes;
class NotInStock extends Model
{
use SoftDeletes;
protected $fillable = [
'plant_id',
'sticker_master_id',
'location',
'bin',
'serial_number',
'batch',
'quantity',
'doc_no',
'type',
'motor_scanned_status',
'pump_scanned_status',
'capacitor_scanned_status',
'scanned_status_set',
'panel_box_item_code',
'panel_box_supplier',
'panel_box_sno',
'scanned_status',
'scanned_quantity',
'created_by',
'updated_by',
'created_at',
'updated_at',
];
public function plant(): BelongsTo
{
return $this->belongsTo(Plant::class);
}
public function stickerMaster(): BelongsTo
{
return $this->belongsTo(StickerMaster::class);
}
public function stickerMasterRelation()
{
return $this->belongsTo(StickerMaster::class, 'sticker_master_id');
}
}

View File

@@ -53,11 +53,21 @@ class Plant extends Model
return $this->hasMany(InvoiceValidation::class, 'plant_id', 'id');
}
public function stockDataMasters()
{
return $this->hasMany(StockDataMaster::class, 'plant_id', 'id');
}
public function qualityValidations()
{
return $this->hasMany(QualityValidation::class, 'plant_id', 'id');
}
public function motorTestingMasters()
{
return $this->hasMany(MotorTestingMaster::class, 'plant_id', 'id');
}
public function testingPanelReadings()
{
return $this->hasMany(TestingPanelReading::class, 'plant_id', 'id');
@@ -108,11 +118,26 @@ class Plant extends Model
return $this->hasMany(EquipmentMaster::class, 'plant_id', 'id');
}
public function ClassCharacteristics()
{
return $this->hasMany(ClassCharacteristic::class, 'plant_id', 'id');
}
// public function rejectReasons()
// {
// return $this->hasMany(RejectReason::class, 'plant_id', 'id');
// }
public function requestCharacteristics()
{
return $this->hasMany(RequestCharacteristic::class, 'plant_id', 'id');
}
public function productionCharacteristics()
{
return $this->hasMany(ProductionCharacteristic::class, 'plant_id', 'id');
}
public function users()
{
return $this->hasMany(User::class, 'plant_id', 'id');

View File

@@ -21,6 +21,7 @@ class ProcessOrder extends Model
'coil_number',
'order_quantity',
'received_quantity',
'updated_order_quantity',
'sfg_number',
'machine_name',
'scrap_quantity',

View File

@@ -0,0 +1,50 @@
<?php
namespace App\Models;
use Illuminate\Database\Eloquent\Model;
use Illuminate\Database\Eloquent\Relations\BelongsTo;
use Illuminate\Database\Eloquent\SoftDeletes;
class ProductionCharacteristic extends Model
{
use SoftDeletes;
protected $fillable = [
'plant_id',
'line_id',
'item_id',
'machine_id',
'production_order',
'serial_number',
'observed_value',
'characteristic_name',
'status',
'inspection_status',
'remark',
'created_at',
'updated_at',
'created_by',
'updated_by',
];
public function plant(): BelongsTo
{
return $this->belongsTo(Plant::class);
}
public function line(): BelongsTo
{
return $this->belongsTo(Line::class);
}
public function item(): BelongsTo
{
return $this->belongsTo(Item::class);
}
public function machine(): BelongsTo
{
return $this->belongsTo(Machine::class);
}
}

View File

@@ -0,0 +1,53 @@
<?php
namespace App\Models;
use Illuminate\Database\Eloquent\Model;
use Illuminate\Database\Eloquent\Relations\BelongsTo;
use Illuminate\Database\Eloquent\SoftDeletes;
class StockDataMaster extends Model
{
use SoftDeletes;
protected $fillable = [
'plant_id',
'sticker_master_id',
'location',
'bin',
'serial_number',
'batch',
'quantity',
'doc_no',
'type',
'motor_scanned_status',
'pump_scanned_status',
'capacitor_scanned_status',
'scanned_status_set',
'panel_box_item_code',
'panel_box_supplier',
'panel_box_sno',
'scanned_status',
'scanned_quantity',
'created_by',
'updated_by',
'created_at',
'updated_at',
];
public function plant(): BelongsTo
{
return $this->belongsTo(Plant::class);
}
public function stickerMaster(): BelongsTo
{
return $this->belongsTo(StickerMaster::class);
}
public function stickerMasterRelation()
{
return $this->belongsTo(StickerMaster::class, 'sticker_master_id');
}
}

View File

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

View File

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

View File

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

View File

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

View File

@@ -1,7 +1,6 @@
<?php
use Illuminate\Database\Migrations\Migration;
use Illuminate\Database\Schema\Blueprint;
use Illuminate\Support\Facades\Schema;
return new class extends Migration

View File

@@ -142,7 +142,7 @@ return new class extends Migration
zmm_type TEXT DEFAULT NULL,
zmm_usp TEXT DEFAULT NULL,
mark_status TEXT DEFAULT NULL,
marked_datetime TIMESTAMP DEFAULT NULL,
marked_datetime TIMESTAMP NOT NULL DEFAULT NOW(),
marked_physical_count TEXT DEFAULT '0',
marked_expected_time TEXT DEFAULT '0',
marked_by TEXT DEFAULT NULL,
@@ -178,6 +178,7 @@ return new class extends Migration
updated_by TEXT DEFAULT NULL,
deleted_at TIMESTAMP,
UNIQUE (gernr, plant_id),
FOREIGN KEY (plant_id) REFERENCES plants (id),
FOREIGN KEY (machine_id) REFERENCES machines (id),
FOREIGN KEY (item_id) REFERENCES items (id)

View File

@@ -0,0 +1,61 @@
<?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 stock_data_masters (
id BIGINT GENERATED always AS IDENTITY PRIMARY KEY,
plant_id BIGINT NOT NULL,
sticker_master_id BIGINT NOT NULL,
location TEXT DEFAULT NULL,
bin TEXT DEFAULT NULL,
serial_number TEXT DEFAULT NULL,
batch TEXT DEFAULT NULL,
quantity TEXT DEFAULT NULL,
doc_no TEXT DEFAULT NULL,
type TEXT DEFAULT '0',
motor_scanned_status TEXT DEFAULT NULL,
pump_scanned_status TEXT DEFAULT NULL,
capacitor_scanned_status TEXT DEFAULT NULL,
scanned_status_set TEXT DEFAULT NULL,
panel_box_item_code TEXT DEFAULT NULL,
panel_box_supplier TEXT DEFAULT NULL,
panel_box_sno TEXT DEFAULT NULL,
scanned_status TEXT DEFAULT NULL,
scanned_quantity 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, serial_number),
FOREIGN KEY (plant_id) REFERENCES plants(id),
FOREIGN KEY (sticker_master_id) REFERENCES sticker_masters (id)
);
SQL;
DB::statement($sql);
}
/**
* Reverse the migrations.
*/
public function down(): void
{
Schema::dropIfExists('stock_data_masters');
}
};

View File

@@ -0,0 +1,60 @@
<?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 not_in_stocks (
id BIGINT GENERATED always AS IDENTITY PRIMARY KEY,
plant_id BIGINT NOT NULL,
sticker_master_id BIGINT NOT NULL,
location TEXT DEFAULT NULL,
bin TEXT DEFAULT NULL,
serial_number TEXT DEFAULT NULL,
batch TEXT DEFAULT NULL,
quantity TEXT DEFAULT NULL,
doc_no TEXT DEFAULT NULL,
type TEXT DEFAULT '0',
motor_scanned_status TEXT DEFAULT NULL,
pump_scanned_status TEXT DEFAULT NULL,
capacitor_scanned_status TEXT DEFAULT NULL,
scanned_status_set TEXT DEFAULT NULL,
panel_box_item_code TEXT DEFAULT NULL,
panel_box_supplier TEXT DEFAULT NULL,
panel_box_sno TEXT DEFAULT NULL,
scanned_status TEXT DEFAULT NULL,
scanned_quantity 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, serial_number),
FOREIGN KEY (plant_id) REFERENCES plants(id),
FOREIGN KEY (sticker_master_id) REFERENCES sticker_masters (id)
);
SQL;
DB::statement($sql);
}
/**
* Reverse the migrations.
*/
public function down(): void
{
Schema::dropIfExists('not_in_stocks');
}
};

View File

@@ -0,0 +1,39 @@
<?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 duplicate_stocks (
id BIGINT GENERATED always AS IDENTITY PRIMARY KEY,
stock_data_master_id BIGINT NOT 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 (stock_data_master_id) REFERENCES stock_data_masters(id)
);
SQL;
DB::statement($sql);
}
/**
* Reverse the migrations.
*/
public function down(): void
{
Schema::dropIfExists('duplicate_stocks');
}
};

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 process_orders
ADD COLUMN updated_order_quantity NUMERIC(10,3) NULL
SQL;
DB::statement($sql1);
}
/**
* Reverse the migrations.
*/
public function down(): void
{
// Schema::table('process_orders', function (Blueprint $table) {
// //
// });
}
};

View File

@@ -0,0 +1,53 @@
<?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_characteristics (
id BIGINT GENERATED always AS IDENTITY PRIMARY KEY,
plant_id BIGINT NOT NULL,
line_id BIGINT NOT NULL,
item_id BIGINT NOT NULL,
machine_id BIGINT NOT NULL,
production_order TEXT DEFAULT NULL,
serial_number TEXT DEFAULT NULL,
characteristic_name TEXT DEFAULT NULL,
observed_value TEXT DEFAULT NULL,
status TEXT DEFAULT NULL,
inspection_status 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),
FOREIGN KEY (line_id) REFERENCES lines (id),
FOREIGN KEY (item_id) REFERENCES items (id),
FOREIGN KEY (machine_id) REFERENCES machines (id)
);
SQL;
DB::statement($sql);
}
/**
* Reverse the migrations.
*/
public function down(): void
{
Schema::dropIfExists('production_characteristics');
}
};

View File

@@ -92,6 +92,7 @@ class PermissionSeeder extends Seeder
Permission::updateOrCreate(['name' => 'view import material invoice']);
Permission::updateOrCreate(['name' => 'view import invoice']);
Permission::updateOrCreate(['name' => 'view export invoice']);
Permission::updateOrCreate(['name' => 'view export asn invoice']);
Permission::updateOrCreate(['name' => 'view import locator invoice validation']);
Permission::updateOrCreate(['name' => 'view export locator invoice validation']);
@@ -197,5 +198,19 @@ class PermissionSeeder extends Seeder
Permission::updateOrCreate(['name' => 'view wire master print page']);
Permission::updateOrCreate(['name' => 'view cycle count page']);
Permission::updateOrCreate(['name' => 'view import stock data master']);
Permission::updateOrCreate(['name' => 'view export stock data master']);
Permission::updateOrCreate(['name' => 'view import duplicate stock']);
Permission::updateOrCreate(['name' => 'view export duplicate stock']);
Permission::updateOrCreate(['name' => 'view import production characteristics']);
Permission::updateOrCreate(['name' => 'view export production characteristics']);
Permission::updateOrCreate(['name' => 'view import temp class characteristic']);
Permission::updateOrCreate(['name' => 'view export temp class characteristic']);
}
}

View File

@@ -0,0 +1,6 @@
<div>
@livewire('production-check-list', [
'records' => $existingRecords,
'data' => $data
])
</div>

View File

@@ -0,0 +1,13 @@
<x-filament-panels::page>
<div class="space-y-4">
{{-- Render the Select form fields --}}
<div class="space-y-4">
{{ $this->form }}
</div>
<div class="bg-white shadow rounded-xl p-4 mt-6">
<livewire:stock-data-table />
</div>
</div>
</x-filament-panels::page>

View File

@@ -0,0 +1,126 @@
<x-filament-panels::page>
<!-- HEADER -->
<div class="mb-8">
<h1 class="text-4xl font-bold tracking-tight">
CRI Digital Manufacturing IIoT Platform
</h1>
<p class="text-lg text-gray-600 mt-2">
Complete visibility, traceability, and control across the manufacturing operations.
</p>
</div>
<!-- BANNER -->
{{-- <div class="w-full overflow-hidden rounded-2xl shadow mb-10"> --}}
<div class="w-full overflow-hidden rounded-xl shadow">
<img
src="{{ asset('images/iiot-banner.jpg') }}"
alt="CRI Digital Manufacturing IIoT"
class="w-full h-72 object-cover"
>
</div>
<!-- INTRO -->
<div class="max-w-4xl mb-10">
<p class="text-lg text-gray-700 mb-4">
CRI Digital Manufacturing IIoT is built to deliver
<strong>end-to-end traceability, real-time insights, and operational transparency</strong>
across plants, lines, and production processes.
</p>
<p class="text-lg text-gray-700">
The platform ensures <strong>right quality and on-time delivery</strong> by enabling
complete tracking of materials, production orders, and finished goods—helping teams
make faster, data-driven decisions with confidence.
</p>
</div>
<!-- KEY PILLARS -->
<div class="grid grid-cols-1 md:grid-cols-4 gap-6 mb-10">
<div class="bg-white rounded-xl border p-6 shadow-sm">
<h3 class="text-lg font-semibold mb-2">🔍 Traceability</h3>
<p class="text-gray-600">
Track materials, batches, and serials from input to dispatch.
</p>
</div>
<div class="bg-white rounded-xl border p-6 shadow-sm">
<h3 class="text-lg font-semibold mb-2"> Quality Assurance</h3>
<p class="text-gray-600">
Validate process data and ensure first-time-right production.
</p>
</div>
<div class="bg-white rounded-xl border p-6 shadow-sm">
<h3 class="text-lg font-semibold mb-2"> On-Time Delivery</h3>
<p class="text-gray-600">
Identify delays early and meet production commitments.
</p>
</div>
<div class="bg-white rounded-xl border p-6 shadow-sm">
<h3 class="text-lg font-semibold mb-2">📊 Real-Time Insights</h3>
<p class="text-gray-600">
Monitor performance and take quick corrective actions.
</p>
</div>
</div>
<!-- SUPPORT -->
<div class="bg-white rounded-xl border p-6 shadow-sm">
<h2 class="text-2xl font-semibold mb-3">24×7 Support</h2>
<p class="text-gray-700 mb-2">
Our dedicated IIoT support team is available round-the-clock to ensure
uninterrupted operations and quick issue resolution.
</p>
<p class="text-lg font-medium text-gray-900">
📞 Support Landline: <span class="font-semibold">0422 711 7179</span>
</p>
{{-- <p class="text-lg font-medium text-gray-900">
📞 Technical Support Contact: <span class="font-semibold">9952468104 / 9100832269</span>
</p> --}}
</div>
{{-- <div class="bg-white rounded-xl border p-6 shadow-sm">
<h2 class="text-2xl font-semibold mb-4">24×7 Support</h2>
<p class="text-lg text-gray-700 mb-4">
Our support structure is designed to ensure quick resolution based on the type
of issue whether it is on-site, application-related, or infrastructure-related.
</p>
<div class="space-y-3">
<p class="text-lg font-medium text-gray-900">
🏭 <strong>Plant & On-Site Support</strong> <br>
<span class="text-gray-700">
For plant visits, industry-level issues, and on-ground validation
</span><br>
📞 <span class="font-semibold">8925899458 / 8925899459</span>
</p>
<p class="text-lg font-medium text-gray-900">
💻 <strong>Application & Logic Support</strong> <br>
<span class="text-gray-700">
For website errors, logic issues, and application-level problems
</span><br>
📞 <span class="font-semibold">9952468104 / 9100832269</span>
</p>
</div>
</div> --}}
<!-- TEAM -->
{{-- <div class="bg-white rounded-xl border p-6 shadow-sm">
<h2 class="text-2xl font-semibold mb-4">IIOT Team Members</h2>
<div class="grid grid-cols-2 md:grid-cols-3 gap-4 text-gray-700">
<div class="flex items-center gap-2">👤 Jothikumar</div>
<div class="flex items-center gap-2">👤 Jeithef Shibu</div>
<div class="flex items-center gap-2">👤 Dhanabalan</div>
<div class="flex items-center gap-2">👤 Ranjith</div>
<div class="flex items-center gap-2">👤 Srimathy</div>
<div class="flex items-center gap-2">👤 Gokul</div>
</div>
</div> --}}
</x-filament-panels::page>

View File

@@ -1,126 +1,13 @@
<x-filament-panels::page>
<!-- HEADER -->
<div class="mb-8">
<h1 class="text-4xl font-bold tracking-tight">
CRI Digital Manufacturing IIoT Platform
</h1>
<p class="text-lg text-gray-600 mt-2">
Complete visibility, traceability, and control across your manufacturing operations.
</p>
<div class="grid grid-cols-1 sm:grid-cols-2 lg:grid-cols-3 gap-2 sm:gap-4 md:gap-4 p-2 md:p-4 items-start">
{{-- Filters form --}}
<div class="space-y-4 w-full max-w-full col-span-1">
{{ $this->filtersForm($this->form) }}
</div>
<!-- BANNER -->
{{-- <div class="w-full overflow-hidden rounded-2xl shadow mb-10"> --}}
<div class="w-full overflow-hidden rounded-xl shadow">
<img
src="{{ asset('images/iiot-banner.jpg') }}"
alt="CRI Digital Manufacturing IIoT"
class="w-full h-72 object-cover"
>
</div>
<!-- INTRO -->
<div class="max-w-4xl mb-10">
<p class="text-lg text-gray-700 mb-4">
CRI Digital Manufacturing IIoT is built to deliver
<strong>end-to-end traceability, real-time insights, and operational transparency</strong>
across plants, lines, and production processes.
</p>
<p class="text-lg text-gray-700">
The platform ensures <strong>right quality and on-time delivery</strong> by enabling
complete tracking of materials, production orders, and finished goods—helping teams
make faster, data-driven decisions with confidence.
</p>
</div>
<!-- KEY PILLARS -->
<div class="grid grid-cols-1 md:grid-cols-4 gap-6 mb-10">
<div class="bg-white rounded-xl border p-6 shadow-sm">
<h3 class="text-lg font-semibold mb-2">🔍 Traceability</h3>
<p class="text-gray-600">
Track materials, batches, and serials from input to dispatch.
</p>
</div>
<div class="bg-white rounded-xl border p-6 shadow-sm">
<h3 class="text-lg font-semibold mb-2"> Quality Assurance</h3>
<p class="text-gray-600">
Validate process data and ensure first-time-right production.
</p>
</div>
<div class="bg-white rounded-xl border p-6 shadow-sm">
<h3 class="text-lg font-semibold mb-2"> On-Time Delivery</h3>
<p class="text-gray-600">
Identify delays early and meet production commitments.
</p>
</div>
<div class="bg-white rounded-xl border p-6 shadow-sm">
<h3 class="text-lg font-semibold mb-2">📊 Real-Time Insights</h3>
<p class="text-gray-600">
Monitor performance and take quick corrective actions.
</p>
{{-- Stat widget --}}
<div class="w-full max-w-full col-span-1 sm:col-span-1 lg:col-span-2">
@livewire(\App\Filament\Widgets\CumulativeChart::class)
</div>
</div>
<!-- SUPPORT -->
<div class="bg-white rounded-xl border p-6 shadow-sm">
<h2 class="text-2xl font-semibold mb-3">24×7 Support</h2>
<p class="text-gray-700 mb-2">
Our dedicated IIoT support team is available round-the-clock to ensure
uninterrupted operations and quick issue resolution.
</p>
<p class="text-lg font-medium text-gray-900">
📞 Support Landline: <span class="font-semibold">0422 711 7179</span>
</p>
{{-- <p class="text-lg font-medium text-gray-900">
📞 Technical Support Contact: <span class="font-semibold">9952468104 / 9100832269</span>
</p> --}}
</div>
{{-- <div class="bg-white rounded-xl border p-6 shadow-sm">
<h2 class="text-2xl font-semibold mb-4">24×7 Support</h2>
<p class="text-lg text-gray-700 mb-4">
Our support structure is designed to ensure quick resolution based on the type
of issue whether it is on-site, application-related, or infrastructure-related.
</p>
<div class="space-y-3">
<p class="text-lg font-medium text-gray-900">
🏭 <strong>Plant & On-Site Support</strong> <br>
<span class="text-gray-700">
For plant visits, industry-level issues, and on-ground validation
</span><br>
📞 <span class="font-semibold">8925899458 / 8925899459</span>
</p>
<p class="text-lg font-medium text-gray-900">
💻 <strong>Application & Logic Support</strong> <br>
<span class="text-gray-700">
For website errors, logic issues, and application-level problems
</span><br>
📞 <span class="font-semibold">9952468104 / 9100832269</span>
</p>
</div>
</div> --}}
<!-- TEAM -->
{{-- <div class="bg-white rounded-xl border p-6 shadow-sm">
<h2 class="text-2xl font-semibold mb-4">IIOT Team Members</h2>
<div class="grid grid-cols-2 md:grid-cols-3 gap-4 text-gray-700">
<div class="flex items-center gap-2">👤 Jothikumar</div>
<div class="flex items-center gap-2">👤 Jeithef Shibu</div>
<div class="flex items-center gap-2">👤 Dhanabalan</div>
<div class="flex items-center gap-2">👤 Ranjith</div>
<div class="flex items-center gap-2">👤 Srimathy</div>
<div class="flex items-center gap-2">👤 Gokul</div>
</div>
</div> --}}
</x-filament-panels::page>

View File

@@ -0,0 +1,65 @@
<div class="fixed inset-0 flex items-center justify-center z-50">
<div class="bg-white max-h-[80vh] overflow-hidden p-6 rounded-lg shadow-lg pointer-events-auto"
style="width:30vw !important; max-width:none !important;">
@if($records && $records->count())
<div style="max-height:250px; overflow-y:auto; border:1px solid #ccc;">
{{-- <table class="min-w-full border"> --}}
<table class="w-full table-fixed border text-sm">
<thead>
<tr class="bg-gray-100">
<th class="border px-2 py-1 w-2/3">Characteristics</th>
<th class="border px-2 py-1 w-1/6">OK</th>
<th class="border px-2 py-1 w-1/6">Not OK</th>
</tr>
</thead>
<tbody>
@foreach($records as $record)
<tr>
<td class="border p-2">
{{ $record['name'] }}
</td>
<td class="border text-center">
<input type="radio"
wire:model="checklist.{{ $record['id'] }}"
value="ok">
</td>
<td class="border text-center">
<input type="radio"
wire:model="checklist.{{ $record['id'] }}"
value="not_ok">
</td>
</tr>
@endforeach
</tbody>
</table>
</div>
@else
<p>No records found.</p>
@endif
<div class="border-t mt-6 pt-4 flex justify-end gap-3">
<button
type="button"
wire:click="cancel"
style="background-color:#dc2626; color:white;"
class="px-6 py-2 rounded-lg shadow-md"
>
Cancel
</button>
<button
type="button"
wire:click="saveChecklist"
style="background-color:#16a34a; color:white;"
class="px-6 py-2 rounded-lg shadow-md"
>
Save
</button>
</div>
</div>
</div>

View File

@@ -0,0 +1,308 @@
<div>
<div class="mb-4">
<h2 class="text-lg font-bold text-gray-800">
@if ($hasSearched)
FG STOCK DATA TABLE
@elseif ($isSfg)
SFG STOCK DATA TABLE
@elseif ($isnonQuanSfg)
SFG STOCK DATA TABLE
@else
STOCK DATA TABLE
@endif
</h2>
</div>
<div class="mt-2">
<hr class="border-t-2 border-gray-300">
</div>
@if ($hasSearched)
<div class="overflow-x-auto" style="height: 385px;">
<table class="min-w-full text-sm text-center border border-gray-300">
<table class="table-fixed min-w-[1500px] text-sm text-center border border-gray-300">
<thead class="bg-gray-100 font-bold">
<tr>
<th class="border px-4 py-2">No</th>
<th class="border px-4 py-2">Material Code</th>
<th class="border px-4 py-2">Serial Number</th>
<th class="border px-4 py-2">Motor Scanned Status</th>
<th class="border px-4 py-2">Pump Scanned Status</th>
<th class="border px-4 py-2">Scanned Status Set</th>
<th class="border px-4 py-2">Scanned Status</th>
<th class="border px-4 py-2 w-[300px] whitespace-nowrap">Time Stamp</th>
<th class="border px-4 py-2">Operator ID</th>
</tr>
</thead>
<tbody>
@forelse ($records as $index => $record)
<tr wire:key="inv-{{ $record->id }}" class="border-t">
<td class="border px-2 py-2">{{ $records->firstItem() + $index }}</td>
<td class="border px-2 py-2">{{ $record->stickerMasterRelation?->item?->code ?? 'N/A' }}</td>
<td class="border px-2 py-2">{{ $record->serial_number ?? 'N/A' }}</td>
<td class="border px-2 py-2">{{ $record->motor_scanned_status ? '1' : '' }}</td>
<td class="border px-2 py-2">{{ $record->pump_scanned_status ? '1' : '' }}</td>
<td class="border px-2 py-2">{{ $record->scanned_status_set ? '1' : '' }}</td>
<td class="border px-2 py-2">{{ $record->scanned_status ?? '' }}</td>
<td class="border px-2 py-2 whitespace-nowrap">{{ optional($record->created_at)->format('d-m-Y H:i:s') }}</td>
<td class="border px-2 py-2">{{ $record->updated_by ?? '' }}</td>
</tr>
@empty
<tr>
<td colspan="12" class="py-4 text-gray-500">
No scanned data found for location <strong>{{ $location }}</strong>
</td>
</tr>
@endforelse
</tbody>
</table>
{{-- <div class="mt-3 flex justify-center">
{{ $records->onEachSide(3)->links() }}
</div> --}}
</div>
@endif
@if($isSfg)
<div class="w-full overflow-x-auto" style="height:385px">
<table class="w-full text-sm text-center border border-gray-300">
<thead class="bg-gray-100 font-bold">
<tr>
<th class="border px-4 py-2">No</th>
<th class="border px-4 py-2">Location</th>
<th class="border px-4 py-2">Bin</th>
<th class="border px-4 py-2">Item Code</th>
<th class="border px-4 py-2">Serial Number</th>
<th class="border px-4 py-2">Batch</th>
<th class="border px-4 py-2">Document Number</th>
<th class="border px-4 py-2">Total Quantity</th>
<th class="border px-4 py-2">Scanned Quantity</th>
<th class="border px-4 py-2">Operator ID</th>
</tr>
</thead>
<tbody>
@forelse($scannedSfgData as $index => $row)
<tr>
<td class="border px-3 py-2">{{ $index+1 }}</td>
<td class="border px-3 py-2">{{ $row['location'] }}</td>
<td class="border px-3 py-2">{{ $row['bin'] }}</td>
<td class="border px-3 py-2">{{ $row['item_code'] }}</td>
<td class="border px-3 py-2">{{ $row['serial_number'] }}</td>
<td class="border px-3 py-2">{{ $row['batch'] }}</td>
<td class="border px-3 py-2">{{ $row['doc_no'] }}</td>
<td class="border px-3 py-2">{{ $row['quantity'] }}</td>
<td class="border px-3 py-2">{{ $row['scanned_quantity'] }}</td>
<td class="border px-3 py-2">{{ $row['updated_by'] }}</td>
</tr>
@empty
<tr>
<td colspan="10" class="py-4 text-gray-500">
No scanned SFG data
</td>
</tr>
@endforelse
</tbody>
</table>
</div>
@endif
@if($isnonQuanSfg)
<div class="w-full overflow-x-auto" style="height:385px">
<table class="w-full text-sm text-center border border-gray-300">
<thead class="bg-gray-100 font-bold">
<tr>
<th class="border px-4 py-2">No</th>
<th class="border px-4 py-2">Location</th>
<th class="border px-4 py-2">Bin</th>
<th class="border px-4 py-2">Item Code</th>
<th class="border px-4 py-2">Serial Number</th>
<th class="border px-4 py-2">Batch</th>
<th class="border px-4 py-2">Document Number</th>
<th class="border px-4 py-2">Total Quantity</th>
<th class="border px-4 py-2">Scanned Quantity</th>
<th class="border px-4 py-2">Operator ID</th>
</tr>
</thead>
<tbody>
@forelse($scannedSerials as $index => $row)
<tr>
<td class="border px-3 py-2">{{ $index+1 }}</td>
<td class="border px-3 py-2">{{ $row['location'] }}</td>
<td class="border px-3 py-2">{{ $row['bin'] }}</td>
<td class="border px-3 py-2">{{ $row['item_code'] }}</td>
<td class="border px-3 py-2">{{ $row['serial_number'] }}</td>
<td class="border px-3 py-2">{{ $row['batch'] }}</td>
<td class="border px-3 py-2">{{ $row['doc_no'] }}</td>
<td class="border px-3 py-2">{{ $row['quantity'] }}</td>
<td class="border px-3 py-2">{{ $row['scanned_quantity'] }}</td>
<td class="border px-3 py-2">{{ $row['updated_by'] }}</td>
</tr>
@empty
<tr>
<td colspan="10" class="py-4 text-gray-500">
No scanned SFG data
</td>
</tr>
@endforelse
</tbody>
</table>
</div>
@endif
{{-- Modal for Capacitor Input --}}
<div>
<button wire:click="$set('showCapacitorInput', true)"></button>
@if($showCapacitorInput)
<div class="fixed inset-0 z-[9999] bg-black bg-opacity-50 flex items-center justify-center">
<div style="background:white; border:4px solid orange;" class="p-6 rounded-xl shadow-2xl w-[450px]">
<h3 class="text-xl font-semibold text-orange-700 mb-4">
Scan the Panel Box Supplier/Item Code/Serial Number
</h3>
<input
type="text"
id="capacitorInput"
autocomplete="off"
wire:model.defer="capacitorInput"
wire:keydown.enter.prevent="processCapacitorInput"
class="w-full border border-orange-300 rounded px-3 py-2 focus:outline-none focus:ring-0 focus:border-orange-300"
placeholder="Scan the panel box QR code"
{{-- autofocus --}}
onload="this.focus(); this.select();"
{{-- onfocus="this.select();" --}}
/>
<div class="flex justify-end gap-2 mt-4">
<button type="button" wire:click="cancelCapacitorInput"
class="mt-6 ml-10 bg-gray-300 hover:bg-gray-400 px-4 py-2 rounded transition">
Cancel
</button>
</div>
</div>
</div>
{{-- Add this script to focus on the input --}}
<script>
document.getElementById('capacitorInput').focus();
</script>
{{-- <script>
document.addEventListener('livewire:initialized', () => {
@this.on('focus-capacitor-input', () => {
setTimeout(() => {
const el = document.getElementById('capacitorInput');
if (el) el.focus();
}, 100);
});
});
</script> --}}
@endif
</div>
{{-- Modal for material invoice--}}
@if($materialInvoice)
{{-- <div class="flex justify-center overflow-x-auto overflow-y-visible" style="height: 385px;"> --}}
<div class="overflow-x-auto overflow-y-visible" style="height: 385px;">
{{-- <table class="min-w-full text-sm text-center border border-gray-300"> --}}
<table class="min-w-full mx-auto text-sm text-center border border-gray-300">
<thead class="bg-gray-100 font-bold">
<tr>
<th class="border px-4 py-2">No</th>
<th class="border px-4 py-2">Material Code</th>
<th class="border px-4 py-2">Material Type</th>
<th class="border px-4 py-2">Material Quantity</th>
<th class="border px-4 py-2">Serial Number</th>
<th class="border px-4 py-2">Batch Number</th>
<th class="border px-4 py-2">TimeStamp</th>
<th class="border px-4 py-2">Operator ID</th>
</tr>
</thead>
<tbody>
@forelse ($invoiceData as $index => $row)
<tr class="border-t">
<td class="border px-4 py-2">{{ $index + 1 }}</td>
<td class="border px-4 py-2">{{ $row['code'] ?? 'N/A' }}</td>
<td class="border px-4 py-2">{{ $row['material_type'] ?? 'N/A' }}</td>
<td class="border px-4 py-2">
@if(($row['material_type'] ?? '') === 'Individual' || ($row['material_type'] ?? '') === 'Bundle')
{{ number_format((float)($row['quantity'] ?? 0), 0) }}
@else
{{ $row['quantity'] ?? 'N/A' }}
@endif
</td>
<td class="border px-4 py-2">{{ $row['serial_number'] ?? 'N/A' }}</td>
<td class="border px-4 py-2">{{ $row['batch_number'] ?? 'N/A' }}</td>
<td class="border px-4 py-2">{{ $row['created_at'] ?? 'N/A' }}</td>
<td class="border px-4 py-2">{{ $row['operator_id'] ?? 'N/A' }}</td>
</tr>
@empty
<tr>
<td colspan="10" class="text-center py-4 text-gray-500">
No data found for invoice number <strong>{{ $invoiceNumber }}</strong>.
</td>
</tr>
@endforelse
</tbody>
</table>
</div>
@endif
</div>
{{-- <script>
// Clear input and set focus on form load
document.addEventListener('DOMContentLoaded', function () {
const input = document.getElementById('capacitorInput');
input.value = ''; // Clear the input field
input.focus(); // Set focus to the input field
});
</script> --}}
<script>
window.addEventListener('focus-capacitor-input', () => {
setTimeout(() => {
const input = document.getElementById('capacitorInput');
if (input) {
input.focus();
input.select();
}
}, 50);
});
window.addEventListener('focus-serial-number', () => {
setTimeout(() => {
const container = document.getElementById('serial_number_input');
const input = container?.querySelector('input'); // gets the actual input inside
if (input) {
input.focus();
input.select();
}
}, 50);
});
window.addEventListener('focus-invoice-number', () => {
setTimeout(() => {
const container = document.getElementById('invoice_number_input');
const input = container?.querySelector('input'); // gets the actual input inside
if (input) {
input.focus();
input.select();
}
}, 50);
});
</script>

View File

@@ -136,9 +136,13 @@ Route::post('serial-invoice/store-data', [InvoiceValidationController::class, 's
Route::post('material-invoice/store-data', [InvoiceValidationController::class, 'materialInvoice']);
// User Controller
Route::get('user/get-data', [UserController::class, 'get_user_data']);
// Testing panel Controller
Route::get('testing/user/get-data', [UserController::class, 'get_testing_data']);
Route::get('testing/user/get-data', [UserController::class, 'get_user_data']);
Route::get('testing/item/get-master-data', [TestingPanelController::class, 'get_motor_master']);
@@ -170,7 +174,7 @@ Route::get('laser/characteristics/check', [CharacteristicsController::class, 'ch
Route::post('laser/characteristics/data', [CharacteristicsController::class, 'storeClassChar']);
// ..serial (auto or manual)
// ..Marked serial (auto or manual)
Route::post('laser/characteristics/status', [CharacteristicsController::class, 'storeLaserStatus']);