Compare commits

...

5 Commits

@ -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)
{
$schedule->job(new DocumentReminder)->daily();
$schedule->job(new DocumentReminder)->everyMinute();
}
/**

@ -74,7 +74,7 @@ class DocumentController extends Controller
{
$request->validate([
"no_doc" => "nullable|string",
"name" => "required|string",
"name" => "nullable|string",
"type_id" => "required|exists:types,id",
"category_id" => "required|exists:categories,id",
"publisher" => "required|string",
@ -149,7 +149,7 @@ class DocumentController extends Controller
{
$request->validate([
"no_doc" => "nullable|string",
"name" => "required|string",
"name" => "nullable|string",
"type_id" => "required|exists:types,id",
"category_id" => "required|exists:categories,id",
"publisher" => "required|string",
@ -243,9 +243,9 @@ class DocumentController extends Controller
'penerbit' => $document->publisher,
'tipe' => $document->type == Document::TYPE_TETAP ? 'Tetap' : 'Tidak Tetap',
'tanggal terbit' => $document->publish_date->format('d-m-Y'),
'tanggal jatuh tempo' => $document->due_date->format('d-m-Y'),
'tanggal jatuh tempo' => $document->due_date?->format('d-m-Y'),
'keterangan' => $document->description,
'file' => asset('documents/'.$document->document),
'file' => $document->document != null ? asset('documents/'.$document->document) : null,
'status' => $document->status == Document::STATUS_YES ? 'Ya' : 'Tidak',
'catatan' => $document->due_status,
]);
@ -276,10 +276,8 @@ class DocumentController extends Controller
private function exportAsExcel($collections)
{
$date = now()->format('d-m-Y');
$header_style = (new StyleBuilder())->setFontBold()->build();
return (new FastExcel($collections))
->headerStyle($header_style)
->download("document-$date.xlsx");
}
}

@ -8,7 +8,7 @@ use Illuminate\Http\Request;
class RegionController extends Controller
{
/**
/**
* Display a listing of the resource.
*
* @return \Illuminate\Http\Response
@ -31,12 +31,14 @@ class RegionController extends Controller
{
$request->validate([
'name' => 'required|string|max:255',
'group_id' => 'required|exists:groups,id'
'group_id' => 'required|exists:groups,id',
'email' => 'required|email',
]);
Region::create([
'group_id' => $request->group_id,
'name' => $request->name
'name' => $request->name,
'email' => $request->email
]);
}
@ -51,12 +53,14 @@ class RegionController extends Controller
{
$request->validate([
'name' => 'required|string|max:255',
'group_id' => 'required|exists:groups,id'
'group_id' => 'required|exists:groups,id',
'email' => 'required|email',
]);
$region->update([
'group_id' => $request->group_id,
'name' => $request->name
'name' => $request->name,
'email' => $request->email
]);
}

@ -3,7 +3,11 @@
namespace App\Http\Controllers;
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\Region;
use App\Models\Setting;
use Illuminate\Http\Request;
use Illuminate\Support\Facades\Mail;
@ -21,18 +25,49 @@ class SettingController extends Controller
public function update(Request $request)
{
$request->validate([
'email' => 'required|email',
'email' => 'nullable|email',
]);
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();
Mail::to($request->email)
->cc($users)
->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;
use App\Mail\DocumentNotification;
use App\Mail\DocumentRegionNotification;
use App\Models\Category;
use App\Models\Document;
use App\Models\Setting;
use App\Models\Mail as ModelsMail;
use App\Models\Region;
use Illuminate\Bus\Queueable;
use Illuminate\Contracts\Queue\ShouldBeUnique;
use Illuminate\Contracts\Queue\ShouldQueue;
use Illuminate\Foundation\Bus\Dispatchable;
use Illuminate\Queue\InteractsWithQueue;
use Illuminate\Queue\SerializesModels;
use Illuminate\Support\Facades\Log;
use Illuminate\Support\Facades\Mail;
class DocumentReminder implements ShouldQueue
@ -34,11 +39,46 @@ class DocumentReminder implements ShouldQueue
*/
public function handle()
{
Log::info('staring', ['send email']);
$email = Setting::where('key', 'DESTINATION_MAIL')->first();
$users = ModelsMail::all()->pluck('value')->toArray();
Mail::to($email->value)
->cc($users)
->send(new DocumentNotification());
if ($email?->value != '') {
Mail::to($email->value)
->cc($users)
->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 '';
}
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;
if ($diff >= $date && $date > 0) {
return $date . " hari mendekati jatuh tempo";
return $date . " Hari mendekati jatuh tempo";
}
if ($date <= 0) {
return "jatuh tempo";
return "Jatuh tempo";
}
},
);

@ -13,6 +13,7 @@ class Region extends Model
protected $fillable = [
"name",
"group_id",
"email"
];
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' => 'import-document', 'label' => 'Import Dokumen'],
['name' => 'export-document', 'label' => 'Export Dokumen'],
['name' => 'download-document', 'label' => 'Download Documen'],
['name' => 'view-category', 'label' => 'Lihat Kategori'],
['name' => 'update-category', 'label' => 'Edit Kategori'],
['name' => 'create-category', 'label' => 'Buat Kategori'],

@ -5,12 +5,14 @@ import DocStatusItem from './DocStatusItem'
import AuthenticatedLayout from '@/Layouts/AuthenticatedLayout'
import InputLabel from '@/Components/InputLabel'
import TextInput from '@/Components/TextInput'
import { formatDate } from '@/utils'
import { formatDate, hasPermission } from '@/utils'
import { useModalState } from '@/Hooks'
export default function FormDocument(props) {
const { doc, doc_url }= props
const canDownload = hasPermission('download-document', props.auth.user)
return (
<AuthenticatedLayout
auth={props.auth}
@ -138,17 +140,19 @@ export default function FormDocument(props) {
readOnly={true}
/>
</div>
<div className='mt-4'>
<InputLabel forInput="due_date" value="Tanggal Jatuh Tempo" />
<TextInput
type="text"
name="due_date"
value={formatDate(doc.due_date)}
className="mt-1 block w-full"
autoComplete={"false"}
readOnly={true}
/>
</div>
{doc.due_date !== null && (
<div className='mt-4'>
<InputLabel forInput="due_date" value="Tanggal Jatuh Tempo" />
<TextInput
type="text"
name="due_date"
value={formatDate(doc.due_date)}
className="mt-1 block w-full"
autoComplete={"false"}
readOnly={true}
/>
</div>
)}
<div className='mt-4'>
<InputLabel forInput="description" value="Keterangan" />
<TextInput
@ -159,10 +163,12 @@ export default function FormDocument(props) {
readOnly={true}
/>
</div>
<div className='mt-4'>
<InputLabel forInput="document" value="Dokumen" />
<a href={doc_url} className='btn btn-outline'>Download</a>
</div>
{canDownload && (
<div className='mt-4'>
<InputLabel forInput="document" value="Dokumen" />
<a href={doc_url} className='btn btn-outline'>Download</a>
</div>
)}
<div className='mt-4'>
<div className="flex w-32 justify-between items-center">
<InputLabel value="Status" />

@ -140,7 +140,7 @@ export default function FormDocument(props) {
/>
<InputError message={errors.no_doc}/>
</div>
<div className='mt-4'>
{/* <div className='mt-4'>
<InputLabel forInput="name" value="Nama Dokumen" />
<TextInput
type="text"
@ -152,7 +152,7 @@ export default function FormDocument(props) {
isError={errors.name}
/>
<InputError message={errors.name}/>
</div>
</div> */}
<div className='mt-4'>
<InputLabel forInput="publisher" value="Penerbit" />
<TextInput

@ -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('category_id')}>Ketegori</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('due_date')}>Tanggal Berakhir</th>
<th>Catatan</th>
@ -152,7 +152,7 @@ export default function Document(props) {
<td>{doc.variety.name}</td>
<td>{doc.category.name}</td>
<td>{doc.no_doc}</td>
<td>{doc.name}</td>
{/* <td>{doc.name}</td> */}
<td>
{doc.publish_date !== null ? formatDate(doc.publish_date) : ''}
</td>

@ -8,7 +8,8 @@ export default function FormModal(props) {
const { data, setData, post, put, processing, errors, reset, clearErrors } = useForm({
name: '',
group_id: ''
group_id: '',
email: '',
})
const handleOnChange = (event) => {
@ -54,7 +55,8 @@ export default function FormModal(props) {
if (region !== null) {
setData({
name: region?.name,
group_id: region?.group_id
group_id: region?.group_id,
email: region?.email,
})
}
}, [modalState])
@ -116,6 +118,24 @@ export default function FormModal(props) {
</span>
</label>
</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
onClick={handleSubmit}

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

@ -3,13 +3,13 @@
Reminder, untuk dokumen perlu diperhatikan :
@component('mail::table')
|No | Nama | Jenis | Status |
|No | Perusahaan | Jenis | Status |
| ----------------------- |:---------------------:|:------------------------------:| ---------------------------:|
| @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
|@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
@endcomponent

@ -53,7 +53,11 @@
<td style="width: 7%;">{{ $collec["tanggal jatuh tempo"] }}</td>
<td >{{ $collec["keterangan"] }}</td>
<td >
@if($collec["file"] != null)
<a href='{{ $collec["file"] }}'>Download</a>
@else
Belum ada file
@endif
</td>
<td >{{ $collec["status"] }}</td>
<td >{{ $collec["catatan"] }}</td>

Loading…
Cancel
Save