diff --git a/Layout/default/Billing/Index.php b/Layout/default/Billing/Index.php new file mode 100644 index 000000000..c786a0c3c --- /dev/null +++ b/Layout/default/Billing/Index.php @@ -0,0 +1,165 @@ +getUrl($Mod, "Index"); +$pagination_baseurl_params = ["filter" => $filter]; +$pagination_entity_name = "Billingrecords"; +?> + + + +
+
+
+
+ +
+

Rechnungsdatensätze

+
+
+
+ + +
+
+ +
+
+

Filter

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

Fertiggestellte Bestellungen

+ +
+ +
+
+ +
+
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Contract IDPeriodeVertragsinhaberRechnungsadresseKundennummerEinzugZustellungBankdatenProduktAnzahlPreisPreis Setup
$billing->contract_id])?>" target="_blank">contract_id?>start_date?> - end_date?> + contract->owner->getCompanyOrName()?>
+ contract->owner->street?>
+ contract->owner->zip?> contract->owner->city?> + contract->owner->country->name?> +
+ company) ? $billing->company."
" : ""?> + firstname || $billing->lastname) ? $billing->firstname." ".$billing->lastname."
" : ""?> + street?>
+ zip?> city?>
+ country?> +
customer_number?>billing_type == "sepa") ? "SEPA" : ""?>billing_delivery == "email") ? "Email" : "Papier"?> + billing_type == "sepa"): ?> + Kontoinhaber: bank_account_owner?>
+ Bank: bank_account_bank?>
+ IBAN: bank_account_iban?>
+ BIC: bank_account_bic?>
+ +
+ product_name?>matchcode) ? " (".$billing->matchcode.")" : ""?> + product_info): ?> +
+ product_info?> +
+ +
amount,3,",",".")?>price,4,",",".")?>price_setup,4,",",".")?>
+ + + + + +
+
+ + +
+ +
+ +
+ +
+ + + \ No newline at end of file diff --git a/Layout/default/Building/Index.php b/Layout/default/Building/Index.php index bd669702e..7a34278b9 100644 --- a/Layout/default/Building/Index.php +++ b/Layout/default/Building/Index.php @@ -147,6 +147,7 @@ Adresse Einheiten Status + @@ -162,6 +163,7 @@ units?> status->name."-b")?> + $building->id])?>"> $building->id])?>" class="text-danger" onclick="if(!confirm('Objekt wirklich löschen?')) return false;" title="Objekt Löschen"> diff --git a/Layout/default/Contract/Index.php b/Layout/default/Contract/Index.php index 2c7a54fea..8926ffc5f 100644 --- a/Layout/default/Contract/Index.php +++ b/Layout/default/Contract/Index.php @@ -128,8 +128,8 @@ --> - isFinished()) ? "not-finished" : "" ?> price < 0) ? "text-danger" : ""?>">price?> - isFinished()) ? "not-finished" : "" ?> price_setup < 0) ? "text-danger" : ""?>">price_setup?> + isFinished()) ? "not-finished" : "" ?> price < 0) ? "text-danger" : ""?>">€ price,4,",",".")?> + isFinished()) ? "not-finished" : "" ?> price_setup < 0) ? "text-danger" : ""?>">€ price_setup,4,",",".")?> isFinished()) ? "not-finished" : "" ?>"> billing_period == 1): ?> monatlich 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 ddc3469ba..c9351c0bf 100644 --- a/application/Admin/functions/IvtContractImport.php +++ b/application/Admin/functions/IvtContractImport.php @@ -4,6 +4,7 @@ class Admin_IvtContractImport { private $request; private $log; private $static_ivt_order_match = []; + private $no_matchcode = []; public function __construct($request = false) { $this->request = $request; @@ -77,6 +78,13 @@ class Admin_IvtContractImport { 16267 => 3079, // schmuck marianne 16786 => 3079 ]; + $this->no_matchcode = [ + 9, + 2847, + 3049, + 5719 + + ]; } /* TODO: Credit */ @@ -166,12 +174,9 @@ class Admin_IvtContractImport { - $finish_date = new DateTime($ivt_contract->created); - $finish_date->modify("+2 hours"); - $last_date = new DateTime($ivt_contract->lastdate); - $last_date->modify("+1 day"); - $last_date->modify("+1 hours"); + + $contract_data = []; $contract_data['owner_id'] = $customer->id; @@ -184,23 +189,35 @@ class Admin_IvtContractImport { $contract_data['price_nne'] = 0; $contract_data['price_nbe'] = 0; $contract_data['sla_id'] = $this->getNewSlaId($ivt_contract->sid); - $contract_data['order_date'] = $finish_date->getTimestamp(); - $contract_data['finish_date'] = $last_date->getTimestamp(); - $contract_data['finish_date_by'] = 1; $contract_data['imported_from'] = "ivt"; $contract_data['imported_data'] = $ivt_contract->id; $contract_data['create_by'] = 1; $contract_data['edit_by'] = 1; + $finish_date = new DateTime($ivt_contract->lastdate); + switch($ip->interval) { case 0: $contract_data['billing_period'] = 1; + $finish_date->modify("+1 month"); break; case 1: $contract_data['billing_period'] = 12; + $finish_date->modify("+1 year"); break; } + $order_date = new DateTime($ivt_contract->created); + $order_date->setTime(2,0,0); + + $finish_date->modify("first day of this month"); + $finish_date->setTime(2,0,0); + //$finish_date->setDate($finish_date->format("Y"), $finish_date->format("m"), 1); + //$finish_date->modify("+1 hours"); + + $contract_data['order_date'] = $order_date->getTimestamp(); + $contract_data['finish_date'] = $finish_date->getTimestamp(); + $contract_data['finish_date_by'] = 1; $neu["customer"] = $customer; $neu["ivtcustomer"] = $ivt_customer; @@ -319,6 +336,8 @@ class Admin_IvtContractImport { foreach($new_contracts as $ivt_customer_id => $contracts) { $this->addVoipData($ivt_customer_id, $contracts); + if(in_array($ivt_contract->id, $this->no_matchcode)) break; + if(count($contracts) < 2) continue; $prev_contracts = []; $primary_matchcode = false; diff --git a/application/Admin/functions/IvtCreditImport.php b/application/Admin/functions/IvtCreditImport.php index a155bc2b2..cc90709cc 100644 --- a/application/Admin/functions/IvtCreditImport.php +++ b/application/Admin/functions/IvtCreditImport.php @@ -6,12 +6,18 @@ class Admin_IvtCreditImport { private $netownerid = [ 3805 => 2840, 4941 => 2840, - 4909 => 3199, + 4909 => 3199 ]; private $cust_cred_ignore = [ 2267, 2934 ]; + private $netowner_ignore = [ + 3716 + ]; + private $netowner_rules = [ + 3715 => ["action" => "double_price"], + ]; private $cust_cred_id_to_customer_id = [ 2891 => 104004, @@ -49,6 +55,8 @@ class Admin_IvtCreditImport { $ivt_customer = $cust_cred->customer; } + if(in_array($ivt_netowner->id, $this->netowner_ignore)) continue; + if(!$ivt_customer) { echo __METHOD__.": No customer in cust_cred ".$cust_cred->id."\n"; continue; @@ -62,7 +70,7 @@ class Admin_IvtCreditImport { } if(!$customer) { - echo __METHOD__ . ": No Customer ".$ivt_customer->id." cust_cred ".$cust_cred->id."\n"; + // XXX echo __METHOD__ . ": No Customer ".$ivt_customer->id." cust_cred ".$cust_cred->id."\n"; //$this->log->debug("No Customer ".$ivt_customer->id." cust_cred ".$cust_cred->id); exit; } @@ -74,60 +82,107 @@ class Admin_IvtCreditImport { } $contracts = ContractModel::search(["owner_id" => $customer->id]); - - // DEBUG: not all contracts imported yet - if(!count($contracts)) { - $ivt_contract_count = IvtCustomerProductModel::count(["cid" => $customer->id]); - echo __METHOD__ . ": Contract not found for credit ".$cust_cred->id." Kunde ".$customer->getCompanyOrName()." (".$customer->customer_number."; $ivt_contract_count IVT Contracts), GS an ".$netowner->getCompanyOrName()." (".$netowner->customer_number.")\n"; - continue; - } - // use first contract as primary contract - $primary_contract = reset($contracts); - // find more suitable primary contract - foreach($contracts as $contract) { - // only monthly products - if($contract->biling_period > 1) continue; - // no one-off products - if(!$contract->price && $contract->price_setup) continue; - if($contract->termination_id) { - $primary_contract = $contract; - break; - } - if(preg_match('/(dsl|funkinternet|standortgeber|glasfaser|brettljausn)/i', $contract->product->name)) { - $primary_contract = $contract; - break; - } - - } - - if(!$primary_contract) { - //echo __METHOD__ . ": Contract not found for credit ".$cust_cred->id."\n"; - $this->log->debug("No primary contract cust ".$ivt_customer->id); - } - - // create Credit Contract - - if(!$primary_contract->product_id) { - var_dump($primary_contract);exit; - } - $data = []; - $data["orderproduct_id"] = $primary_contract->orderproduct_id; - $data["product_id"] = $primary_contract->product_id; - $data["product_name"] = $primary_contract->product_name; - $data["product_info"] = $primary_contract->product_info; - $data["amount"] = $primary_contract->amount; - $data["sla_id"] = $primary_contract->sla_id; - $data["product_external"] = $primary_contract->product_external; - $data["product_external_id"] = $primary_contract->product_external_id; - $data["billing_delay"] = $primary_contract->billing_delay; - $data["billing_period"] = $primary_contract->billing_period; - $data["contract_term"] = $primary_contract->contract_term; - $data["order_date"] = $primary_contract->order_date; - $data["finish_date"] = $primary_contract->finish_date; - $data["finish_date_by"] = $primary_contract->finish_date_by; - $data["note"] = $primary_contract->note; + /* + * 1962 - internal xinon account for credits missing contract + * + */ + if($ivt_customer->id != 1962) { + // if not xinon internal, look up primary contract for linking + if(!count($contracts)) { + $ivt_contracts = IvtCustomerProductModel::search(["cid" => $ivt_customer->id]); + //echo __METHOD__ . ": Contract not found for credit ".$cust_cred->id." Kunde ".$customer->getCompanyOrName()." (".$customer->customer_number."; ".count($ivt_contracts)." IVT Contracts), GS an ".$netowner->getCompanyOrName()." (".$netowner->customer_number.")\n"; + echo "Netzinhaber: " . $netowner->getCompanyOrName() . " (" . $netowner->customer_number . ")\n"; + echo "Kunde: " . $customer->getCompanyOrName() . " (" . $customer->customer_number . ")\n"; + echo "Gutschft: " . $cust_cred->crediting_product->name . " | " . $cust_cred->crediting_product->price_excl . "\n"; + echo "GS Comment: " . $cust_cred->comment . "\n"; + if($ivt_contracts) { + echo "Kunde Produkte:\n"; + foreach($ivt_contracts as $ivtc) { + echo "\t" . $ivtc->pid . ": " . $ivtc->product->name . " | " . $ivtc->product->price . "\n"; + } + } else { + echo "Keine aktiven Produkte\n"; + } + + echo "=========================\n\n"; + continue; + } + + // use first contract as primary contract + $primary_contract = reset($contracts); + // find more suitable primary contract + foreach($contracts as $contract) { + // only monthly products + if($contract->biling_period > 1) continue; + // no one-off products + if(!$contract->price && $contract->price_setup) continue; + if($contract->termination_id) { + $primary_contract = $contract; + break; + } + if(preg_match('/(dsl|funkinternet|standortgeber|glasfaser|brettljausn)/i', $contract->product->name)) { + $primary_contract = $contract; + break; + } + + } + + if(!$primary_contract) { + //echo __METHOD__ . ": Contract not found for credit ".$cust_cred->id."\n"; + $this->log->debug("No primary contract cust " . $ivt_customer->id); + } + + // create Credit Contract + + if(!$primary_contract->product_id) { + var_dump($primary_contract); + exit; + } + + + $data["orderproduct_id"] = $primary_contract->orderproduct_id; + $data["product_id"] = $primary_contract->product_id; + $data["product_name"] = $primary_contract->product_name; + $data["product_info"] = $primary_contract->product_info; + $data["amount"] = $primary_contract->amount; + $data["sla_id"] = $primary_contract->sla_id; + $data["product_external"] = $primary_contract->product_external; + $data["product_external_id"] = $primary_contract->product_external_id; + $data["billing_delay"] = $primary_contract->billing_delay; + $data["billing_period"] = $primary_contract->billing_period; + $data["contract_term"] = $primary_contract->contract_term; + $data["order_date"] = $primary_contract->order_date; + + $data["finish_date"] = $primary_contract->finish_date; + $data["finish_date_by"] = $primary_contract->finish_date_by; + $data["note"] = $primary_contract->note; + } else { + $create_date = new DateTime($cust_cred->created); + $create_date->setTime(2,0); + + $finish_date = new DateTime($cust_cred->lastdate); + $finish_date->modify("first day of this month"); + $finish_date->setTime(2,0,0); + //$finish_date->setDate($finish_date->format("Y"), $finish_date->format("m"), 1); + + $data["orderproduct_id"] = null; + $data["product_id"] = 336; // Mainproduct dummy for crediting import [IVT] + $data["product_name"] = $cust_cred->crediting_product->name; + $data["product_info"] = null; + $data["amount"] = 1; + $data["sla_id"] = 4; + $data["product_external"] = 0; + $data["product_external_id"] = null; + $data["billing_delay"] = 0; + $data["billing_period"] = 1; + $data["contract_term"] = 12; + $data["order_date"] = $create_date->getTimestamp(); + $data["finish_date"] = $finish_date->getTimestamp(); + $data["finish_date_by"] = 1; + $data["note"] = null; + } $data["matchcode"] = $cust_cred->comment; $data["owner_id"] = $netowner->id; @@ -138,6 +193,16 @@ class Admin_IvtCreditImport { $data["price_nne"] = 0; $data["price_nbe"] = 0; + $data['imported_from'] = "ivt-credit"; + $data['imported_data'] = $cust_cred->id; + + + if(array_key_exists($ivt_netowner->id, $this->netowner_rules)) { + if($this->netowner_rules[$ivt_netowner->id]["action"] == "double_price") { + $data['price'] *= 2; + } + } + $cred_contract = ContractModel::create($data); if(!$cred_contract->save()) { $this->log->debug("error saving credit contract"); @@ -146,22 +211,49 @@ class Admin_IvtCreditImport { } $c++; + // create Journals + // creation journal + $journal = ContractjournalModel::create([ + 'contract_id' => $cred_contract->id, + 'type' => "created_from", + 'value' => "import", + 'text' => "IVT customer_credit ".$cust_cred->id."; cid: ".$cust_cred->cust_id."; pid: ".$ivt_cred_product->id." (".$ivt_cred_product->name.")" + ]); + $journal_id = $journal->save(); + if(!$journal_id) { + echo "Fehler beim Journal erstellen.
\n"; + exit; + } - // Link to all Contracts of Customer - foreach($contracts as $contract) { - if (ContractLinkModel::getFirst(["contract_id" => $cred_contract->id, "origin_contract_id" => $contract->id])) { - continue; + // credit linking journal + $journal = ContractjournalModel::create([ + 'contract_id' => $primary_contract->id, + 'type' => "credit_created", + 'value' => $cred_contract->id, + ]); + $journal_id = $journal->save(); + if(!$journal_id) { + echo "Fehler beim Journal erstellen.
\n"; + exit; + } + + if(count($contracts)) { + // Link to all Contracts of Customer + foreach($contracts as $contract) { + if(ContractLinkModel::getFirst(["contract_id" => $cred_contract->id, "origin_contract_id" => $contract->id])) { + continue; + } + $link = ContractLinkModel::create([ + 'contract_id' => $cred_contract->id, + 'origin_contract_id' => $contract->id, + 'type' => 'link' + ]); + $link->save(); } - $link = ContractLinkModel::create([ - 'contract_id' => $cred_contract->id, - 'origin_contract_id' => $contract->id, - 'type' => 'link' - ]); - $link->save(); } } - echo "Imported $i credits; $c Contracts erstellt\n"; + echo "Imported $i credits; $c Credit Contracts erstellt\n"; } } \ No newline at end of file diff --git a/application/Api/v1/AddressdbApicontroller.php b/application/Api/v1/AddressdbApicontroller.php index 971e109c1..deaf5fc20 100644 --- a/application/Api/v1/AddressdbApicontroller.php +++ b/application/Api/v1/AddressdbApicontroller.php @@ -839,9 +839,9 @@ class AddressdbApicontroller extends mfBaseApicontroller { } protected function exportAddresses() { - /*if($this->me->username != 'r.eschner@rmlinfrastruktur.at') { + if($this->me->username != 'r.eschner@rmlinfrastruktur.at') { return mfResponse::Forbidden(); - }*/ + } if($this->me->is("Admin")) { $my_networks = NetworkModel::getAll(); @@ -854,10 +854,7 @@ class AddressdbApicontroller extends mfBaseApicontroller { foreach($my_networks as $network) { if($network->adb_netzgebiet_id && !in_array($network->adb_netzgebiet_id, $netzgebiet_ids)) { $netzgebiet_ids[] = $network->id; - if($network->adb_netzgebiet_id) { - $adb_network_ids[] = $network->adb_netzgebiet_id; - } - + $adb_network_ids[] = $network->adb_netzgebiet_id; } } diff --git a/application/Billing/Billing.php b/application/Billing/Billing.php new file mode 100644 index 000000000..69ccd8318 --- /dev/null +++ b/application/Billing/Billing.php @@ -0,0 +1,32 @@ +$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..160e0d254 --- /dev/null +++ b/application/Billing/BillingController.php @@ -0,0 +1,377 @@ +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 (array_key_exists("show_credit", $filter)) { + if ($filter["show_credit"] == 0) { + $new_filter["price>="] = 0; + } + unset($filter["show_credit"]); + } else { + $new_filter["price>="] = 0; + } + + 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; + + $now_year = date("Y"); + $now_month = date("m"); + $now_day = date("d"); + $now_year = 2024; + $now_month = 7; + + foreach(ContractModel::search(["finish_date<" => mktime(0,0,0,$now_month, $now_day, $now_year), "cancel_date" => null]) as $contract) { + //var_dump($contract);exit; + //$contract = new Contract(1); + + + + + $bill_month = $now_month; + $bill_year = $now_year; + //$bill_day = $now_day; + $bill_date = new DateTime("$bill_year-$bill_month-01"); + //echo $bill_date->format("Y-m-d H:i:s")."
"; + $monthly_bill_period_to = clone($bill_date); + $monthly_bill_period_to->modify("last day of this month"); + + $contract_finish_date = new DateTime("@".$contract->finish_date); + $finish_year = date("Y", $contract->finish_date); + $finish_month = date("m", $contract->finish_date); + $finish_day = date("d", $contract->finish_date); + + //echo "$bill_month $bill_year\n";exit; + + //echo $monthly_bill_period_to->format("Y-m-d H:i:s");exit; + if($contract_finish_date > $monthly_bill_period_to) { + $this->log->debug(__METHOD__.": Ignoring Contract ".$contract->id." because finish_date is in $finish_month $finish_year"); + continue; + } + + if($contract->billing_period < 1) { + $this->log->debug(__METHOD__.": Ignoring Contract ".$contract->id." because billing_period == 0"); + continue; + } + if($contract->price == 0 && $contract->price_setup == 0) { + $this->log->debug(__METHOD__.": Ignoring Contract ".$contract->id." because price and price_setup == 0"); + continue; + } + + $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; + } + } + + $start_date = new DateTime("@".$contract->finish_date); + $start_date->setTimezone(new DateTimeZone("Europe/Vienna")); + + // ignore yearly contracts which are not billable this month + if($contract->billing_period == 12) { + if($start_date->format("m") != $bill_month) { + continue; + } + } + + $create_bills = []; + + // Concurrent Billing + // find not yet billed periods + + $create_dates = []; + + $create_date = clone $start_date; + //$create_date->modify("+".$contract->billing_period." month"); + $create_date->modify("first day of this month"); + $last_create_date = false; + //echo "first create_date: ".$create_date->format("Y-m-d H:i:s")."
\n"; + //echo "while ".$create_date->getTimestamp()." (".$create_date->format("Y-m-d H:i:s").") >= ".$contract->finish_date." (".date("Y-m-d H:i:s", $contract->finish_date).")
\n"; + + while($create_date->getTimestamp() >= $contract->finish_date) { + //echo "in need date while (".$create_date->format("Y-m-d H:i:s").")
"; + if($last_create_date) { + // must for safety / shouldn't happen + die("need-date ran out of dates"); + } + + //echo "    "; + //echo $create_date->format("Y")." == ".$finish_year." && ".$create_date->format("m")." == ".$finish_month."
"; + if($create_date->format("Y") == $finish_year && $create_date->format("m") == $finish_month) { + $create_date->setDate($finish_year, $finish_month, $finish_day); + //echo "set last_create_date true
"; + $last_create_date = true; + } + + $existing_bill = BillingModel::getFirst(["contract_id" => $contract->id, "start_date" => $create_date->format("Y-m-d")]); + //var_dump($need_bill);exit; + if(!$existing_bill) { + //echo "adding date to create_dates[]
"; + $new_create_date = clone $create_date; + $create_dates[] = $new_create_date; + $create_date->modify("-".$contract->billing_period." months"); + continue; + } + break; + } + + //var_dump($create_dates); + // find missing billings + foreach($create_dates as $start_date) { + $price_setup = 0; + if($start_date->format("Y") == $finish_year && $start_date->format("m") == $finish_month) { + $price_setup = $contract->price_setup; + } + $create_bills[] = [ + "start_date" => $start_date, + "price_setup" => $price_setup // set Setup price to 0, because it was billed already + ]; + } + + /*$last_billings = BillingModel::count(["contract_id" => $contract->id]); + if(!$last_billings) { + // First billing + $start_date->setTime(0,0,0); + //echo "start_date: ".$start_date->format("Y-m-d H:i:s")."
"; + $create_bills[] = [ + "start_date" => $start_date, + "price_setup" => $contract->price_setup + ]; + } else { + // Concurrent Billing + // find not yet billed periods + + $create_dates = []; + + $create_date = clone $start_date; + $create_date->modify("+1 month"); + $create_date->modify("first day of this month"); + $last_create_date = false; + //echo "first create_date: ".$create_date->format("Y-m-d H:i:s")."
\n"; + //echo "while ".$create_date->getTimestamp()." (".$create_date->format("Y-m-d H:i:s").") >= ".$contract->finish_date." (".date("Y-m-d H:i:s", $contract->finish_date).")
\n"; + + while($create_date->getTimestamp() >= $contract->finish_date) { + //echo "in need date while (".$create_date->format("Y-m-d H:i:s").")
"; + if($last_create_date) { + // must for safety / shouldn't happen + die("need-date ran out of dates"); + } + + //echo "    "; + //echo $create_date->format("Y")." == ".$finish_year." && ".$create_date->format("m")." == ".$finish_month."
"; + if($create_date->format("Y") == $finish_year && $create_date->format("m") == $finish_month) { + $create_date->setDate($finish_year, $finish_month, $finish_day); + //echo "set last_create_date true
"; + $last_create_date = true; + } + + $existing_bill = BillingModel::getFirst(["contract_id" => $contract->id, "start_date" => $create_date->format("Y-m-d")]); + //var_dump($need_bill);exit; + if(!$existing_bill) { + //echo "adding date to create_dates[]
"; + $new_create_date = clone $create_date; + $create_dates[] = $new_create_date; + $create_date->modify("-".$contract->billing_period." months"); + continue; + } + break; + } + + //var_dump($create_dates); + // find missing billings + foreach($create_dates as $start_date) { + // ignore if last billing row is from this month + /*if($start_date->getTimestamp() < $earliest_next_billing_date->getTimestamp()) { + $this->log->debug(__METHOD__.": last billing row is current billing row. Skip creating new billing row"); + continue; + }*//* + $create_bills[] = [ + "start_date" => $start_date, + "price_setup" => 0 // set Setup price to 0, because it was billed already + ]; + } + }*/ + + + $create_bills = array_reverse($create_bills); + //var_dump($create_bills);exit; + foreach($create_bills as $bill_data) { + $start_date = $bill_data["start_date"]; + $price_setup = $bill_data["price_setup"]; + + // 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("first day of this month"); + $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; + //echo "days: $days
"; + $pc = $days / $eday * 100; + //echo "pc: $pc
"; + $price = round($contract->price / 100 * $pc, 4); + } else { + $price = $contract->price; + } + + /* + echo "contact ID: ".$contract->id."
"; + echo "contract price: ". $contract->price."
"; + echo "price: ". $price."
"; + echo "start_date: ".$start_date->format("Y-m-d H:i:s")."
"; + echo "sday: $sday
"; + exit; + */ + + + $owner = $contract->owner; + $billingaddress = $contract->billingaddress; + + $billing_type = "invoice"; + $billing_delivery = "paper"; + + if ($owner->billing_type) { + $billing_type = $owner->billing_type; + } + if ($owner->billing_delivery) { + $billing_delivery = $owner->billing_delivery; + } + + if ($billingaddress->billing_type) { + $billing_type = $billingaddress->billing_type; + } + if ($billingaddress->billing_delivery) { + $billing_delivery = $billingaddress->billing_delivery; + } + + $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"] = $billing_type; + $data["billing_delivery"] = $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"); + $this->redirect("Billing"); + + } +} \ No newline at end of file diff --git a/application/Billing/BillingModel.php b/application/Billing/BillingModel.php new file mode 100644 index 000000000..53f16efec --- /dev/null +++ b/application/Billing/BillingModel.php @@ -0,0 +1,398 @@ + $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, $order = false) { + //var_dump($filter);exit; + $items = []; + + if(!$order) { + $order = "id ASC"; + } + + $db = FronkDB::singleton(); + + $where = self::getSqlFilter($filter); + $sql = "SELECT * FROM Billing + WHERE $where + ORDER BY $order"; + + 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("start_date", $filter)) { + $start_date = FronkDB::singleton()->escape($filter['start_date']); + if($start_date) { + $where .= " AND Billing.start_date='$start_date'"; + } + } + + if(array_key_exists("start_date>", $filter)) { + $start_date = FronkDB::singleton()->escape($filter['start_date>']); + if($start_date) { + $where .= " AND Billing.start_date > '$start_date'"; + } + } + + if(array_key_exists("start_date<", $filter)) { + $start_date = FronkDB::singleton()->escape($filter['start_date<']); + if($start_date) { + $where .= " AND Billing.start_date < '$start_date'"; + } + } + + if(array_key_exists("start_date>=", $filter)) { + $start_date = FronkDB::singleton()->escape($filter['start_date>=']); + if($start_date) { + $where .= " AND Billing.start_date >='$start_date'"; + } + } + + if(array_key_exists("start_date<=", $filter)) { + $start_date = FronkDB::singleton()->escape($filter['start_date<=']); + if($start_date) { + $where .= " AND Billing.start_date <= '$start_date'"; + } + } + + 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("price<", $filter)) { + $price = $filter['price<']; + if(is_numeric($price)) { + $where .= " AND Billing.price < $price"; + } + } + if(array_key_exists("price<=", $filter)) { + $price = $filter['price<=']; + if(is_numeric($price)) { + $where .= " AND Billing.price <= $price"; + } + } + + if(array_key_exists("price>", $filter)) { + $price = $filter['price>']; + if(is_numeric($price)) { + $where .= " AND Billing.price > $price"; + } + } + if(array_key_exists("price>=", $filter)) { + $price = $filter['price>=']; + if(is_numeric($price)) { + $where .= " AND Billing.price >= $price"; + } + } + + if(array_key_exists("add-where", $filter)) { + $where .= " ".$filter['add-where']; + } + + + if(array_key_exists("billing_period", $filter)) { + $billing_period = $filter['billing_period']; + if(is_numeric($billing_period)) { + $where .= " AND Billing.billing_period = $billing_period"; + } + } + + //var_dump($filter, $where);exit; + return $where; + } + +} diff --git a/application/Contract/ContractModel.php b/application/Contract/ContractModel.php index 30c916861..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)) { @@ -482,7 +485,26 @@ 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("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/application/IvtCrediting/IvtCrediting.php b/application/IvtCrediting/IvtCrediting.php new file mode 100644 index 000000000..c22829826 --- /dev/null +++ b/application/IvtCrediting/IvtCrediting.php @@ -0,0 +1,34 @@ +log = mfLoghandler::singleton(); + $this->data = new stdClass(); + $this->table = "crediting"; + + $this->db = FronkDB::singleton(IVT_DBHOST, IVT_DBUSER, IVT_DBPASS, IVT_DBNAME); + + if(is_numeric($_)) { + $this->fetch($_); + } elseif(is_object($_)) { + $this->load($_); + } + } + + public function save() { + throw new Exception("Cannot save Ivt Bills"); + } + + public function __debugInfo() { + $vars = get_object_vars($this); + if(is_object($vars['db'])) $vars['db'] = "object(FronkDB)"; + if(is_object($vars['log'])) $vars['log'] = 'object(mfLoghandler)'; + return $vars; + } + +} \ No newline at end of file diff --git a/application/IvtCrediting/IvtCreditingModel.php b/application/IvtCrediting/IvtCreditingModel.php new file mode 100644 index 000000000..2d7daa311 --- /dev/null +++ b/application/IvtCrediting/IvtCreditingModel.php @@ -0,0 +1,117 @@ +select("crediting", "*", "1=1 ORDER BY id"); + if($db->num_rows($res)) { + while($data = $db->fetch_object($res)) { + $items[] = new IvtCrediting($data); + } + } + return $items; + } + + public static function getFirst($filter = []) { + $db = FronkDB::singleton(IVT_DBHOST, IVT_DBUSER, IVT_DBPASS, IVT_DBNAME); + + $where = self::getSqlFilter($filter); + $res = $db->select("crediting", "*", "$where ORDER BY id LIMIT 1"); + if($db->num_rows($res)) { + $data = $db->fetch_object($res); + $item = new IvtCrediting($data); + if($item->id) { + return $item; + } else { + return null; + } + } + return null; + } + + public static function getLast($filter = []) { + $db = FronkDB::singleton(IVT_DBHOST, IVT_DBUSER, IVT_DBPASS, IVT_DBNAME); + + $where = self::getSqlFilter($filter); + $res = $db->select("crediting", "*", "$where ORDER BY id DESC LIMIT 1"); + if($db->num_rows($res)) { + $data = $db->fetch_object($res); + $item = new IvtCrediting($data); + if($item->id) { + return $item; + } else { + return null; + } + } + return null; + } + + public static function search($filter, $limit = false) { + $items = []; + $db = FronkDB::singleton(IVT_DBHOST, IVT_DBUSER, IVT_DBPASS, IVT_DBNAME); + + $where = self::getSqlFilter($filter); + $sql = "SELECT * FROM crediting WHERE $where ORDER by id"; + + mfLoghandler::singleton()->debug($sql); + 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']; + } + } + + $res = $db->query($sql); + if($db->num_rows($res)) { + while($data = $db->fetch_object($res)) { + $items[] = new IvtCrediting($data); + } + } + return $items; + } + + private static function getSqlFilter($filter) { + $where = "1=1 "; + + if(array_key_exists("cid", $filter)) { + $cid = $filter['cid']; + if(is_numeric($cid)) { + $where .= " AND cid=$cid"; + } + } + + if(array_key_exists("date_outgoing", $filter)) { + $date_outgoing = $filter['date_outgoing']; + if($date_outgoing) { + $where .= " AND date_outgoing='$date_outgoing'"; + } + } + + if(array_key_exists("date_outgoing>", $filter)) { + $date_outgoing = $filter['date_outgoing>']; + if($date_outgoing) { + $where .= " AND date_outgoing >= '$date_outgoing'"; + } + } + + if(array_key_exists("date_outgoing<", $filter)) { + $date_outgoing = $filter['date_outgoing<']; + if($date_outgoing) { + $where .= " AND date_outgoing <= '$date_outgoing'"; + } + } + + return $where; + } + +} diff --git a/application/IvtCreditingPosition/IvtCreditingPosition.php b/application/IvtCreditingPosition/IvtCreditingPosition.php new file mode 100644 index 000000000..804d2a899 --- /dev/null +++ b/application/IvtCreditingPosition/IvtCreditingPosition.php @@ -0,0 +1,34 @@ +log = mfLoghandler::singleton(); + $this->data = new stdClass(); + $this->table = "crediting_positions"; + + $this->db = FronkDB::singleton(IVT_DBHOST, IVT_DBUSER, IVT_DBPASS, IVT_DBNAME); + + if(is_numeric($_)) { + $this->fetch($_); + } elseif(is_object($_)) { + $this->load($_); + } + } + + public function save() { + throw new Exception("Cannot save Ivt Bills"); + } + + public function __debugInfo() { + $vars = get_object_vars($this); + if(is_object($vars['db'])) $vars['db'] = "object(FronkDB)"; + if(is_object($vars['log'])) $vars['log'] = 'object(mfLoghandler)'; + return $vars; + } + +} \ No newline at end of file diff --git a/application/IvtCreditingPosition/IvtCreditingPositionModel.php b/application/IvtCreditingPosition/IvtCreditingPositionModel.php new file mode 100644 index 000000000..83faa6c8e --- /dev/null +++ b/application/IvtCreditingPosition/IvtCreditingPositionModel.php @@ -0,0 +1,96 @@ +select("crediting_positions", "*", "1=1 ORDER BY id"); + if($db->num_rows($res)) { + while($data = $db->fetch_object($res)) { + $items[] = new IvtCreditingPosition($data); + } + } + return $items; + } + + public static function getFirst($filter = []) { + $db = FronkDB::singleton(IVT_DBHOST, IVT_DBUSER, IVT_DBPASS, IVT_DBNAME); + + $where = self::getSqlFilter($filter); + $res = $db->select("crediting_positions", "*", "$where ORDER BY id LIMIT 1"); + if($db->num_rows($res)) { + $data = $db->fetch_object($res); + $item = new IvtCreditingPosition($data); + if($item->id) { + return $item; + } else { + return null; + } + } + return null; + } + + public static function getLast($filter = []) { + $db = FronkDB::singleton(IVT_DBHOST, IVT_DBUSER, IVT_DBPASS, IVT_DBNAME); + + $where = self::getSqlFilter($filter); + $res = $db->select("crediting_positions", "*", "$where ORDER BY id DESC LIMIT 1"); + if($db->num_rows($res)) { + $data = $db->fetch_object($res); + $item = new IvtCreditingPosition($data); + if($item->id) { + return $item; + } else { + return null; + } + } + return null; + } + + public static function search($filter, $limit = false) { + $items = []; + $db = FronkDB::singleton(IVT_DBHOST, IVT_DBUSER, IVT_DBPASS, IVT_DBNAME); + + $where = self::getSqlFilter($filter); + $sql = "SELECT * FROM crediting_positions WHERE $where ORDER by id"; + + mfLoghandler::singleton()->debug($sql); + 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']; + } + } + + $res = $db->query($sql); + if($db->num_rows($res)) { + while($data = $db->fetch_object($res)) { + $items[] = new IvtCreditingPosition($data); + } + } + return $items; + } + + private static function getSqlFilter($filter) { + $where = "1=1 "; + + if(array_key_exists("head_id", $filter)) { + $head_id = $filter['head_id']; + if($head_id) { + $where .= " AND head_id = '$head_id'"; + } + } + + return $where; + } + +} diff --git a/application/IvtCustomerCrediting/IvtCustomerCreditingModel.php b/application/IvtCustomerCrediting/IvtCustomerCreditingModel.php index 3189194c5..116a037ff 100644 --- a/application/IvtCustomerCrediting/IvtCustomerCreditingModel.php +++ b/application/IvtCustomerCrediting/IvtCustomerCreditingModel.php @@ -53,7 +53,7 @@ class IvtCustomerCreditingModel { $db = FronkDB::singleton(IVT_DBHOST, IVT_DBUSER, IVT_DBPASS, IVT_DBNAME); $where = self::getSqlFilter($filter); - $sql = "SELECT * FROM customer_crediting WHERE $where ORDER by cid,pid,sid,id"; + $sql = "SELECT * FROM customer_crediting WHERE $where ORDER by id"; mfLoghandler::singleton()->debug($sql); if(is_array($limit) && count($limit)) { @@ -99,6 +99,13 @@ class IvtCustomerCreditingModel { $where .= " AND cust_id=$cust_id"; } } + + if(array_key_exists("lastdate", $filter)) { + $lastdate = $filter['lastdate']; + if($lastdate) { + $where .= " AND lastdate = '$lastdate'"; + } + } //var_dump($filter, $where);exit; return $where; diff --git a/application/IvtCustomerProduct/IvtCustomerProductModel.php b/application/IvtCustomerProduct/IvtCustomerProductModel.php index 0fef4decf..539877df0 100644 --- a/application/IvtCustomerProduct/IvtCustomerProductModel.php +++ b/application/IvtCustomerProduct/IvtCustomerProductModel.php @@ -57,7 +57,7 @@ class IvtCustomerProductModel { $db = FronkDB::singleton(IVT_DBHOST, IVT_DBUSER, IVT_DBPASS, IVT_DBNAME); $where = self::getSqlFilter($filter); - $sql = "SELECT * FROM customer_product WHERE $where ORDER by cid,pid,sid,id"; + $sql = "SELECT * FROM customer_product WHERE $where ORDER by id"; mfLoghandler::singleton()->debug($sql); if(is_array($limit) && count($limit)) { @@ -102,13 +102,37 @@ class IvtCustomerProductModel { } //var_dump($filter);exit; + if(array_key_exists("lastdate", $filter)) { + $lastdate = $filter['lastdate']; + if($lastdate) { + $where .= " AND lastdate = '$lastdate'"; + } + } if(array_key_exists("lastdate>", $filter)) { $lastdate = $filter['lastdate>']; if($lastdate) { - $where .= " AND lastdate >= $lastdate"; + $where .= " AND lastdate >= '$lastdate'"; + } + } + if(array_key_exists("lastdate<", $filter)) { + $lastdate = $filter['lastdate<']; + if($lastdate) { + $where .= " AND lastdate <= '$lastdate'"; + } + } + + if(array_key_exists("createdate>", $filter)) { + $createdate = $filter['createdate>']; + if($createdate) { + $where .= " AND createdate >= '$createdate'"; + } + } + if(array_key_exists("createdate<", $filter)) { + $createdate = $filter['createdat<']; + if($createdate) { + $where .= " AND createdate <= '$createdate'"; } } - //var_dump($filter, $where);exit; return $where; } diff --git a/application/PreorderDiscount/PreorderDiscountController.php b/application/PreorderDiscount/PreorderDiscountController.php index 70c69c32f..ad9e39089 100644 --- a/application/PreorderDiscount/PreorderDiscountController.php +++ b/application/PreorderDiscount/PreorderDiscountController.php @@ -61,7 +61,7 @@ class PreorderDiscountController extends mfBaseController { continue; } - $discount_code = PreorderDiscountModel::getFirst(["code" => $code, "preorer_id" => $preorder->id]); + $discount_code = PreorderDiscountModel::getFirst(["code" => $code, "preorder_id" => $preorder->id]); if($discount_code) { $exists++; continue; 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 000000000..7eb02f36e Binary files /dev/null and b/public/assets/images/snopp-sm.png differ diff --git a/scripts/contract/test.php b/scripts/contract/test.php index 6353f66b3..2d802ce8b 100644 --- a/scripts/contract/test.php +++ b/scripts/contract/test.php @@ -13,10 +13,14 @@ require_once(LIBDIR."/mvcfronk/mfBase/mfBaseController.php"); $me = new User(1); define("INTERNAL_USER_ID", $me->id); +$finish_date_from = new DateTime("2024-05-31 22:00:00"); +$finish_date_to = new DateTime("2024-06-01 03:00:00"); +$finish_date = new DateTime("2024-06-01 02:00:00"); + $cms = 0; $cmss = 0; $cys = 0; -foreach(ContractModel::getAll() as $contract) { +foreach(ContractModel::search(["finish_date" => $finish_date->getTimestamp()]) as $contract) { if($contract->billing_period == 1 && $contract->price > 0.00000) { $cms += $contract->price; } @@ -27,20 +31,21 @@ foreach(ContractModel::getAll() as $contract) { } -$First = new DateTime("2024-05-13 00: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-12 23:59:59"); +$Last = new DateTime("2024-06-01 03:00:00"); -foreach(ContractModel::search(["billing_period" => 12]) as $contract) { +foreach(ContractModel::search(["billing_period" => 12, "finish_date" => $finish_date->getTimestamp()]) as $contract) { $fdate = new DateTime("@".$contract->finish_date); $y = $fdate->format("Y"); $m = $fdate->format("m"); $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; - } + //} } $cts = $cms + $cys + $cmss; @@ -53,11 +58,10 @@ echo "Contract Total Sum: $cts\n"; echo "======================================\n"; - $ims = 0; $iys = 0; -foreach(IvtCustomerProductModel::getAll() as $ivt_contract) { +foreach(IvtCustomerProductModel::search(["lastdate" => '2024-06-10']) as $ivt_contract) { $product = $ivt_contract->product; if($product->interval == 0) { $ims += $product->price; @@ -77,7 +81,7 @@ echo "======================================\n"; $ibs = 0; -foreach(IvtBillModel::search(['date_outgoing>' => "2024-06-01"]) as $ivt_bill) { +foreach(IvtBillModel::search(['date_outgoing' => "2024-06-10"]) as $ivt_bill) { $positions = IvtBillPositionProductModel::search(["bid" => $ivt_bill->id]); foreach($positions as $position) { $ibs += $position->price; @@ -89,4 +93,111 @@ echo "Ivt Bills Total Sum: $ibs\n"; echo "======================================\n"; $cid = $ibs - $cts; -echo "Diff thetool <-> ivt Bills: $cid\n"; +echo "Diff thetool <-> ivt Bills: ".round($cid, 4)."\n"; +echo "======================================\n"; + + +$tbms = 0; +$tbys = 0; +$tbs = 0; + +foreach(BillingModel::search(["price>=" => 0]) as $bill) { + if($bill->billing_period == 1) { + $tbms += $bill->price; + } + if($bill->billing_period == 12) { + $tbys += $bill->price; + } + if($bill->price_setup) { + $tbs += $bill->price_setup; + } +} + + +$tbts = $tbms + $tbys + $tbs; + +echo "\n"; +echo "Tool Billing Monthly Sum: $tbms\n"; +echo "Tool Billing Setup Sum: $tbs\n"; +echo "Tool Billing Yearly Sum: $tbys\n"; +echo "--------------------------------------\n"; +echo "Tool Billing Total Sum: $tbts\n"; +echo "======================================\n"; + + +$tbcms = 0; +$tbcys = 0; +$tbcs = 0; + +foreach(BillingModel::search(["price<" => 0]) as $bill) { + if($bill->billing_period == 1) { + $tbcms += $bill->price; + } + if($bill->billing_period == 12) { + $tbcys += $bill->price; + } + if($bill->price_setup) { + $tbcs += $bill->price_setup; + } +} + + +$tbcts = $tbcms + $tbcys + $tbcs; + +echo "\n"; +echo "Tool Billing Crediting Monthly Sum: $tbcms\n"; +echo "Tool Billing Crediting Setup Sum: $tbcs\n"; +echo "Tool Billing Crediting Yearly Sum: $tbcys\n"; +echo "--------------------------------------\n"; +echo "Tool Billing Crediting Total Sum: $tbcts\n"; +echo "======================================\n"; + + +$gsm = 0; +$gsy = 0; +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) { + $gsy += $contract->price; + } +} + +$gst = $gsm + $gsy; + +echo "\n\n"; +echo "Contract Credit monthly: $gsm\n"; +echo "Contract Credit yearly: $gsy\n"; +echo "--------------------------------------\n"; +echo "Contract Credit Total: $gst\n"; +echo "======================================\n"; + +$icm = 0; +foreach(IvtCustomerCreditingModel::search(['lastdate' => '2024-06-10']) as $ivt_credit) { + $product = $ivt_credit->crediting_product; + $icm += $product->price_excl; +} + +$icm *= -1; + +echo "IVT Credit Total: $icm\n"; +echo "======================================\n"; + +$icbs = 0; + +foreach(IvtCreditingModel::search(["date_outgoing" => "2024-06-10"]) as $ivt_credit) { + foreach(IvtCreditingPositionModel::search(["head_id" => $ivt_credit->id]) as $position) { + $icbs += $position->price_excl; + } +} + +$icbs *= -1; + +$cred_diff = $icbs - ($gsm + $gsy); + +echo "IVT Credit Bill Total: $icbs\n"; +echo "======================================\n"; + +echo "\n"; +echo "Credit Diff thetool <-> ivt: ".round($cred_diff, 4)."\n"; +echo "======================================\n"; \ No newline at end of file