diff --git a/app/Http/Controllers/ClientsController.php b/app/Http/Controllers/ClientsController.php index 2de80f0..9ba49b6 100755 --- a/app/Http/Controllers/ClientsController.php +++ b/app/Http/Controllers/ClientsController.php @@ -39,36 +39,61 @@ class ClientsController extends Controller // dd('foo bar'); return view('client.index-inactive', $data); } - public function indexBak(){ - $client_arr = new Models\Client; - $client_arr = $client_arr->with('auth_user_info','country_info', 'created_by_info')->orderBy('name', 'ASC')->paginate(10); - $data = [ - 'page_title' => 'Clients', - 'current_user' => session('current_user') - ]; - return view('client.index-rawjs', $data); - } public function getClientJson(Request $request){ - + // $this->log_query(); $client_arr = \DB::table('clients') ->join('auth_users AS aumngr', 'aumngr.id', '=', 'clients.auth_user_id') ->join('auth_users AS aumodify', 'aumodify.id', '=', 'clients.last_modified_by') ->join('flags AS flags', 'flags.country', '=', 'clients.country') ->select('clients.id', 'clients.name', 'clients.status','clients.progress_indicator_score', 'clients.country', 'aumngr.name As accountMgr', 'aumodify.name AS modifiedBy', 'flags.url AS theflag') + ->whereRaw("status NOT IN ('inactive', 'Cancelled')") ->orderBy('name', 'ASC') ->get(); // ->paginate(15); if($request->has('keyword')){ $keyword = $request->keyword; - $client_arr = \DB::table('clients') - ->join('auth_users AS aumngr', 'aumngr.id', '=', 'clients.auth_user_id') - ->join('auth_users AS aumodify', 'aumodify.id', '=', 'clients.last_modified_by') - ->join('flags AS flags', 'flags.country', '=', 'clients.country') - ->select('clients.id','clients.name', 'clients.status', 'clients.progress_indicator_score','clients.country', 'aumngr.name As accountMgr', 'aumodify.name AS modifiedBy', 'flags.url AS theflag') - ->whereRaw("clients.name like '%$keyword%' or clients.status like '%$keyword%' OR clients.country like '%$keyword%' OR aumngr.name like '%$keyword%' OR aumodify.name like '%$keyword%' OR clients.progress_indicator_score like '%$keyword%'") - ->orderBy('name', 'ASC') - ->get(); + if (strpos('inactive', $keyword) !== false ) { + // dump('foo bars'); + $client_arr = \DB::table('clients') + ->join('auth_users AS aumngr', 'aumngr.id', '=', 'clients.auth_user_id') + ->join('auth_users AS aumodify', 'aumodify.id', '=', 'clients.last_modified_by') + ->join('flags AS flags', 'flags.country', '=', 'clients.country') + ->select('clients.id','clients.name', 'clients.status', 'clients.progress_indicator_score','clients.country', 'aumngr.name As accountMgr', 'aumodify.name AS modifiedBy', 'flags.url AS theflag') + // ->whereRaw("status IN ('Live', 'Prospective')") + ->whereRaw("status NOT IN ('inactive', 'Cancelled')") + ->whereRaw("clients.name LIKE '%$keyword%' OR clients.country LIKE '%$keyword%' OR aumngr.name like '%$keyword%' OR aumodify.name LIKE '%$keyword%'") + ->orderBy('name', 'ASC') + ->get(); + // foreach ($client_arr as $value) { + // // code... + // dd($value); + // } + dump($client_arr->contains('status', 'inactive')); + } + elseif (strpos('Cancelled', $keyword) !== false ) { + $client_arr = \DB::table('clients') + ->join('auth_users AS aumngr', 'aumngr.id', '=', 'clients.auth_user_id') + ->join('auth_users AS aumodify', 'aumodify.id', '=', 'clients.last_modified_by') + ->join('flags AS flags', 'flags.country', '=', 'clients.country') + ->select('clients.id','clients.name', 'clients.status', 'clients.progress_indicator_score','clients.country', 'aumngr.name As accountMgr', 'aumodify.name AS modifiedBy', 'flags.url AS theflag') + // ->whereRaw("status IN ('Live', 'Prospective')") + ->whereRaw("status NOT IN ('inactive', 'Cancelled')") + ->whereRaw("clients.name LIKE '%$keyword%' OR clients.country LIKE '%$keyword%' OR aumngr.name LIKE '%$keyword%' OR aumodify.name LIKE '%$keyword%'") + ->orderBy('name', 'ASC') + ->get(); + }else{ + $client_arr = \DB::table('clients') + ->join('auth_users AS aumngr', 'aumngr.id', '=', 'clients.auth_user_id') + ->join('auth_users AS aumodify', 'aumodify.id', '=', 'clients.last_modified_by') + ->join('flags AS flags', 'flags.country', '=', 'clients.country') + ->select('clients.id','clients.name', 'clients.status', 'clients.progress_indicator_score','clients.country', 'aumngr.name As accountMgr', 'aumodify.name AS modifiedBy', 'flags.url AS theflag') + ->whereRaw("status IN ('Live', 'Prospective')") + ->whereRaw("clients.name LIKE '%$keyword%' OR clients.status LIKE '%$keyword%' OR clients.country LIKE '%$keyword%' OR aumngr.name LIKE '%$keyword%' OR aumodify.name LIKE '%$keyword%'") + ->orderBy('name', 'ASC') + ->get(); + } + // ->paginate(15); } @@ -82,7 +107,7 @@ class ClientsController extends Controller ->join('auth_users AS aumngr', 'aumngr.id', '=', 'clients.auth_user_id') ->join('auth_users AS aumodify', 'aumodify.id', '=', 'clients.last_modified_by') ->select('clients.id', 'clients.name', 'clients.status', 'clients.country', 'aumngr.name As accountMgr', 'aumodify.name AS modifiedBy') - + ->whereRaw("status <> 'Inactive'") ->paginate(10); if($request->has('keyword')){ @@ -91,7 +116,8 @@ class ClientsController extends Controller ->join('auth_users AS aumngr', 'aumngr.id', '=', 'clients.auth_user_id') ->join('auth_users AS aumodify', 'aumodify.id', '=', 'clients.last_modified_by') ->select('clients.id','clients.name', 'clients.status', 'clients.country', 'aumngr.name As accountMgr', 'aumodify.name AS modifiedBy') - ->whereRaw("clients.name like '%$keyword%' or clients.status like '%$keyword%' OR clients.country like '%$keyword%' OR aumngr.name like '%$keyword%' OR aumodify.name like '%$keyword%'") + ->whereRaw("status <> 'Inactive'") + ->whereRaw("clients.name like '%$keyword%' OR clients.status like '%$keyword%' OR clients.country like '%$keyword%' OR aumngr.name like '%$keyword%' OR aumodify.name like '%$keyword%'") ->paginate(10); } return response()->json($client_arr); @@ -104,7 +130,7 @@ class ClientsController extends Controller ->join('auth_users AS aumodify', 'aumodify.id', '=', 'clients.last_modified_by') ->join('flags AS flags', 'flags.country', '=', 'clients.country') ->select('clients.id', 'clients.name', 'clients.status','clients.progress_indicator_score', 'clients.country', 'aumngr.name As accountMgr', 'aumodify.name AS modifiedBy', 'flags.url AS theflag') - ->whereRaw("status = 'inactive'") + ->whereRaw("status IN ('inactive', 'Cancelled')") ->orderBy('name', 'ASC') ->get(); // ->paginate(15); @@ -116,8 +142,8 @@ class ClientsController extends Controller ->join('auth_users AS aumodify', 'aumodify.id', '=', 'clients.last_modified_by') ->join('flags AS flags', 'flags.country', '=', 'clients.country') ->select('clients.id','clients.name', 'clients.status', 'clients.progress_indicator_score','clients.country', 'aumngr.name As accountMgr', 'aumodify.name AS modifiedBy', 'flags.url AS theflag') - ->whereRaw("status = 'inactive'") - ->whereRaw("clients.name like '%$keyword%' or clients.status like '%$keyword%' OR clients.country like '%$keyword%' OR aumngr.name like '%$keyword%' OR aumodify.name like '%$keyword%' OR clients.progress_indicator_score like '%$keyword%'") + ->whereRaw("status IN ('inactive', 'Cancelled')") + ->whereRaw("clients.name LIKE '%$keyword%' OR clients.status LIKE '%$keyword%' OR clients.country LIKE '%$keyword%' OR aumngr.name LIKE '%$keyword%' OR aumodify.name LIKE '%$keyword%' OR clients.progress_indicator_score LIKE '%$keyword%'") ->orderBy('name', 'ASC') ->get(); // ->paginate(15); @@ -130,7 +156,7 @@ class ClientsController extends Controller ->join('auth_users AS aumngr', 'aumngr.id', '=', 'clients.auth_user_id') ->join('auth_users AS aumodify', 'aumodify.id', '=', 'clients.last_modified_by') ->select('clients.id', 'clients.name', 'clients.status', 'clients.country', 'aumngr.name As accountMgr', 'aumodify.name AS modifiedBy') - ->whereRaw("status = 'inactive'") + ->whereRaw("status = 'Inactive'") ->paginate(10); if($request->has('keyword')){ @@ -140,7 +166,7 @@ class ClientsController extends Controller ->join('auth_users AS aumodify', 'aumodify.id', '=', 'clients.last_modified_by') ->select('clients.id','clients.name', 'clients.status', 'clients.country', 'aumngr.name As accountMgr', 'aumodify.name AS modifiedBy') // ->where('status', 'inactive') - ->whereRaw("status = 'inactive'") + ->whereRaw("status = 'Inactive'") ->whereRaw("clients.name like '%$keyword%' or clients.status like '%$keyword%' OR clients.country like '%$keyword%' OR aumngr.name like '%$keyword%' OR aumodify.name like '%$keyword%'") ->paginate(10); } @@ -159,7 +185,7 @@ class ClientsController extends Controller $service_type = Models\Service::pluck('name', 'name'); $payment_type = ['Prepaid' => 'Prepaid', 'Postpaid' => 'Postpaid']; //Models\PaymentType::pluck('name', 'id'); $auth_users = Models\SystemUser::pluck('name', 'id'); - $status = ['Live' => 'Live', 'inactive' => 'Inactive', 'Prospective' => 'Prospective', 'Cancelled' => 'Cancelled']; + $status = ['Live' => 'Live', 'Inactive' => 'Inactive', 'Prospective' => 'Prospective', 'Cancelled' => 'Cancelled']; $currency = Models\Currency::pluck('name','name'); $company_types = ['Aggregator/Supplier' => 'Aggregator/Supplier', 'Enterprise' => 'Enterprise', 'Hybrid' => 'Hybrid']; $industries = Models\Industry::orderBy('name', 'ASC')->pluck('name', 'name'); diff --git a/app/Http/Controllers/DashboardController.php b/app/Http/Controllers/DashboardController.php index cd3c42b..e8e9e4c 100755 --- a/app/Http/Controllers/DashboardController.php +++ b/app/Http/Controllers/DashboardController.php @@ -24,7 +24,7 @@ class DashboardController extends Controller $recent_clients = Models\Client::with('auth_user_info')->orderBy('id', 'DESC')->take(5)->get(); // $upcoming_birthdays = Models\StaffMember::whereDate('dob', '>=', $currentdate)->orderBy('dob', 'ASC')->take(5)->get(); $upcoming_birthdays = Models\StaffMember::whereRaw("(month(dob) >= month(curdate())) AND day(dob) >= day(curdate())")->orderBy('dob', 'ASC')->take(5)->get(); - $upcoming_hodidays = Models\NationalHoliday::whereRaw("(month(event_date) >= month(curdate()))")->orderBy('event_date', 'ASC')->take(5)->get(); + $upcoming_hodidays = Models\NationalHoliday::whereRaw("(month(event_date) >= month(curdate()))")->whereRaw("(year(event_date) >= year(curdate()))")->orderBy('event_date', 'ASC')->take(15)->get(); // dd($upcoming_hodidays); // $recent_clients = Models\Client::orderBy('id', 'DESC')->take(5)->get(); diff --git a/app/Http/Controllers/EmailController.php b/app/Http/Controllers/EmailController.php new file mode 100644 index 0000000..182b869 --- /dev/null +++ b/app/Http/Controllers/EmailController.php @@ -0,0 +1,58 @@ +getLatestEmails(10); + return response()->json($emails); + // Or for view: return view('emails.index', compact('emails')); + } catch (\Exception $e) { + return response()->json(['error' => $e->getMessage()], 500); + } + } + public function index() + { + try { + // Initialize IMAP client + $client = app(ClientManager::class)->account('default'); + $client->connect(); + + // Get INBOX folder + $folder = $client->getFolder('INBOX'); + + // Fetch last 10 emails (newest first) + $messages = $folder->messages()->unseen()->limit(10)->get(); + + // Prepare data for view + $emails = $messages->map(function ($message) { + return [ + 'subject' => $message->getSubject() ?? '(No Subject)', + 'sender' => $message->getFrom()[0]->mail ?? 'Unknown', + 'email_date' => $message->getDate()->toDateTimeString(), + 'email_body' => substr(strip_tags($message->getTextBody()), 0, 200) . '...', + ]; + }); + + // Disconnect + $client->disconnect(); + dd($emails); + // Return view or JSON + // return view('emails.index', compact('emails')); + // Or for API: return response()->json($emails); + + } catch (ConnectionFailedException $e) { + return response()->json(['error' => 'Failed to connect: ' . $e->getMessage()], 500); + } catch (\Exception $e) { + return response()->json(['error' => 'Error: ' . $e->getMessage()], 500); + } + } +} \ No newline at end of file diff --git a/app/Http/Controllers/StaffMembersController.php b/app/Http/Controllers/StaffMembersController.php index 8071849..bae2769 100644 --- a/app/Http/Controllers/StaffMembersController.php +++ b/app/Http/Controllers/StaffMembersController.php @@ -21,8 +21,6 @@ class StaffMembersController extends Controller } public function profile($staff_member_id){ $staff_member = Models\StaffMember::find($staff_member_id); - // dd($staff_member); - $data = [ 'page_title' => 'Staff Profile', 'staff_member' => $staff_member, @@ -30,6 +28,12 @@ class StaffMembersController extends Controller ]; return view('staff_members.profile', $data); } + public function profile_json(){ + $staff_member_id = session('current_user.id'); + $staff_member = Models\StaffMember::findOrFail($staff_member_id); + + return response()->json(['code' => 1, 'staff_member' => $staff_member]); + } public function indexOld(){ $staff_members_arr = new Models\StaffMember; $data = [ @@ -38,6 +42,26 @@ class StaffMembersController extends Controller ]; return view('staff_members.index', $data); } + public function profileupdate(Request $request) + { + $account_arr = Models\StaffMember::find($request->user_id); + $account_arr->name = $request->name; + $account_arr->email = $request->email; + $account_arr->phone = $request->phone; + $msg_text = 'Staff detials successfully Updated'; + if ($request->password == true) { + $account_arr->password = md5($request->password); + $msg_text = "Staff details and password successfully updated"; + } + $result = $account_arr->save(); + if ($result == true) { + $data = ['code' => 1, 'msg' => $msg_text]; + } + else{ + $data = ['code' => 1, 'msg' => 'Staff details could not be updated at this time. Try again!']; + } + return response()->json($data); + } public function getstaffMemberssJson(Request $request) { #$this->log_query(); diff --git a/app/Http/Controllers/SystemUsersController.php b/app/Http/Controllers/SystemUsersController.php index a8d5e9e..7a5ea7e 100755 --- a/app/Http/Controllers/SystemUsersController.php +++ b/app/Http/Controllers/SystemUsersController.php @@ -53,6 +53,12 @@ class SystemUsersController extends Controller return view('systemusers.index', $data); } + public function profile_json(){ + $staff_member_id = session('current_user.id'); + $staff_member = Models\SystemUser::findOrFail($staff_member_id); + + return response()->json(['code' => 1, 'staff_member' => $staff_member]); + } /** * Show the form for creating a new resource. @@ -156,6 +162,25 @@ class SystemUsersController extends Controller Session::flash('success_message', 'Account successfully Updated'); return redirect(url('systemusers')); } + public function profileupdate(Request $request){ + $account_arr = Models\SystemUser::find($request->user_id); + $account_arr->name = $request->name; + $account_arr->email = $request->email; + $account_arr->phone = $request->phone; + $msg_text = 'Account successfully Updated'; + if ($request->password == true) { + $account_arr->password = md5($request->password); + $msg_text = "Account details and password successfully updated"; + } + $result = $account_arr->save(); + if ($result == true) { + $data = ['code' => 1, 'msg' => $msg_text]; + } + else{ + $data = ['code' => 1, 'msg' => 'Account could not be updated at this time. Try again!']; + } + return response()->json($data); + } /** * Remove the specified resource from storage. diff --git a/app/Libs/ImapService.php b/app/Libs/ImapService.php new file mode 100644 index 0000000..4cea6df --- /dev/null +++ b/app/Libs/ImapService.php @@ -0,0 +1,57 @@ +connection = @imap_open($hostname, $username, $password); + if (!$this->connection) { + throw new \Exception('Cannot connect: ' . imap_last_error()); + } + } + public function getLatestEmails($limit = 10): array + { + $emails = imap_search($this->connection, 'ALL', SE_UID); + + if (!$emails) { + return []; + } + + rsort($emails); // Newest first + $result = []; + + foreach (array_slice($emails, 0, $limit) as $uid) { + $header = imap_headerinfo($this->connection, imap_msgno($this->connection, $uid), FT_UID); + $body = imap_fetchbody($this->connection, imap_msgno($this->connection, $uid), 1, FT_UID); + $body = quoted_printable_decode($body); + + $result[] = [ + 'subject' => isset($header->subject) ? imap_utf8($header->subject) : '(No Subject)', + 'from' => $header->from[0]->mailbox . '@' . $header->from[0]->host, + 'date' => $header->date ?? 'Unknown', + 'body' => substr(strip_tags($body), 0, 200) . '...', + ]; + } + + return $result; + } + + public function __destruct() + { + if ($this->connection) { + imap_close($this->connection); + } + } +} \ No newline at end of file diff --git a/app/Models/DailyQoute.php b/app/Models/DailyQoute.php deleted file mode 100644 index ff1eb8b..0000000 --- a/app/Models/DailyQoute.php +++ /dev/null @@ -1,12 +0,0 @@ -=5.0.0", + "php": ">=5.5.9", + "webklex/php-imap": "^4.1.2" + }, + "type": "library", + "extra": { + "laravel": { + "aliases": { + "Client": "Webklex\\IMAP\\Facades\\Client" + }, + "providers": [ + "Webklex\\IMAP\\Providers\\LaravelServiceProvider" + ] + }, + "branch-alias": { + "dev-master": "1.0-dev" + } + }, + "autoload": { + "psr-4": { + "Webklex\\IMAP\\": "src" + } + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "MIT" + ], + "authors": [ + { + "name": "Malte Goldenbaum", + "email": "github@webklex.com", + "role": "Developer" + } + ], + "description": "Laravel IMAP client", + "homepage": "https://github.com/webklex/laravel-imap", + "keywords": [ + "idle", + "imap", + "laravel", + "laravel-imap", + "mail", + "oauth", + "pop3", + "webklex" + ], + "support": { + "issues": "https://github.com/Webklex/laravel-imap/issues", + "source": "https://github.com/Webklex/laravel-imap/tree/4.1.2" + }, + "funding": [ + { + "url": "https://www.buymeacoffee.com/webklex", + "type": "custom" + }, + { + "url": "https://ko-fi.com/webklex", + "type": "ko_fi" + } + ], + "time": "2023-01-18T18:33:20+00:00" + }, + { + "name": "webklex/php-imap", + "version": "4.1.2", + "source": { + "type": "git", + "url": "https://github.com/Webklex/php-imap.git", + "reference": "94bf93ae8868ac1e073cfbaef377f0ca1acac2bc" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/Webklex/php-imap/zipball/94bf93ae8868ac1e073cfbaef377f0ca1acac2bc", + "reference": "94bf93ae8868ac1e073cfbaef377f0ca1acac2bc", + "shasum": "" + }, + "require": { + "ext-fileinfo": "*", + "ext-iconv": "*", + "ext-json": "*", + "ext-mbstring": "*", + "ext-openssl": "*", + "illuminate/pagination": ">=5.0.0", + "nesbot/carbon": ">=1.0", + "php": ">=7.0.0", + "symfony/http-foundation": ">=2.8.0" + }, + "require-dev": { + "phpunit/phpunit": "~4.0" + }, + "suggest": { + "symfony/mime": "Recomended for better extension support" + }, + "type": "library", + "extra": { + "branch-alias": { + "dev-master": "1.0-dev" + } + }, + "autoload": { + "psr-4": { + "Webklex\\PHPIMAP\\": "src" + } + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "MIT" + ], + "authors": [ + { + "name": "Malte Goldenbaum", + "email": "github@webklex.com", + "role": "Developer" + } + ], + "description": "PHP IMAP client", + "homepage": "https://github.com/webklex/php-imap", + "keywords": [ + "imap", + "mail", + "php-imap", + "pop3", + "webklex" + ], + "support": { + "issues": "https://github.com/Webklex/php-imap/issues", + "source": "https://github.com/Webklex/php-imap/tree/4.1.2" + }, + "funding": [ + { + "url": "https://www.buymeacoffee.com/webklex", + "type": "custom" + }, + { + "url": "https://ko-fi.com/webklex", + "type": "ko_fi" + } + ], + "time": "2022-12-14T15:45:15+00:00" } ], "packages-dev": [ diff --git a/config/imap.php b/config/imap.php new file mode 100644 index 0000000..537c46b --- /dev/null +++ b/config/imap.php @@ -0,0 +1,246 @@ + env('IMAP_DEFAULT_ACCOUNT', 'default'), + + /* + |-------------------------------------------------------------------------- + | Default date format + |-------------------------------------------------------------------------- + | + | The default date format is used to convert any given Carbon::class object into a valid date string. + | These are currently known working formats: "d-M-Y", "d-M-y", "d M y" + | + */ + 'date_format' => 'd-M-Y', + + /* + |-------------------------------------------------------------------------- + | Available IMAP accounts + |-------------------------------------------------------------------------- + | + | Please list all IMAP accounts which you are planning to use within the + | array below. + | + */ + 'accounts' => [ + + 'default' => [// account identifier + 'host' => env('IMAP_HOST', 'localhost'), + 'port' => env('IMAP_PORT', 993), + 'protocol' => env('IMAP_PROTOCOL', 'imap'), //might also use imap, [pop3 or nntp (untested)] + 'encryption' => env('IMAP_ENCRYPTION', 'ssl'), // Supported: false, 'ssl', 'tls', 'notls', 'starttls' + 'validate_cert' => env('IMAP_VALIDATE_CERT', true), + 'username' => env('IMAP_USERNAME', 'root@example.com'), + 'password' => env('IMAP_PASSWORD', ''), + 'authentication' => env('IMAP_AUTHENTICATION', null), + 'proxy' => [ + 'socket' => null, + 'request_fulluri' => false, + 'username' => null, + 'password' => null, + ], + "timeout" => 30, + "extensions" => [] + ], + + /* + 'gmail' => [ // account identifier + 'host' => 'imap.gmail.com', + 'port' => 993, + 'encryption' => 'ssl', + 'validate_cert' => true, + 'username' => 'example@gmail.com', + 'password' => 'PASSWORD', + 'authentication' => 'oauth', + ], + + 'another' => [ // account identifier + 'host' => '', + 'port' => 993, + 'encryption' => false, + 'validate_cert' => true, + 'username' => '', + 'password' => '', + 'authentication' => null, + ] + */ + ], + + /* + |-------------------------------------------------------------------------- + | Available IMAP options + |-------------------------------------------------------------------------- + | + | Available php imap config parameters are listed below + | -Delimiter (optional): + | This option is only used when calling $oClient-> + | You can use any supported char such as ".", "/", (...) + | -Fetch option: + | IMAP::FT_UID - Message marked as read by fetching the body message + | IMAP::FT_PEEK - Fetch the message without setting the "seen" flag + | -Fetch sequence id: + | IMAP::ST_UID - Fetch message components using the message uid + | IMAP::ST_MSGN - Fetch message components using the message number + | -Body download option + | Default TRUE + | -Flag download option + | Default TRUE + | -Soft fail + | Default FALSE - Set to TRUE if you want to ignore certain exception while fetching bulk messages + | -RFC822 + | Default TRUE - Set to FALSE to prevent the usage of \imap_rfc822_parse_headers(). + | See https://github.com/Webklex/php-imap/issues/115 for more information. + | -Debug enable to trace communication traffic + | -UID cache enable the UID cache + | -Fallback date is used if the given message date could not be parsed + | -Boundary regex used to detect message boundaries. If you are having problems with empty messages, missing + | attachments or anything like this. Be advised that it likes to break which causes new problems.. + | -Message key identifier option + | You can choose between the following: + | 'id' - Use the MessageID as array key (default, might cause hickups with yahoo mail) + | 'number' - Use the message number as array key (isn't always unique and can cause some interesting behavior) + | 'list' - Use the message list number as array key (incrementing integer (does not always start at 0 or 1) + | 'uid' - Use the message uid as array key (isn't always unique and can cause some interesting behavior) + | -Fetch order + | 'asc' - Order all messages ascending (probably results in oldest first) + | 'desc' - Order all messages descending (probably results in newest first) + | -Disposition types potentially considered an attachment + | Default ['attachment', 'inline'] + | -Common folders + | Default folder locations and paths assumed if none is provided + | -Open IMAP options: + | DISABLE_AUTHENTICATOR - Disable authentication properties. + | Use 'GSSAPI' if you encounter the following + | error: "Kerberos error: No credentials cache + | file found (try running kinit) (...)" + | or ['GSSAPI','PLAIN'] if you are using outlook mail + | + */ + 'options' => [ + 'delimiter' => '/', + 'fetch' => \Webklex\PHPIMAP\IMAP::FT_PEEK, + 'sequence' => \Webklex\PHPIMAP\IMAP::ST_UID, + 'fetch_body' => true, + 'fetch_flags' => true, + 'soft_fail' => false, + 'rfc822' => true, + 'debug' => false, + 'uid_cache' => true, + // 'fallback_date' => "01.01.1970 00:00:00", + 'boundary' => '/boundary=(.*?(?=;)|(.*))/i', + 'message_key' => 'list', + 'fetch_order' => 'asc', + 'dispositions' => ['attachment', 'inline'], + 'common_folders' => [ + "root" => "INBOX", + "junk" => "INBOX/Junk", + "draft" => "INBOX/Drafts", + "sent" => "INBOX/Sent", + "trash" => "INBOX/Trash", + ], + 'open' => [ + // 'DISABLE_AUTHENTICATOR' => 'GSSAPI' + ] + ], + + /** + * |-------------------------------------------------------------------------- + * | Available decoding options + * |-------------------------------------------------------------------------- + * | + * | Available php imap config parameters are listed below + * | -options: Decoder options (currently only the message subject and attachment name decoder can be set) + * | 'utf-8' - Uses imap_utf8($string) to decode a string + * | 'mimeheader' - Uses mb_decode_mimeheader($string) to decode a string + * | -decoder: Decoder to be used. Can be replaced by custom decoders if needed. + * | 'header' - HeaderDecoder + * | 'message' - MessageDecoder + * | 'attachment' - AttachmentDecoder + */ + 'decoding' => [ + 'options' => [ + 'header' => 'utf-8', // mimeheader + 'message' => 'utf-8', // mimeheader + 'attachment' => 'utf-8' // mimeheader + ], + 'decoder' => [ + 'header' => \Webklex\PHPIMAP\Decoder\HeaderDecoder::class, + 'message' => \Webklex\PHPIMAP\Decoder\MessageDecoder::class, + 'attachment' => \Webklex\PHPIMAP\Decoder\AttachmentDecoder::class + ] + ], + + /* + |-------------------------------------------------------------------------- + | Available flags + |-------------------------------------------------------------------------- + | + | List all available / supported flags. Set to null to accept all given flags. + */ + 'flags' => ['recent', 'flagged', 'answered', 'deleted', 'seen', 'draft'], + + /* + |-------------------------------------------------------------------------- + | Available events + |-------------------------------------------------------------------------- + | + */ + 'events' => [ + "message" => [ + 'new' => \Webklex\IMAP\Events\MessageNewEvent::class, + 'moved' => \Webklex\IMAP\Events\MessageMovedEvent::class, + 'copied' => \Webklex\IMAP\Events\MessageCopiedEvent::class, + 'deleted' => \Webklex\IMAP\Events\MessageDeletedEvent::class, + 'restored' => \Webklex\IMAP\Events\MessageRestoredEvent::class, + ], + "folder" => [ + 'new' => \Webklex\IMAP\Events\FolderNewEvent::class, + 'moved' => \Webklex\IMAP\Events\FolderMovedEvent::class, + 'deleted' => \Webklex\IMAP\Events\FolderDeletedEvent::class, + ], + "flag" => [ + 'new' => \Webklex\IMAP\Events\FlagNewEvent::class, + 'deleted' => \Webklex\IMAP\Events\FlagDeletedEvent::class, + ], + ], + + /* + |-------------------------------------------------------------------------- + | Available masking options + |-------------------------------------------------------------------------- + | + | By using your own custom masks you can implement your own methods for + | a better and faster access and less code to write. + | + | Checkout the two examples custom_attachment_mask and custom_message_mask + | for a quick start. + | + | The provided masks below are used as the default masks. + */ + 'masks' => [ + 'message' => \Webklex\PHPIMAP\Support\Masks\MessageMask::class, + 'attachment' => \Webklex\PHPIMAP\Support\Masks\AttachmentMask::class + ] +]; \ No newline at end of file diff --git a/issues-20-02-2026.md b/issues-20-02-2026.md new file mode 100644 index 0000000..42cffd3 --- /dev/null +++ b/issues-20-02-2026.md @@ -0,0 +1,10 @@ +1. The logo looks stretched. Can we get that fixed? resized and repositioned it nut we need a new one +2. ⁠we need to get ERP SSL sorted. -- this needs a domain name +3. ⁠Sam’s message of the day: Sam suggested we have an email that the quotes can be sent to and automatically update on the ERP. +And maybe add other quotes from different people. Not just Sam’s quote. +Have Effie, maybe Mansa, maybe you. And it should be changed to weekly not daily +implemented a solution with the emails +4. ⁠for contract validity (expiry date), add a feature for Auto Renewal which wont be asking for the validity. +This is of contracts that dont expire. done. need to upload +5. ⁠for the Holidays, he asked that I send emails to Country Managers every month asking for the following month holidays of their respective countries +6. How far with the profile page? -- done \ No newline at end of file diff --git a/public/assets/img/cml-final-3 copy.png b/public/assets/img/cml-final-3 copy.png new file mode 100644 index 0000000..97f9d12 Binary files /dev/null and b/public/assets/img/cml-final-3 copy.png differ diff --git a/public/assets/img/cml-final-3_no-bg.png b/public/assets/img/cml-final-3_no-bg.png new file mode 100644 index 0000000..4840cc7 Binary files /dev/null and b/public/assets/img/cml-final-3_no-bg.png differ diff --git a/public/assets/img/cml-logo.png b/public/assets/img/cml-logo.png new file mode 100644 index 0000000..65f58ae Binary files /dev/null and b/public/assets/img/cml-logo.png differ diff --git a/public/documents/general_files/erp_1771406806bROnEj.xlsx b/public/documents/general_files/erp_1771406806bROnEj.xlsx new file mode 100644 index 0000000..fae4a5c Binary files /dev/null and b/public/documents/general_files/erp_1771406806bROnEj.xlsx differ diff --git a/public/documents/general_files/erp_1771406806bROnEj.xlsx_rejected_rows.txt b/public/documents/general_files/erp_1771406806bROnEj.xlsx_rejected_rows.txt new file mode 100644 index 0000000..3d80ad3 --- /dev/null +++ b/public/documents/general_files/erp_1771406806bROnEj.xlsx_rejected_rows.txt @@ -0,0 +1,16 @@ +{"senderid":"IKKODE","direct_mno":"NO","mno_name":"MOOV(Benin)","supplier_name":null,"status":"Approved on MNO","remarks":null} +{"senderid":"KREEZUS","direct_mno":"NO","mno_name":"MOOV(Benin)","supplier_name":null,"status":"Approved on MNO","remarks":null} +{"senderid":"AIR CI","direct_mno":"NO","mno_name":"MOOV(Benin)","supplier_name":null,"status":"Approved on MNO","remarks":null} +{"senderid":"BENIN CTRL","direct_mno":"NO","mno_name":"MOOV(Benin)","supplier_name":null,"status":"Approved on MNO","remarks":null} +{"senderid":"AMNESTY","direct_mno":"NO","mno_name":"MOOV(Benin)","supplier_name":null,"status":"Approved on MNO","remarks":null} +{"senderid":"Sun King","direct_mno":"NO","mno_name":"MOOV(Benin)","supplier_name":null,"status":"Approved on MNO","remarks":"_"} +{"senderid":"ECOBANK","direct_mno":"NO","mno_name":"MOOV(Benin)","supplier_name":null,"status":"Approved on MNO","remarks":null} +{"senderid":"SGB","direct_mno":"NO","mno_name":"MOOV(Benin)","supplier_name":null,"status":"Approved on MNO","remarks":null} +{"senderid":"SimAU","direct_mno":"NO","mno_name":"MOOV(Benin)","supplier_name":null,"status":"Approved on MNO","remarks":null} +{"senderid":"CORIS MESO","direct_mno":"NO","mno_name":"MOOV(Benin)","supplier_name":null,"status":"Approved on MNO","remarks":null} +{"senderid":"ADKONTACT","direct_mno":"NO","mno_name":"MOOV(Benin)","supplier_name":null,"status":"Approved on MNO","remarks":null} +{"senderid":"Missebo app","direct_mno":"NO","mno_name":"MOOV(Benin)","supplier_name":null,"status":"Approved on MNO","remarks":null} +{"senderid":"Boo co","direct_mno":"NO","mno_name":"MOOV(Benin)","supplier_name":null,"status":"Approved on MNO","remarks":null} +{"senderid":"TransAfrika","direct_mno":"NO","mno_name":"MOOV(Benin)","supplier_name":null,"status":"Approved on MNO","remarks":null} +{"senderid":"MOON","direct_mno":"NO","mno_name":"MOOV(Benin)","supplier_name":null,"status":"Approved on MNO","remarks":null} +{"senderid":"SONAM HONDA","direct_mno":"NO","mno_name":"MOOV(Benin)","supplier_name":null,"status":"Approved on MNO","remarks":null} diff --git a/resources/views/daily_quotes/create.blade.php b/resources/views/daily_quotes/create.blade.php new file mode 100644 index 0000000..4c429cc --- /dev/null +++ b/resources/views/daily_quotes/create.blade.php @@ -0,0 +1,108 @@ +@extends('layouts.master') +@section('page_title') + @if(isset($page_title)) + {{ $page_title }} + @endif +@endsection +@section('content') +
+
+
+ +
+
+
+
+
+
+
+ New Daily Quote + @include('commons.notifications') +
+
+ {{-- start of content --}} +
+
+ {!! Form::open(['url' => 'dailyquotes', 'id' => 'dailyQuoteCreateForm', 'class' => 'form-horizontal form-label-left']) !!} +
+ +
+ +
+ {!! Form::text('quote', old('quote'), ['class' => 'form-control col-md-7 col-xs-12', 'placeholder'=>'Enter quote , 'id' => 'quoteIDD', 'required' => 'true']) !!} + {!! $errors->first('quote', '

:message

') !!} +
+
+
+ +
+ {!! Form::select('direct_mno', $direct_mno_arr ,old('direct_mno'), ['class' => 'form-control col-md-7 col-xs-12', 'placeholder'=>'Select one ' , 'id' => 'directMno', 'required' => 'true']) !!} + {!! $errors->first('direct_mno', '

:message

') !!} +
+
+ +
+ +
+ {!! Form::select('mno_name', $network_arr, old('mno_name'), ['class' => 'form-control col-md-7 col-xs-12', 'id' => 'networkName', 'placeholder' => '-- Select --', 'required' => 'true', 'style' => 'width:100%;']) !!} + {!! $errors->first('network', '

:message

') !!} +
+
+
+ +
+ + {!! Form::select('supplier_name', $clients, old('supplier_name'), ['class' => 'form-control', 'id' => 'supplierName', 'placeholder' => '-- Select --', 'style' => 'width:100%;']) !!} + {!! $errors->first('client_id', '

:message

') !!} +
+
+
+ +
+ {!! Form::select('status', $status ,old('status'), ['class' => 'form-control col-md-7 col-xs-12', 'placeholder'=>'Select Status ' , 'id' => 'status', 'required' => 'true']) !!} + {!! $errors->first('status', '

:message

') !!} +
+
+
+ +
+ {!! Form::text('remarks', old('remarks'), ['class' => 'form-control col-md-7 col-xs-12', 'placeholder'=>'Enter remarks here' , 'id' => 'remarks']) !!} + {!! $errors->first('remarks', '

:message

') !!} +
+
+ +
+
+
+ +   + + +
+
+ {!! Form::close() !!} +
+ {{-- end of x_content --}} +
+ {{-- end of x_panel --}} +
+
+ +
+ +@endsection + +@section('javascript') + + +@endsection diff --git a/resources/views/daily_quotes/edit.blade.php b/resources/views/daily_quotes/edit.blade.php new file mode 100644 index 0000000..641ee78 --- /dev/null +++ b/resources/views/daily_quotes/edit.blade.php @@ -0,0 +1,105 @@ +@extends('layouts.master') +@section('page_title') + @if(isset($page_title)) + {{ $page_title }} + @endif +@endsection +@section('content') +
+
+
+ +
+
+
+
+
+
+
+ Update Sender ID + @include('commons.notifications') +
+
+ {{-- start of content --}} +
+
+ {!! Form::model($senderid, [ + 'method' => 'PATCH', + 'url' => ['senderids', $senderid], + 'class' => 'form-horizontal form-label-left' + ]) !!} +
+
+ +
+ {!! Form::text('senderid', old('senderid'), ['class' => 'form-control col-md-7 col-xs-12', 'placeholder'=>'Enter sender ID' , 'id' => 'senderIddEdit', 'required' => 'true']) !!} + {!! $errors->first('name', '

:message

') !!} +
+
+
+ +
+ {!! Form::select('direct_mno', $direct_mno_arr ,old('direct_mno'), ['class' => 'form-control col-md-7 col-xs-12', 'placeholder'=>'Select one ' , 'id' => 'directMnoEdit', 'required' => 'true']) !!} + {!! $errors->first('direct_mno', '

:message

') !!} +
+
+
" id="mnoDivEdit"> + +
+ {!! Form::select('mno_name', $network_arr, old('mno_name'), ['class' => 'form-control col-md-7 col-xs-12', 'id' => 'networkNameEdit', 'placeholder' => '-- Select --', 'style' => 'width:100%;']) !!} + {!! $errors->first('network', '

:message

') !!} +
+
+
" id="supplierDivEdit"> + +
+ {!! Form::select('supplier_name', $clients, old('supplier_name'), ['class' => 'form-control', 'id' => 'supplierNameEdit', 'placeholder' => '-- Select --', 'style' => 'width:100%;']) !!} + {!! $errors->first('client_id', '

:message

') !!} +
+
+
+ +
+ {!! Form::select('status', $status ,old('status'), ['class' => 'form-control col-md-7 col-xs-12', 'placeholder'=>'Select Status ' , 'id' => 'statusEdit', 'required' => 'true']) !!} + {!! $errors->first('status', '

:message

') !!} +
+
+
+ +
+ {!! Form::text('remarks', old('remarks'), ['class' => 'form-control col-md-7 col-xs-12', 'placeholder'=>'Enter remarks here' , 'id' => 'remarksEdit']) !!} + {!! $errors->first('remarks', '

:message

') !!} +
+
+ +
+
+
+ +
+
+ {!! Form::close() !!} +
+ {{-- end of x_content --}} +
+ {{-- end of x_panel --}} +
+
+ +
+ +@endsection + +@section('javascript') + + +@endsection diff --git a/resources/views/daily_quotes/index.blade.php b/resources/views/daily_quotes/index.blade.php new file mode 100644 index 0000000..700fa56 --- /dev/null +++ b/resources/views/daily_quotes/index.blade.php @@ -0,0 +1,199 @@ +@extends('layouts.master') + @section('page_title') + @if(isset($page_title)) + {{ $page_title }} + @endif + @endsection +@section('css') + +@endsection +@section('content') +
+
+
+
+ +
+
+ +
+
+
+
+ +
+ +
+
+
+
+
+
+
+
+
+ +
+
+ @include('commons.notifications') +
+
+ + +
+ + @if(session('current_user.rejected_rows_filename') !== null) + + @endif + +
+ +
+
+
+
+
+
+
+ +@endsection + +@section('javascript') + + + + + + +@endsection diff --git a/resources/views/layouts/dashboardmaster.blade.php b/resources/views/layouts/dashboardmaster.blade.php index 0bb2fc4..fcfeb23 100755 --- a/resources/views/layouts/dashboardmaster.blade.php +++ b/resources/views/layouts/dashboardmaster.blade.php @@ -35,6 +35,7 @@ + @include('systemusers.partials.profile')