From da52a802eff659bbdbd276edcaa72511eeb6614b Mon Sep 17 00:00:00 2001 From: Frank Schubert Date: Fri, 21 Jun 2024 12:10:04 +0200 Subject: [PATCH] WIP Contract/Billing 2024-06-20 --- Layout/default/Billing/Index.php | 97 ++++++ application/Address/AddressModel.php | 2 +- application/Addresstype/AddresstypeModel.php | 18 +- .../Admin/functions/IvtContractImport.php | 6 +- application/Billing/Billing.php | 31 ++ application/Billing/BillingController.php | 191 ++++++++++ application/Billing/BillingModel.php | 325 ++++++++++++++++++ application/Contract/ContractModel.php | 25 +- .../20240620160026_create_billing.php | 72 ++++ public/assets/images/snopp-sm.png | Bin 0 -> 4858 bytes scripts/contract/test.php | 14 +- 11 files changed, 752 insertions(+), 29 deletions(-) create mode 100644 Layout/default/Billing/Index.php create mode 100644 application/Billing/Billing.php create mode 100644 application/Billing/BillingController.php create mode 100644 application/Billing/BillingModel.php create mode 100644 db/migrations/20240620160026_create_billing.php create mode 100644 public/assets/images/snopp-sm.png diff --git a/Layout/default/Billing/Index.php b/Layout/default/Billing/Index.php new file mode 100644 index 000000000..f943a071d --- /dev/null +++ b/Layout/default/Billing/Index.php @@ -0,0 +1,97 @@ +getUrl($Mod, "Index"); +$pagination_baseurl_params = ["filter" => $filter]; +$pagination_entity_name = "Billingrecords"; +?> + + + +
+
+
+
+ +
+

Contractfreigabe

+
+
+
+ + +
+
+ +
+
+

Filter

+ +
"> +
+ +
+ + "/> +
+ +
+
+
+ + ?resetFilter=1">Filter zurücksetzen +
+
+
+ +
+
+ +
+
+ +
+
+
+

Fertiggestellte Bestellungen

+ +
+ +
+
+ +
+
+ + + + + + + +
+ + + + + +
+
+ + +
+ +
+ +
+ +
+ + + \ No newline at end of file diff --git a/application/Address/AddressModel.php b/application/Address/AddressModel.php index dc61e811a..73189b104 100644 --- a/application/Address/AddressModel.php +++ b/application/Address/AddressModel.php @@ -219,7 +219,7 @@ class AddressModel { if (is_array($limit) && count($limit)) { if (is_numeric($limit['start']) && is_numeric($limit['count'])) { $sql .= " LIMIT " . $limit['start'] . ", " . $limit['count']; - } elseif (is_numeric($count)) { + } elseif (is_numeric($limit['count'])) { $sql .= " LIMIT " . $limit['count']; } } diff --git a/application/Addresstype/AddresstypeModel.php b/application/Addresstype/AddresstypeModel.php index 0f30428ff..901eb0ff1 100644 --- a/application/Addresstype/AddresstypeModel.php +++ b/application/Addresstype/AddresstypeModel.php @@ -34,28 +34,14 @@ class AddresstypeModel { return $model; } - - public static function getOne($id) { - if(!is_numeric($id) || !$id) { - throw new Exception("Invalid number", 400); - } - $item = []; - $db = FronkDB::singleton(); - - $res = $db->select($this->table, "*", "id=$id LIMIT 1"); - if($db->num_rows($res)) { - $data = $db->fetch_object($res); - $item = new Addresstype($data); - } - return $item; - } + public static function getAll() { $items = []; $db = FronkDB::singleton(); - $res = $db->select($this->table, "*"); + $res = $db->select("Addresstype", "*"); if($db->num_rows($res)) { while($data = $db->fetch_object($res)) { $items[] = new Addresstype($data); diff --git a/application/Admin/functions/IvtContractImport.php b/application/Admin/functions/IvtContractImport.php index d3d987c8b..d3f5076f3 100644 --- a/application/Admin/functions/IvtContractImport.php +++ b/application/Admin/functions/IvtContractImport.php @@ -167,10 +167,12 @@ class Admin_IvtContractImport { $order_date = new DateTime($ivt_contract->created); - $order_date->modify("+2 hours"); + $order_date->setTime(0,0,0); $finish_date = new DateTime($ivt_contract->lastdate); - $finish_date->setDate($finish_date->format("Y"), $finish_date->format("m"), 1); + $finish_date->modify("first day of this month"); + $finish_date->setTime(0,0,0); + //$finish_date->setDate($finish_date->format("Y"), $finish_date->format("m"), 1); //$finish_date->modify("+1 hours"); $contract_data = []; diff --git a/application/Billing/Billing.php b/application/Billing/Billing.php new file mode 100644 index 000000000..82aecf33f --- /dev/null +++ b/application/Billing/Billing.php @@ -0,0 +1,31 @@ +$name == null) { + + + + $classname = ucfirst($name); + $idfield = $name."_id"; + $this->$name = mfValuecache::singleton()->get("mfObjectmodel-$name-".$this->$idfield); + if(!$this->$name) { + $this->$name = new $classname($this->$idfield); + } + + if($this->$name->id) { + mfValuecache::singleton()->set("mfObjectmodel-$name-".$this->$name->id, $this->$name); + return $this->$name; + } else { + return null; + } + + } + + return $this->$name; + } +} \ No newline at end of file diff --git a/application/Billing/BillingController.php b/application/Billing/BillingController.php new file mode 100644 index 000000000..55f85a210 --- /dev/null +++ b/application/Billing/BillingController.php @@ -0,0 +1,191 @@ +needlogin = true; + $me = new User(); + $me->loadMe(); + $this->me = $me; + $this->layout()->set("me", $me); + + if (!$me->is(["Admin"])) { + $this->redirect("Dashboard"); + } + } + + protected function indexAction() { + $this->layout()->setTemplate("Billing/Index"); + + if ($this->request->resetFilter) { + unset($_SESSION[MFAPPNAME . '-Billing-filter']); + } + + $filter = []; + if (is_array($this->request->filter)) { + $filter = $this->request->filter; + $_SESSION[MFAPPNAME . '-Billing-filter'] = $filter; + } else { + if (array_key_exists(MFAPPNAME . '-Billing-filter', $_SESSION) && count($_SESSION[MFAPPNAME . '-Billing-filter'])) { + $filter = $_SESSION[MFAPPNAME . '-Billing-filter']; + } + } + + $this->layout->set("filter", $filter); + $filter = $this->getPreparedFilter($filter); + + // pagination defaults + $pagination = []; + $pagination['start'] = 0; + $pagination['count'] = 50; + $pagination['maxItems'] = 0; + + if (is_numeric($this->request->s)) { + $pagination['start'] = intval($this->request->s); + } + //var_dump($filter);exit; + $pagination['maxItems'] = BillingModel::count($filter); + $billings = BillingModel::search($filter, $pagination); + + $this->layout()->set("billings", $billings); + $this->layout()->set("pagination", $pagination); + + } + + private function getPreparedFilter($filter) + { + $new_filter = []; + + if (is_array($filter) && count($filter)) { + foreach ($filter as $name => $value) { + $new_filter[$name] = $value; + } + } + + return $new_filter; + } + + protected function importContractsAction() { + $r = $this->request; + + $today = new DateTime("now"); + $today->setTime(0,0,0); + + //$tomorrow = new DateTime("tomorrow"); + //$tomorrow->setTime(0,0,0); + + $i = 0; + + foreach(ContractModel::searchActive(["finish_date<" => $today->getTimestamp()]) as $contract) { + //var_dump($contract);exit; + + $now_year = date("Y"); + $now_month = date("m"); + $now_day = date("d"); + + $finish_year = date("Y", $contract->finish_date); + $finish_month = date("m", $contract->finish_date); + $finish_day = date("d", $contract->finish_date); + + $cancel_date = false; + if($contract->cancel_date) { + $cancel_date = new DateTime("@".$contract->cancel_date); + $cancel_date->setTime(0,0,0); + if($cancel_date->format("Y") != $now_year || $cancel_date->format("m") != $now_month) { + $cancel_date = false; + } + } + + // find last Billing row + $last_billing = BillingModel::getLast(["contract_id" => $contract->id]); + if(!$last_billing) { + // First billing + // check finish_date + // create Billing with start_date=finish_date and end_date = end of billing_period (month or year) + + $start_date = new DateTime("@".$contract->finish_date); + $start_date->setTime(2,0,0); + + $price_setup = $contract->price_setup; + } else { + // Concurrent Billing + // start_date next date after previous end_date + + $start_date = new DateTime($last_billing->end_date); + $start_date->modify("+1 month"); + + // set Setup price to 0, because it was billed already + $price_setup = 0; + } + + + + // if contract has cancel date this month + // use cancel date as end_date + if($cancel_date) { + $end_date = clone($cancel_date); + } else { + // else calculate last of month + $end_date = clone($start_date); + $end_date->modify("+".$contract->billing_period." months"); + $end_date->modify("first day of this month"); + $end_date->modify("-1 day"); + } + + $sday = $start_date->format("d"); + $eday = $end_date->format("d"); + + if($sday > 1 || $cancel_date) { + // aliquoter preis + $days = ($eday - $sday) + 1; + $pc = $days / $eday * 100; + $price = round($contract->price / 100 * $pc, 4); + } else { + $price = $contract->price; + } + + $owner = $contract->owner; + $billingaddress = $contract->billingaddress; + + $data = []; + $data["contract_id"] = $contract->id; + $data["start_date"] = $start_date->format("Y-m-d"); + $data["end_date"] = $end_date->format("Y-m-d"); + $data["billingaddress_id"] = ($contract->billingaddress_id) ? $contract->billingaddress_id : $contract->owner_id; + $data["customer_number"] = $contract->owner->customer_number; + $data["company"] = $billingaddress->company; + $data["firstname"] = $billingaddress->firstname; + $data["lastname"] = $billingaddress->lastname; + $data["street"] = $billingaddress->street; + $data["zip"] = $billingaddress->zip; + $data["city"] = $billingaddress->city; + $data["country"] = $billingaddress->country->name; + $data["email"] = $billingaddress->email; + $data["uid"] = $billingaddress->uid; + $data["billing_type"] = $billingaddress->billing_type; + $data["billing_delivery"] = $billingaddress->billing_delivery; + $data["bank_account_bank"] = $billingaddress->bank_account_bank; + $data["bank_account_owner"] = $billingaddress->bank_account_owner; + $data["bank_account_iban"] = $billingaddress->bank_account_iban; + $data["bank_account_bic"] = $billingaddress->bank_account_bic; + $data["matchcode"] = $contract->mathcode; + $data["product_id"] = $contract->product_id; + $data["product_name"] = $contract->product_name; + $data["product_info"] = $contract->product_info; + $data["amount"] = $contract->amount; + $data["price"] = $price; + $data["price_setup"] = $price_setup; + $data["billing_period"] = $contract->billing_period; + + $billing = BillingModel::create($data); + if(!$billing->save()) { + var_dump($billing);exit; + } + + $i++; + + } + $this->layout()->setFlash("$i Billing records generiert"); + } +} \ No newline at end of file diff --git a/application/Billing/BillingModel.php b/application/Billing/BillingModel.php new file mode 100644 index 000000000..07b2b1793 --- /dev/null +++ b/application/Billing/BillingModel.php @@ -0,0 +1,325 @@ + $value) { + if(property_exists(get_called_class(), $field)) { + $model ->$field = $value; + } + } + + $me = new User(); + $me->loadMe(); + + if($model->create_by === null) { + $model->create_by = $me->id; + } + if($model->edit_by === null) { + $model->edit_by = $me->id; + } + + return $model; + } + + public static function getAll() { + $items = []; + + $db = FronkDB::singleton(); + + $res = $db->select("Billing", "*", "1 = 1 ORDER BY billingaddress_id"); + if($db->num_rows($res)) { + while($data = $db->fetch_object($res)) { + $items[] = new Billing($data); + } + } + return $items; + + } + + public static function getFirst($filter) { + $db = FronkDB::singleton(); + + $where = self::getSqlFilter($filter); + $sql = "SELECT * FROM Billing + WHERE $where + ORDER BY billingaddress_id LIMIT 1"; + //var_dump($sql);exit; + $res = $db->query($sql); + if($db->num_rows($res)) { + $data = $db->fetch_object($res); + $item = new Billing($data); + if($item->id) { + return $item; + } else { + return null; + } + } + return null; + } + + public static function getLast($filter) { + $db = FronkDB::singleton(); + + $where = self::getSqlFilter($filter); + $sql = "SELECT * FROM Billing + WHERE $where + ORDER BY `create` DESC LIMIT 1"; + //var_dump($sql);exit; + $res = $db->query($sql); + if($db->num_rows($res)) { + $data = $db->fetch_object($res); + $item = new Billing($data); + if($item->id) { + return $item; + } else { + return null; + } + } + return null; + } + + public static function count($filter) { + $db = FronkDB::singleton(); + + $where = self::getSqlFilter($filter); + $sql = "SELECT COUNT(*) as cnt FROM Billing + WHERE $where"; + + mfLoghandler::singleton()->debug($sql); + + $res = $db->query($sql); + if($db->num_rows($res)) { + $data = $db->fetch_object($res); + return $data->cnt; + } + return 0; + } + + public static function search($filter, $limit = false) { + //var_dump($filter);exit; + $items = []; + $db = FronkDB::singleton(); + + $where = self::getSqlFilter($filter); + $sql = "SELECT * FROM Billing + WHERE $where + ORDER BY billingaddress_id"; + + if(is_array($limit) && count($limit)) { + if(is_numeric($limit['start']) && is_numeric($limit['count'])) { + $sql .= " LIMIT ".$limit['start'].", ".$limit['count']; + } elseif(is_numeric($limit['count'])) { + $sql .= " LIMIT ".$limit['count']; + } + } + + mfLoghandler::singleton()->debug($sql); + + $res = $db->query($sql); + if($db->num_rows($res)) { + while($data = $db->fetch_object($res)) { + $items[$data->id] = new Billing($data); + } + } + + return $items; + } + + private static function getSqlFilter($filter) { + $where = "1=1 "; + + $db = FronkDB::singleton(); + + //var_dump($filter);exit; + + if(array_key_exists("id", $filter)) { + $id = $filter['id']; + if(is_numeric($id)) { + $where .= " AND Billing.id like '%$id%'"; + } + } + + if(array_key_exists("approved", $filter)) { + $approved = $filter['approved']; + if($approved) { + $where .= " AND Billing.approved = 1"; + } else { + $where .= " AND Billing.approved = 0"; + } + } + + if(array_key_exists("invoice_id", $filter)) { + $invoice_id = $filter['invoice_id']; + if(is_numeric($invoice_id)) { + $where .= " AND Billing.invoice_id=$invoice_id"; + } + } + + if(array_key_exists("invoice_date", $filter)) { + $invoice_date = $filter['invoice_date']; + if($invoice_date) { + $where .= " AND Billing.invoice_date='$invoice_date'"; + } + } + + if(array_key_exists("contract_id", $filter)) { + $contract_id = $filter['contract_id']; + if(is_numeric($contract_id)) { + $where .= " AND Billing.contract_id=$contract_id"; + } + } + + if(array_key_exists("billingaddress_id", $filter)) { + $billingaddress_id = $filter['billingaddress_id']; + if(is_numeric($billingaddress_id)) { + $where .= " AND Billing.billingaddress_id=$billingaddress_id"; + } + } + + if(array_key_exists("customer_number", $filter)) { + $customer_number = $filter['customer_number']; + if(is_numeric($customer_number)) { + $where .= " AND Billing.customer_number LIKE $customer_number"; + } + } + + if (array_key_exists("company", $filter)) { + $company = FronkDB::singleton()->escape($filter["company"]); + if ($company) { + $where .= " AND company like '%$company%'"; + } + } + + if (array_key_exists("firstname", $filter)) { + $firstname = FronkDB::singleton()->escape($filter["firstname"]); + if ($firstname) { + $where .= " AND firstname like '%$firstname%'"; + } + } + + if (array_key_exists("lastname", $filter)) { + $lastname = FronkDB::singleton()->escape($filter["lastname"]); + if ($lastname) { + $where .= " AND lastname like '%$lastname%'"; + } + } + + if (array_key_exists("mergedName", $filter)) { + $name = FronkDB::singleton()->escape($filter["mergedName"]); + if ($name) { + $where .= " AND (CONCAT(firstname, ' ', lastname) like '%$name%' OR CONCAT(lastname, ' ', firstname) like '%$name%' )"; + } + } + + if (array_key_exists("street", $filter)) { + $street = FronkDB::singleton()->escape($filter["street"]); + if ($street) { + $where .= " AND street like '%$street%'"; + } + } + + if (array_key_exists("zip", $filter)) { + $zip = FronkDB::singleton()->escape($filter["zip"]); + if ($zip) { + $where .= " AND zip like '%$zip%'"; + } + } + + if (array_key_exists("city", $filter)) { + $city = FronkDB::singleton()->escape($filter["city"]); + if ($city) { + $where .= " AND city like '%$city%'"; + } + } + + if (array_key_exists("country", $filter)) { + $country = FronkDB::singleton()->escape($filter["country"]); + if ($country) { + $where .= " AND country like '%$country%'"; + } + } + + if (array_key_exists("email", $filter)) { + $email = FronkDB::singleton()->escape($filter["email"]); + if ($email) { + $where .= " AND email like '%$email%'"; + } + } + + if(array_key_exists("matchcode", $filter)) { + $matchcode = FronkDB::singleton()->escape($filter["matchcode"]); + if($matchcode) { + $where .= " AND matchcode like '%$matchcode%'"; + } + } + + if(array_key_exists("product_id", $filter)) { + $product_id = $filter['product_id']; + if(is_numeric($product_id)) { + $where .= " AND Billing.product_id=$product_id"; + } + } + + if(array_key_exists("product_name", $filter)) { + $product_name = $db->escape($filter['product_name']); + if($product_name) { + $where .= " AND product_name like '%$product_name%')"; + } + } + + if(array_key_exists("matchcode", $filter)) { + $matchcode = $db->escape($filter['matchcode']); + if($matchcode) { + $where .= " AND Billing.`matchcode` like '%$matchcode%'"; + } + } + + if(array_key_exists("add-where", $filter)) { + $where .= " ".$filter['add-where']; + } + + + //var_dump($filter, $where);exit; + return $where; + } + +} diff --git a/application/Contract/ContractModel.php b/application/Contract/ContractModel.php index c35e4daf7..94d78d311 100644 --- a/application/Contract/ContractModel.php +++ b/application/Contract/ContractModel.php @@ -184,10 +184,6 @@ class ContractModel { return $contract; } - public function savePrecontract($contract) { - - } - public static function getAll() { $items = []; @@ -475,6 +471,13 @@ class ContractModel { } } + if(array_key_exists("finish_date", $filter)) { + $finish_date = $filter['finish_date']; + if(is_numeric($finish_date)) { + $where .= " AND Contract.finish_date = $finish_date"; + } + } + if(array_key_exists("finish_date>", $filter)) { $finish_date = $filter['finish_date>']; if(is_numeric($finish_date)) { @@ -488,6 +491,20 @@ class ContractModel { $where .= " AND Contract.finish_date <= $finish_date"; } } + + if(array_key_exists("cancel_date>", $filter)) { + $cancel_date = $filter['cancel_date>']; + if(is_numeric($cancel_date)) { + $where .= " AND Contract.cancel_date >= $cancel_date"; + } + } + + if(array_key_exists("cancel_date<", $filter)) { + $cancel_date = $filter['cancel_date<']; + if(is_numeric($cancel_date)) { + $where .= " AND Contract.cancel_date <= $cancel_date"; + } + } if(array_key_exists("add-where", $filter)) { $where .= " ".$filter['add-where']; diff --git a/db/migrations/20240620160026_create_billing.php b/db/migrations/20240620160026_create_billing.php new file mode 100644 index 000000000..5eb323ad2 --- /dev/null +++ b/db/migrations/20240620160026_create_billing.php @@ -0,0 +1,72 @@ +getEnvironment() == "thetool") { + $table = $this->table("Billing"); + $table->addColumn("invoice_id", "integer", ["null" => true, "default" => null]); + $table->addColumn("invoice_date", "date", ["null" => true, "default" => null]); + $table->addColumn("contract_id", "integer", ["null" => false]); + $table->addColumn("start_date", "date", ["null" => false]); + /*$table->addColumn("start_year", "integer", ["null" => false]); + $table->addColumn("start_month", "integer", ["null" => false]); + $table->addColumn("start_day", "integer", ["null" => false]);*/ + $table->addColumn("end_date", "date", ["null" => false]); + /*$table->addColumn("end_year", "integer", ["null" => false]); + $table->addColumn("end_month", "integer", ["null" => false]); + $table->addColumn("end_day", "integer", ["null" => false]);*/ + $table->addColumn("billingaddress_id", "integer", ["null" => false]); + $table->addColumn("customer_number", "integer", ["null" => false]); + $table->addColumn("company", "string", ["null" => true, "default" => null, "length" => 1024]); + $table->addColumn("firstname", "string", ["null" => true, "default" => null, "length" => 1024]); + $table->addColumn("lastname", "string", ["null" => true, "default" => null, "length" => 1024]); + $table->addColumn("street", "string", ["null" => false, "length" => 1024]); + $table->addColumn("zip", "string", ["null" => false, "length" => 1024]); + $table->addColumn("city", "string", ["null" => false, "length" => 1024]); + $table->addColumn("country", "string", ["null" => true, "default" => null, "length" => 1024]); + $table->addColumn("email", "string", ["null" => true, "default" => null, "length" => 1024]); + $table->addColumn("uid", "string", ["null" => true, "default" => null, "length" => 1024]); + $table->addColumn("billing_type", "enum", ["null" => false, "values" => "invoice,sepa"]); + $table->addColumn("billing_delivery", "enum", ["null" => false, "values" => "email,paper"]); + $table->addColumn("bank_account_bank", "string", ["null" => true, "default" => null, "length" => 255]); + $table->addColumn("bank_account_owner", "string", ["null" => true, "default" => null, "length" => 255]); + $table->addColumn("bank_account_iban", "string", ["null" => true, "default" => null, "length" => 255]); + $table->addColumn("bank_account_bic", "string", ["null" => true, "default" => null, "length" => 255]); + $table->addColumn("matchcode", "string", ["null" => true, "default" => null, "length" => 255]); + $table->addColumn("product_id", "integer", ["null" => false]); + $table->addColumn("product_name", "string", ["null" => false, "length" => 255]); + $table->addColumn("product_info", "text", ["null" => true, "default" => null]); + $table->addColumn("amount", "decimal", ["null" => false, "precision" => 9, "scale" => 6]); + $table->addColumn("price", "decimal", ["null" => false, "precision" => 14, "scale" => 4]); + $table->addColumn("price_setup", "decimal", ["null" => false, "default" => 0, "precision" => 14, "scale" => 4]); + $table->addColumn("billing_period", "integer", ["null" => false, "default" => 0]); + + $table->addColumn("create_by", "integer", ["null" => false]); + $table->addColumn("edit_by", "integer", ["null" => false]); + $table->addColumn("create", "integer", ["null" => false]); + $table->addColumn("edit", "integer", ["null" => false]); + $table->create(); + + } + + if($this->getEnvironment() == "addressdb") { + + } + } + + public function down(): void + { + if($this->getEnvironment() == "thetool") { + $this->table("Billing")->drop()->save(); + } + + if($this->getEnvironment() == "addressdb") { + + } + } +} diff --git a/public/assets/images/snopp-sm.png b/public/assets/images/snopp-sm.png new file mode 100644 index 0000000000000000000000000000000000000000..7eb02f36ec4fb6a288a8c2e37f60bc785e4eaa66 GIT binary patch literal 4858 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 $finish_date_from = new DateTime("2024-05-31 22:00:00"); -$finish_date_to = new DateTime("2024-06-01 23:59:59"); +$finish_date_to = new DateTime("2024-06-01 02:00:00"); +$finish_date = new DateTime("2024-06-01 00:00:00"); $cms = 0; $cmss = 0; $cys = 0; -foreach(ContractModel::search(["finish_date>" => $finish_date_from->getTimestamp(), "finish_date<" => $finish_date_to->getTimestamp()]) as $contract) { +foreach(ContractModel::search(["finish_date" => $finish_date->getTimestamp()]) as $contract) { if($contract->billing_period == 1 && $contract->price > 0.00000) { $cms += $contract->price; } @@ -30,9 +31,9 @@ foreach(ContractModel::search(["finish_date>" => $finish_date_from->getTimestamp } -$First = new DateTime("2024-05-31 22:00:00"); +$First = new DateTime("2023-05-31 22:00:00"); //$First = new DateTime("2024-06-09 00:00:00"); -$Last = new DateTime("2024-06-01 06:00:00"); +$Last = new DateTime("2024-06-01 00:00:00"); foreach(ContractModel::search(["billing_period" => 12]) as $contract) { $fdate = new DateTime("@".$contract->finish_date); @@ -41,7 +42,8 @@ foreach(ContractModel::search(["billing_period" => 12]) as $contract) { $d = $fdate->format("d"); //if(($m == 5 && $d >= 11) || ($m == 6 && $d <= 10)) { - if($contract->finish_date >= $First->getTimestamp() && $contract->finish_date <= $Last->getTimestamp()) { + //if($contract->finish_date >= $First->getTimestamp() && $contract->finish_date <= $Last->getTimestamp()) { + if($contract->finish_date == $Last->getTimestamp()) { $cys += $contract->price; } } @@ -97,7 +99,7 @@ echo "Diff thetool <-> ivt Bills: ".round($cid, 4)."\n"; $gsm = 0; $gsy = 0; -foreach(ContractModel::search(["price<" => 0, "finish_date>" => $finish_date_from->getTimestamp(), "finish_date<" => $finish_date_to->getTimestamp()]) as $contract) { +foreach(ContractModel::search(["price<" => 0, "finish_date" => $finish_date->getTimestamp()]) as $contract) { if($contract->billing_period == 1) { $gsm += $contract->price; } elseif($contract->billing_period == 12) {