change request email perregion

change-request
ajikamaludin 2 years ago
parent 51d3962676
commit dfb27457d2
Signed by: ajikamaludin
GPG Key ID: 476C9A2B4B794EBB

@ -0,0 +1,69 @@
<?php
namespace App\Console\Commands;
use App\Mail\DocumentRegionNotification;
use App\Models\Category;
use App\Models\Document;
use App\Models\Region;
use Illuminate\Console\Command;
use Illuminate\Support\Facades\Mail;
class TestDoc extends Command
{
/**
* The name and signature of the console command.
*
* @var string
*/
protected $signature = 'test:doc';
/**
* The console command description.
*
* @var string
*/
protected $description = 'Command description';
/**
* Execute the console command.
*
* @return int
*/
public function handle()
{
$docs = [];
$categories = Category::all();
foreach($categories as $category) {
foreach($category->documents()->with(['variety'])->get() as $doc) {
if ($doc->is_close_due != 0) {
$docs[$doc->company->region->id][] = $doc;
}
}
}
$regions = Region::all();
foreach($regions as $region) {
$rdocs = Document::with(['variety'])
->whereHas('creator', function ($query) use ($region) {
$query->where('region_id', $region->id);
})
->whereDate('due_date', '<=', now()->toDateString());
if ($rdocs->count() > 0) {
foreach($rdocs->get() as $doc) {
$docs[$region->id][] = $doc;
}
}
}
foreach($docs as $regionId => $doc) {
$region = Region::find($regionId);
if ($region != null && $region->email != '') {
Mail::to($region->email)->send(new DocumentRegionNotification($doc));
}
}
return Command::SUCCESS;
}
}

@ -16,7 +16,7 @@ class Kernel extends ConsoleKernel
*/ */
protected function schedule(Schedule $schedule) protected function schedule(Schedule $schedule)
{ {
$schedule->job(new DocumentReminder)->daily(); $schedule->job(new DocumentReminder)->everyMinute();
} }
/** /**

@ -74,7 +74,7 @@ class DocumentController extends Controller
{ {
$request->validate([ $request->validate([
"no_doc" => "nullable|string", "no_doc" => "nullable|string",
"name" => "required|string", "name" => "nullable|string",
"type_id" => "required|exists:types,id", "type_id" => "required|exists:types,id",
"category_id" => "required|exists:categories,id", "category_id" => "required|exists:categories,id",
"publisher" => "required|string", "publisher" => "required|string",
@ -149,7 +149,7 @@ class DocumentController extends Controller
{ {
$request->validate([ $request->validate([
"no_doc" => "nullable|string", "no_doc" => "nullable|string",
"name" => "required|string", "name" => "nullable|string",
"type_id" => "required|exists:types,id", "type_id" => "required|exists:types,id",
"category_id" => "required|exists:categories,id", "category_id" => "required|exists:categories,id",
"publisher" => "required|string", "publisher" => "required|string",

@ -31,12 +31,14 @@ class RegionController extends Controller
{ {
$request->validate([ $request->validate([
'name' => 'required|string|max:255', 'name' => 'required|string|max:255',
'group_id' => 'required|exists:groups,id' 'group_id' => 'required|exists:groups,id',
'email' => 'required|email',
]); ]);
Region::create([ Region::create([
'group_id' => $request->group_id, 'group_id' => $request->group_id,
'name' => $request->name 'name' => $request->name,
'email' => $request->email
]); ]);
} }
@ -51,12 +53,14 @@ class RegionController extends Controller
{ {
$request->validate([ $request->validate([
'name' => 'required|string|max:255', 'name' => 'required|string|max:255',
'group_id' => 'required|exists:groups,id' 'group_id' => 'required|exists:groups,id',
'email' => 'required|email',
]); ]);
$region->update([ $region->update([
'group_id' => $request->group_id, 'group_id' => $request->group_id,
'name' => $request->name 'name' => $request->name,
'email' => $request->email
]); ]);
} }

@ -3,7 +3,11 @@
namespace App\Http\Controllers; namespace App\Http\Controllers;
use App\Mail\DocumentNotification; use App\Mail\DocumentNotification;
use App\Mail\DocumentRegionNotification;
use App\Models\Category;
use App\Models\Document;
use App\Models\Mail as ModelsMail; use App\Models\Mail as ModelsMail;
use App\Models\Region;
use App\Models\Setting; use App\Models\Setting;
use Illuminate\Http\Request; use Illuminate\Http\Request;
use Illuminate\Support\Facades\Mail; use Illuminate\Support\Facades\Mail;
@ -21,18 +25,49 @@ class SettingController extends Controller
public function update(Request $request) public function update(Request $request)
{ {
$request->validate([ $request->validate([
'email' => 'required|email', 'email' => 'nullable|email',
]); ]);
Setting::where('key', 'DESTINATION_MAIL')->update([ Setting::where('key', 'DESTINATION_MAIL')->update([
'value' => $request->email, 'value' => $request->email ?? '',
]); ]);
if ($request->has('test')) { if ($request->has('test') && $request->email != null) {
$users = ModelsMail::all()->pluck('value')->toArray(); $users = ModelsMail::all()->pluck('value')->toArray();
Mail::to($request->email) Mail::to($request->email)
->cc($users) ->cc($users)
->send(new DocumentNotification()); ->send(new DocumentNotification());
$docs = [];
$categories = Category::all();
foreach($categories as $category) {
foreach($category->documents()->with(['variety'])->get() as $doc) {
if ($doc->is_close_due != 0) {
$docs[$doc->company->region->id][] = $doc;
}
}
}
$regions = Region::all();
foreach($regions as $region) {
$rdocs = Document::with(['variety'])
->whereHas('company', function ($query) use ($region) {
$query->where('region_id', $region->id);
})
->whereDate('due_date', '<=', now()->toDateString());
if ($rdocs->count() > 0) {
foreach($rdocs->get() as $doc) {
$docs[$region->id][] = $doc;
}
}
}
foreach($docs as $regionId => $doc) {
$region = Region::find($regionId);
if ($region != null && $region->email != '') {
Mail::to($region->email)->send(new DocumentRegionNotification($doc));
}
}
} }
} }

@ -3,14 +3,19 @@
namespace App\Jobs; namespace App\Jobs;
use App\Mail\DocumentNotification; use App\Mail\DocumentNotification;
use App\Mail\DocumentRegionNotification;
use App\Models\Category;
use App\Models\Document;
use App\Models\Setting; use App\Models\Setting;
use App\Models\Mail as ModelsMail; use App\Models\Mail as ModelsMail;
use App\Models\Region;
use Illuminate\Bus\Queueable; use Illuminate\Bus\Queueable;
use Illuminate\Contracts\Queue\ShouldBeUnique; use Illuminate\Contracts\Queue\ShouldBeUnique;
use Illuminate\Contracts\Queue\ShouldQueue; use Illuminate\Contracts\Queue\ShouldQueue;
use Illuminate\Foundation\Bus\Dispatchable; use Illuminate\Foundation\Bus\Dispatchable;
use Illuminate\Queue\InteractsWithQueue; use Illuminate\Queue\InteractsWithQueue;
use Illuminate\Queue\SerializesModels; use Illuminate\Queue\SerializesModels;
use Illuminate\Support\Facades\Log;
use Illuminate\Support\Facades\Mail; use Illuminate\Support\Facades\Mail;
class DocumentReminder implements ShouldQueue class DocumentReminder implements ShouldQueue
@ -34,11 +39,46 @@ class DocumentReminder implements ShouldQueue
*/ */
public function handle() public function handle()
{ {
Log::info('staring', ['send email']);
$email = Setting::where('key', 'DESTINATION_MAIL')->first(); $email = Setting::where('key', 'DESTINATION_MAIL')->first();
$users = ModelsMail::all()->pluck('value')->toArray(); $users = ModelsMail::all()->pluck('value')->toArray();
if ($email?->value != '') {
Mail::to($email->value) Mail::to($email->value)
->cc($users) ->cc($users)
->send(new DocumentNotification()); ->send(new DocumentNotification());
} }
$docs = [];
$categories = Category::all();
foreach($categories as $category) {
foreach($category->documents()->with(['variety'])->get() as $doc) {
if ($doc->is_close_due != 0) {
$docs[$doc->company->region->id][] = $doc;
}
}
}
$regions = Region::all();
foreach($regions as $region) {
$rdocs = Document::with(['variety'])
->whereHas('company', function ($query) use ($region) {
$query->where('region_id', $region->id);
})
->whereDate('due_date', '<=', now()->toDateString());
if ($rdocs->count() > 0) {
foreach($rdocs->get() as $doc) {
$docs[$region->id][] = $doc;
}
}
}
foreach($docs as $regionId => $doc) {
$region = Region::find($regionId);
if ($region != null && $region->email != '') {
Mail::to($region->email)->send(new DocumentRegionNotification($doc));
}
}
}
} }

@ -0,0 +1,50 @@
<?php
namespace App\Mail;
use Illuminate\Bus\Queueable;
use Illuminate\Contracts\Queue\ShouldQueue;
use Illuminate\Mail\Mailable;
use Illuminate\Mail\Mailables\Content;
use Illuminate\Mail\Mailables\Envelope;
use Illuminate\Queue\SerializesModels;
class DocumentRegionNotification extends Mailable
{
use Queueable, SerializesModels;
/**
* Create a new message instance.
*
* @return void
*/
public function __construct(
public $docs,
)
{}
/**
* Get the message envelope.
*
* @return \Illuminate\Mail\Mailables\Envelope
*/
public function envelope()
{
return new Envelope(
subject: 'Document Region Notification',
);
}
/**
* Build the message.
*
* @return $this
*/
public function build()
{
return $this->markdown('emails.document.notification', [
'documents' => $this->docs,
'dueDocuments' => []
]);
}
}

@ -74,16 +74,16 @@ class Document extends Model
return ''; return '';
} }
if (now()->toDateString() == $this->due_date->toDateString()) { if (now()->toDateString() == $this->due_date->toDateString()) {
return "hari ini jatuh tempo"; return "Hari ini jatuh tempo";
} }
$date = now()->diffInDays($this->due_date, false) + 1; $date = now()->diffInDays($this->due_date, false) + 1;
if ($diff >= $date && $date > 0) { if ($diff >= $date && $date > 0) {
return $date . " hari mendekati jatuh tempo"; return $date . " Hari mendekati jatuh tempo";
} }
if ($date <= 0) { if ($date <= 0) {
return "jatuh tempo"; return "Jatuh tempo";
} }
}, },
); );

@ -13,6 +13,7 @@ class Region extends Model
protected $fillable = [ protected $fillable = [
"name", "name",
"group_id", "group_id",
"email"
]; ];
protected $cascadeDeletes = ['companies', 'users']; protected $cascadeDeletes = ['companies', 'users'];

@ -0,0 +1,41 @@
<?php
use App\Models\Permission;
use Illuminate\Database\Migrations\Migration;
use Illuminate\Database\Schema\Blueprint;
use Illuminate\Support\Facades\Schema;
return new class extends Migration
{
/**
* Run the migrations.
*
* @return void
*/
public function up()
{
Schema::table('regions', function ($table) {
$table->string('email')->nullable();
});
$permission = Permission::where('name', 'download-document')->first();
if ($permission == null) {
Permission::create([
'name' => 'download-document',
'label' => 'Download Documen'
]);
}
}
/**
* Reverse the migrations.
*
* @return void
*/
public function down()
{
Schema::table('regions', function ($table) {
$table->dropColumn('email');
});
}
};

@ -51,6 +51,7 @@ class DatabaseSeeder extends Seeder
['name' => 'delete-document', 'label' => 'Hapus Dokumen'], ['name' => 'delete-document', 'label' => 'Hapus Dokumen'],
['name' => 'import-document', 'label' => 'Import Dokumen'], ['name' => 'import-document', 'label' => 'Import Dokumen'],
['name' => 'export-document', 'label' => 'Export Dokumen'], ['name' => 'export-document', 'label' => 'Export Dokumen'],
['name' => 'download-document', 'label' => 'Download Documen'],
['name' => 'view-category', 'label' => 'Lihat Kategori'], ['name' => 'view-category', 'label' => 'Lihat Kategori'],
['name' => 'update-category', 'label' => 'Edit Kategori'], ['name' => 'update-category', 'label' => 'Edit Kategori'],
['name' => 'create-category', 'label' => 'Buat Kategori'], ['name' => 'create-category', 'label' => 'Buat Kategori'],

@ -5,12 +5,14 @@ import DocStatusItem from './DocStatusItem'
import AuthenticatedLayout from '@/Layouts/AuthenticatedLayout' import AuthenticatedLayout from '@/Layouts/AuthenticatedLayout'
import InputLabel from '@/Components/InputLabel' import InputLabel from '@/Components/InputLabel'
import TextInput from '@/Components/TextInput' import TextInput from '@/Components/TextInput'
import { formatDate } from '@/utils' import { formatDate, hasPermission } from '@/utils'
import { useModalState } from '@/Hooks' import { useModalState } from '@/Hooks'
export default function FormDocument(props) { export default function FormDocument(props) {
const { doc, doc_url }= props const { doc, doc_url }= props
const canDownload = hasPermission('download-document', props.auth.user)
return ( return (
<AuthenticatedLayout <AuthenticatedLayout
auth={props.auth} auth={props.auth}
@ -159,10 +161,12 @@ export default function FormDocument(props) {
readOnly={true} readOnly={true}
/> />
</div> </div>
{canDownload && (
<div className='mt-4'> <div className='mt-4'>
<InputLabel forInput="document" value="Dokumen" /> <InputLabel forInput="document" value="Dokumen" />
<a href={doc_url} className='btn btn-outline'>Download</a> <a href={doc_url} className='btn btn-outline'>Download</a>
</div> </div>
)}
<div className='mt-4'> <div className='mt-4'>
<div className="flex w-32 justify-between items-center"> <div className="flex w-32 justify-between items-center">
<InputLabel value="Status" /> <InputLabel value="Status" />

@ -138,7 +138,7 @@ export default function Document(props) {
<th className='hover:underline' onClick={() => sort('type_id')}>Jenis</th> <th className='hover:underline' onClick={() => sort('type_id')}>Jenis</th>
<th className='hover:underline' onClick={() => sort('category_id')}>Ketegori</th> <th className='hover:underline' onClick={() => sort('category_id')}>Ketegori</th>
<th>No Dokumen</th> <th>No Dokumen</th>
<th>Nama Dokumen</th> {/* <th>Nama Dokumen</th> */}
<th className='hover:underline' onClick={() => sort('publish_date')}>Tanggal Terbit</th> <th className='hover:underline' onClick={() => sort('publish_date')}>Tanggal Terbit</th>
<th className='hover:underline' onClick={() => sort('due_date')}>Tanggal Berakhir</th> <th className='hover:underline' onClick={() => sort('due_date')}>Tanggal Berakhir</th>
<th>Catatan</th> <th>Catatan</th>
@ -152,7 +152,7 @@ export default function Document(props) {
<td>{doc.variety.name}</td> <td>{doc.variety.name}</td>
<td>{doc.category.name}</td> <td>{doc.category.name}</td>
<td>{doc.no_doc}</td> <td>{doc.no_doc}</td>
<td>{doc.name}</td> {/* <td>{doc.name}</td> */}
<td> <td>
{doc.publish_date !== null ? formatDate(doc.publish_date) : ''} {doc.publish_date !== null ? formatDate(doc.publish_date) : ''}
</td> </td>

@ -8,7 +8,8 @@ export default function FormModal(props) {
const { data, setData, post, put, processing, errors, reset, clearErrors } = useForm({ const { data, setData, post, put, processing, errors, reset, clearErrors } = useForm({
name: '', name: '',
group_id: '' group_id: '',
email: '',
}) })
const handleOnChange = (event) => { const handleOnChange = (event) => {
@ -54,7 +55,8 @@ export default function FormModal(props) {
if (region !== null) { if (region !== null) {
setData({ setData({
name: region?.name, name: region?.name,
group_id: region?.group_id group_id: region?.group_id,
email: region?.email,
}) })
} }
}, [modalState]) }, [modalState])
@ -116,6 +118,24 @@ export default function FormModal(props) {
</span> </span>
</label> </label>
</div> </div>
<div className="form-control">
<label className="label">
<span className="label-text font-semibold">Email</span>
</label>
<input
type="text"
placeholder="email"
className={`input input-bordered ${
errors.email && 'input-error'
}`}
name="email"
value={data.email}
onChange={handleOnChange}
/>
<label className="label">
<span className="label-text-alt text-red-600">{errors.email}</span>
</label>
</div>
<div className="modal-action"> <div className="modal-action">
<div <div
onClick={handleSubmit} onClick={handleSubmit}

@ -66,6 +66,7 @@ export default function Types(props) {
<th>Id</th> <th>Id</th>
<th>Nama</th> <th>Nama</th>
<th>Group</th> <th>Group</th>
<th>Email</th>
<th></th> <th></th>
</tr> </tr>
</thead> </thead>
@ -75,6 +76,7 @@ export default function Types(props) {
<th>{region.id}</th> <th>{region.id}</th>
<td>{`${region.name} (${region.group.name})`}</td> <td>{`${region.name} (${region.group.name})`}</td>
<td>{region.group.name}</td> <td>{region.group.name}</td>
<td>{region.email}</td>
<td className="text-right"> <td className="text-right">
{canUpdate && ( {canUpdate && (
<div <div

@ -6,10 +6,10 @@ Reminder, untuk dokumen perlu diperhatikan :
|No | Nama | Jenis | Status | |No | Nama | Jenis | Status |
| ----------------------- |:---------------------:|:------------------------------:| ---------------------------:| | ----------------------- |:---------------------:|:------------------------------:| ---------------------------:|
| @foreach($dueDocuments as $document) | @foreach($dueDocuments as $document)
| {{ $document->no_doc }} | {{ $document->name }} | {{ $document->variety->name }} | {{ $document->due_status }} | | {{ $document->no_doc }} | {{ $document->company->name }} | {{ $document->variety->name }} | {{ $document->due_status }} |
| @endforeach | @endforeach
|@foreach($documents as $document) |@foreach($documents as $document)
| {{ $document->no_doc }} | {{ $document->name }} | {{ $document->variety->name }} | {{ $document->due_status }} | | {{ $document->no_doc }} | {{ $document->company->name }} | {{ $document->variety->name }} | {{ $document->due_status }} |
|@endforeach |@endforeach
@endcomponent @endcomponent

Loading…
Cancel
Save