Am failing to retrieve DAILY SALES in my codeigniter 4 pos system after mid night when query between two dates.
The POS system is working in the BAR/Club where their start time is 14:00 and end time is 03:00 (next day).
My current code only shows daily sales upto midnight. After mid night my opening hours change to new day returning nothing because no sales by then.
Here is what I tried
MODEL
//Get Daily Sales For Tenant ID - By Specific Opening/Closing time
public function getdailySalesByTenant($t, $ot, $ct)
{
$builder = $this->db->table('orders as o');
$builder->select('o.*, u.first_name as waiter');
$builder->join('users as u', 'u.id = o.sold_by', 'left' );
$builder->where('o.tenant_id', $t);
$builder->where('o.created_at >=', $ot);
$builder->where('o.created_at <=', $ct);
return $results = $builder->get()->getResult();
}
CONTROLLER
//Daily Sales
public function getdailySales()
{
$t = $this->settingsModel->where('user_id', $this->tenantId->tenant_id)->first();
$ot = date('Y-m-d H:i:s', strtotime($t['opening_time']));
$ct = date('Y-m-d H:i:s', strtotime($t['closing_time'].'+ 1 day'));
$data = $this->transactionsModel->getdailySalesByTenant($this->tenantId->tenant_id, $ot, $ct);
$response = [
'success' => true,
'data' => $data,
];
return $this->response->setJSON($response);
}
I want to record daily sales from 2023-01-05 14:00:00 to 2023-01-06 03:00:00
Instead of:❌
// ...
$ot = date('Y-m-d H:i:s', strtotime($t['opening_time']));
$ct = date('Y-m-d H:i:s', strtotime($t['closing_time'].'+ 1 day'));
// ...
Use this:✅
$ot = (new DateTime($t['opening_time']))->format("Y-m-d H:i:s");
$ct = (function () use ($t) {
$openingTime = strtotime($t['opening_time']);
$closingTime = strtotime($t['closing_time']);
return ($closingTime >= $openingTime)
? (new DateTime($t['closing_time']))->format("Y-m-d H:i:s")
: (new DateTime($t['closing_time']))->modify("+1 DAY")->format("Y-m-d H:i:s");
})();
Reference(s):
The DateTime class
Adding one day to a date
When I use if --- else. it worked. Below is the Controller.
//Daily Sales
public function getdailySales()
{
$t = $this->settingsModel->where('user_id', $this->tenantId->tenant_id)->first();
$opening_hour = $t['opening_time'];
$hour=date('H'); //24hr clock.
if($hour < $opening_hour) {
$ot = date('Y-m-d H:i:s', strtotime($t['opening_time'].'- 1 day'));
$ct = date('Y-m-d H:i:s', strtotime($t['closing_time'].'+ 1 day'));
} else {
$ot = date('Y-m-d H:i:s', strtotime($t['opening_time']));
$ct = date('Y-m-d H:i:s', strtotime($t['closing_time'].'+ 1 day'));
}
$data = $this->transactionsModel->getdailySalesByTenant($this->tenantId->tenant_id, $ot, $ct);
$response = [
'success' => true,
'data' => $data,
];
return $this->response->setJSON($response);
}
Related
I want to give an alert when a condition is met in a day time, right now I get the hours statically
$hour1 = strtotime ("09:00");
$hour2 = strtotime ("01:00");
but I want to get the established schedule from the DB
$hour1 = strtotime ("09:00");
$hour2 = strtotime ("01:00");
if ($hour1 > $hour2) {
Session::flash('message', 'ABIERTO!');
Session::flash('', '');
}
elseif ($hour1 < $hour2 ) {
Session::flash('message', 'SHOP CLOSED!');
Session::flash('alert-class', 'alert-danger');
}
I already created the model on table status
help pls
You can try like this
$hour1 = DateTime::createFromFormat('H:i', $status->open);
$hour2 = DateTime::createFromFormat('H:i', $status->closed);
OR just simply
$hour1 = new DateTime($status->open);
$hour2 = new DateTime($status->closed);
Then just make conditional
if ($hour1 > $hour2)
// what to do
Am trying to create a date and time function to check if a given dateTime and timezone passed but my function is always returning true even when i put a future date.
I have below example class
<?php
class JobTimer{
public function __construct() {
}
public function isDateTime($startOn, $timezone = "GMT"){
$nowTime = new \DateTime("NOW", new \DateTimeZone($timezone));
$startTime = \DateTime::createFromFormat('M d, Y H:i:s', $startOn, new \DateTimeZone($timezone));
return ($nowTime >= $startTime ? true : false);
}
}
?>
Usage
Everything is returning true, my expectation is to return false if current time based on timezone has not yet elapse or return true when time has elapse or time is now
<?php
$job = new JobTimer();
//if($job->isDateTime("2019-05-02 12:00AM", "Asia/Kuala_Lumpur")){
//if($job->isDateTime("2021-05-02 12:00AM", "Asia/Kuala_Lumpur")){
if($job->isDateTime("2020-05-02 12:00AM", "Asia/Kuala_Lumpur")){
echo "YES";
}else{
echo "NO";
}
?>
In your JobTimer class $startTime is false because your format for DateTime::createFromFormat() does not match the format of the date you are passing in as a parameter and causing it to fail.
M d, Y H:i:s matches May 02, 2020 12:00:00 which is not what you are passing to that class.
You should be using:
$startTime = \DateTime::createFromFormat('Y-m-d H:iA', $startOn, new \DateTimeZone($timezone));
Working code:
class JobTimer{
public function __construct() {
}
public function isDateTime($startOn, $timezone = "GMT"){
$nowTime = new \DateTime("NOW", new \DateTimeZone($timezone));
$startTime = \DateTime::createFromFormat('Y-m-d H:iA', $startOn, new \DateTimeZone($timezone));
return $nowTime >= $startTime;
}
}
$job = new JobTimer();
if($job->isDateTime("2020-05-02 12:00AM", "Asia/Kuala_Lumpur")){
echo "YES";
}else{
echo "NO";
}
Output:
NO
Demo
Change your function to this:
public function isDateTime($startOn, $timezone = "GMT"){
$nowTime = new \DateTime("NOW", new \DateTimeZone($timezone));
$startTime = new \DateTime($startOn, new \DateTimeZone($timezone));
return ($nowTime >= $startTime ? true : false);
}
Your argument passed to createFromFormat is wrong, and therefore not creating a DateTime correctly. You can just pass your $startOn and a DateTimeZone to create a instance of DateTime
This question is related to my previews one: How to change time zome in different tables in Laravel
After I mark the answer, discover a problem:
When user load the page it need to gives him records for the current day.
For example from 00:00:00 to now.
The problem is that the controller is asking the DB to give records from 00:00:00 in UTC, after this my model(in the link above) parsing it to LOCAL time.
This local time is Europe/Sofia (+3 hours), causing to miss 3 records from today starting with 03:00:00.
Any idea how to fix it?
The controller:
function getdata_chart(Request $request)
{
$start_date = date('d-m-Y 00:00:00');
$end_date = date('d-m-Y 23:59:59');
if($request->start_date != '' && $request->end_date != '')
{
// if user fill dates
$dateScope = array($request->start_date ." 00:00:00", $request->end_date ." 23:59:59");
} else {
// default load page - today
$dateScope = array($start_date, $end_date);
};
$students = MeasCanal::whereBetween('recordtime', $dateScope)
->selectRaw('recordtime')
->selectRaw('max(formattedvalue) filter (where fullname = \'Данни.Кота\') as iazovir')
->selectRaw('max(formattedvalue) filter (where fullname = \'Данни.Температура\') as temperatura350')
->where(function ($query) {
$query->where('fullname', 'like', "Язовир.Данни.Кота")
->orWhere('fullname', 'like', "ГСК_11_350.Данни.Температура");
})
->groupBy('recordtime')
->orderBy('recordtime')
->get();
return response()->json($students);
}
return response()->json($students);
}
The model:
class MeasCanal extends Model
{
protected $connection = 'MeasCanal';
protected $table = 'meas_kanal';
protected $fillable = ['fullname','formattedvalue','recordtime','qualitydesc','statedesc','id'];
/**
* Get the user's recordtime.
*
* #param string $value
* #return string
*/
public function getRecordtimeAttribute($value)
{
return Carbon::parse($value)->timezone('Europe/Sofia')->toDateTimeString();
}
}
You have to map the user input date from the DB timezone to the user timezone by calling the carbon method and array map function. and call the query as it is.
function getdata_chart(Request $request) {
$start_date = date('d-m-Y 00:00:00');
$end_date = date('d-m-Y 23:59:59');
if($request->start_date != '' && $request->end_date != '')
{
// if user fill dates
$dateScope = array($request->start_date ." 00:00:00", $request->end_date ." 23:59:59");
} else {
// default load page - today
$dateScope = array($start_date, $end_date);
};
$dbTimeZone = 'Asia/Kolkata'; // update with your db timezone
$userTimeZone = 'Europe/Sofia';
$dateScope = array_map(function($date) use ($dbTimeZone, $userTimeZone) {
return Carbon::createFromFormat('d-m-Y H:i:s', $date, $dbTimeZone)->setTimezone($userTimeZone);
}, $dateScope);
$students = MeasCanal::whereBetween('recordtime', $dateScope)
->selectRaw('recordtime')
->selectRaw('max(formattedvalue) filter (where fullname = \'Данни.Кота\') as iazovir')
->selectRaw('max(formattedvalue) filter (where fullname = \'Данни.Температура\') as temperatura350')
->where(function ($query) {
$query->where('fullname', 'like', "Язовир.Данни.Кота")
->orWhere('fullname', 'like', "ГСК_11_350.Данни.Температура");
})
->groupBy('recordtime')
->orderBy('recordtime')
->get();
return response()->json($students);
}
return response()->json($students);
}
Note that:- add the following line to the controller if you are not using carbon til yet.
use Carbon\Carbon;
The problem was that date separator was different on each fuction causing Unexpected data found.. After edit him the answer of Sachin Kumar did the job. Thanks for that.
Just discover the problem with similar long way solution:
$start_date0 = date('d-m-Y 00:00:00');
$end_date0 = date('d-m-Y 23:59:59');
$start_date = Carbon::createFromFormat('d-m-Y H:i:s', $start_date0, 'Europe/Sofia')->setTimezone('UTC');
$end_date = Carbon::createFromFormat('d-m-Y H:i:s', $end_date0, 'Europe/Sofia')->setTimezone('UTC');
if($request->start_date != '' && $request->end_date != '')
{
// if user fill dates
$start_date0 = $request->start_date;
$end_date0 = $request->end_date;
$start_date = Carbon::createFromFormat('d/m/Y H:i:s', $start_date0, 'Europe/Sofia')->setTimezone('UTC');
$end_date = Carbon::createFromFormat('d/m/Y H:i:s', $end_date0, 'Europe/Sofia')->setTimezone('UTC');
$dateScope = array($start_date, $end_date);
} else {
// default load page - today
$dateScope = array($start_date, $end_date);
};
I am trying to seed DB table in Laravel. There is a time column which I need to have unique or at least not same for every record in that table.
Currently, I am using this; which does give the result to somewhat I am looking for but it's not complete.
mt_rand(0,23).":".str_pad(mt_rand(0,59), 2, "0", STR_PAD_LEFT)
My issue is that the single digit time don't have a 0 in front and sec are missing. Normally, what I was planning is the below code but it game me same results over and over:
date('H:i:s', strtotime( ((srand(0,1) ? '-'.mt_rand(1,24) : '+'.mt_rand(1,24).' '.rand(0,1) ? 'minute' : 'hour')), strtotime(date('H:i:s')))),
Result is "05:30:00" always so I am confused as to what to do next.
You said you are using Laravel, so why not just use the built-in Faker library for DateTime generation?
$faker = Faker::create();
$faker->time('H:i')
From the documentation, here is the available DateTime related outputs:
unixTime($max = 'now') // 58781813
dateTime($max = 'now', $timezone = null) // DateTime('2008-04-25 08:37:17', 'UTC')
dateTimeAD($max = 'now', $timezone = null) // DateTime('1800-04-29 20:38:49', 'Europe/Paris')
iso8601($max = 'now') // '1978-12-09T10:10:29+0000'
date($format = 'Y-m-d', $max = 'now') // '1979-06-09'
time($format = 'H:i:s', $max = 'now') // '20:49:42'
dateTimeBetween($startDate = '-30 years', $endDate = 'now', $timezone = null) // DateTime('2003-03-15 02:00:49', 'Africa/Lagos')
dateTimeInInterval($startDate = '-30 years', $interval = '+ 5 days', $timezone = null) // DateTime('2003-03-15 02:00:49', 'Antartica/Vostok')
dateTimeThisCentury($max = 'now', $timezone = null) // DateTime('1915-05-30 19:28:21', 'UTC')
dateTimeThisDecade($max = 'now', $timezone = null) // DateTime('2007-05-29 22:30:48', 'Europe/Paris')
dateTimeThisYear($max = 'now', $timezone = null) // DateTime('2011-02-27 20:52:14', 'Africa/Lagos')
dateTimeThisMonth($max = 'now', $timezone = null) // DateTime('2011-10-23 13:46:23', 'Antarctica/Vostok')
amPm($max = 'now') // 'pm'
dayOfMonth($max = 'now') // '04'
dayOfWeek($max = 'now') // 'Friday'
month($max = 'now') // '06'
monthName($max = 'now') // 'January'
year($max = 'now') // '1993'
century // 'VI'
timezone // 'Europe/Paris'
While #leek's answer is probably better considering you're using Laravel, a more generic way of getting what you need is the following:
$dt = new DateTime();
var_dump($dt->format('H:i:s'));
However, this will not be unique enough if you're running the script more than once a second. And of course, it will (potentially) not be unique if you run it over more than 1 day.
How to calculate a date before 10 days of every month end ?Am using codeigniter platform.
I need to check whether a date is within 10 days before the end of every month.
Please help
You can try using date_modify function for example see this php documentation
http://php.net/manual/en/datetime.modify.php
i need to check whether a date is within10 days before the end of a month
function testDate($date) {
$uDate = strtotime($date);
return date("m", $uDate) != date("m", strtotime("+10 days", $uDate));
}
echo testDate("2016-03-07") ? "Yes" :"No"; // No
echo testDate("2016-03-27") ? "Yes" :"No"; // Yes
you can create a library with this
class Calculate_days{
function __construct() {
parent::__construct();
}
function calculate( $to_day = date("j") ){
$days_month = date("t");
$result = (int) $days_month - $to_day;
if( $result <= 10){
$result = array("type" => TRUE, "missing" => $result . 'days');
return $result;
}
else{
$result = array("type" => FASLE, "missing" => $result . 'days');
return $result;
}
}
}
controller.php
function do_somthing(){
$this->load->library('Calculate_days');
$result = $this->Calculate_days->calculate(date("j"));
var_dump($result);
}