update 20.10.2025
This commit is contained in:
parent
8c11130b5d
commit
a939cd51ef
616 changed files with 84821 additions and 4121 deletions
158
dev/app-bak/Services/AboHelper.php
Normal file
158
dev/app-bak/Services/AboHelper.php
Normal file
|
|
@ -0,0 +1,158 @@
|
|||
<?php
|
||||
namespace App\Services;
|
||||
|
||||
use App\Models\Product;
|
||||
use Yard;
|
||||
use App\User;
|
||||
use Carbon\Carbon;
|
||||
use App\Models\UserAbo;
|
||||
use App\Models\UserAboItem;
|
||||
use App\Models\UserAboOrder;
|
||||
use App\Models\ShoppingOrder;
|
||||
use App\Models\ShoppingPayment;
|
||||
use App\Models\ShoppingUser;
|
||||
|
||||
class AboHelper
|
||||
{
|
||||
|
||||
|
||||
public static $txaction_filter_text = [
|
||||
'paid' => 'paymend_paid',
|
||||
'appointed' => 'paymend_open',
|
||||
'failed' => 'paymend_failed',
|
||||
'extern' => 'extern_open', //offen
|
||||
'extern_paid' => 'extern_paid',
|
||||
'invoice_open' => 'invoice_open',
|
||||
'invoice_paid' => 'invoice_paid',
|
||||
'invoice_non' => 'invoice_no_payment',
|
||||
'NULL' => 'no_payment',
|
||||
];
|
||||
|
||||
|
||||
public static function userHasAbo(User $user){
|
||||
$user = $user ? $user : \Auth::user();
|
||||
return UserAbo::where('user_id', $user->id)->where('is_for', 'me')->where('status', '>', 1)->first() === null ? false : true;
|
||||
}
|
||||
|
||||
public static function memberHasAbo(ShoppingUser $shopping_user){
|
||||
if(!$shopping_user){
|
||||
return false;
|
||||
}
|
||||
return UserAbo::where('email', $shopping_user->billing_email)->where('is_for', 'ot')->where('status', '>', 1)->first() === null ? false : true;
|
||||
}
|
||||
|
||||
public static function hasAboByEmail($email){
|
||||
return UserAbo::where('email', $email)->where('status', '>', 1)->first() === null ? false : true;
|
||||
}
|
||||
|
||||
public static function setAboStatus(ShoppingOrder $shopping_order, $status){
|
||||
$user_abo = $shopping_order->getUserAbo();
|
||||
if($user_abo && $user_abo->status < 2){ //status < 2 is not active
|
||||
$user_abo->update(['status' => $status]);
|
||||
}
|
||||
UserAboOrder::where('user_abo_id', $user_abo->id)->where('shopping_order_id', $shopping_order->id)->update(['status' => $status]);
|
||||
}
|
||||
public static function setAboActive(ShoppingOrder $shopping_order, $status){
|
||||
self::setAboStatus($shopping_order, $status);
|
||||
|
||||
//delete UserAbo is not active status = 1
|
||||
//is_for = me
|
||||
UserAbo::where('user_id', $shopping_order->auth_user_id)->where('is_for', 'me')->where('status', 1)->delete();
|
||||
//is_for = ot
|
||||
UserAbo::where('member_id', $shopping_order->member_id)->where('email', $shopping_order->shopping_user->billing_email)->where('is_for', 'ot')->where('status', 1)->delete();
|
||||
|
||||
}
|
||||
|
||||
public static function aboHasBaseProduct($yard_products){
|
||||
foreach($yard_products as $product){
|
||||
if(is_array($product->options->show_on)){
|
||||
if(in_array('12', $product->options->show_on)){
|
||||
return true;
|
||||
}
|
||||
}
|
||||
}
|
||||
return false;
|
||||
}
|
||||
public static function getAboShowOn(Product $product){
|
||||
$show_on = $product->show_on;
|
||||
if(in_array('12', $show_on)){
|
||||
return 'base';
|
||||
}
|
||||
if(in_array('13', $show_on)){
|
||||
return 'upgrade';
|
||||
}
|
||||
return false;
|
||||
}
|
||||
public static function getAboTypeBadge($abo_type){
|
||||
if($abo_type === 'base'){
|
||||
return '<span class="badge badge-pill badge-warning"><i class="fas fa-star"></i> '.__('abo.'.$abo_type).'</span></a>';
|
||||
}
|
||||
if($abo_type === 'upgrade'){
|
||||
return '<span class="badge badge-pill badge-info"><i class="far fa-star"></i> '.__('abo.'.$abo_type).'</span></a>';
|
||||
}
|
||||
return '';
|
||||
}
|
||||
|
||||
public static function setNextDate($date, $abo_interval){
|
||||
$nextDate = Carbon::parse($date)->firstOfMonth();
|
||||
$nextDate->addDays($abo_interval-1);
|
||||
return $nextDate->gt($date) ? $nextDate : $nextDate->addMonth(1);
|
||||
}
|
||||
|
||||
public static function createNewAbo(ShoppingPayment $shopping_payment){
|
||||
//is Abo - create init Abo from PP or else
|
||||
if($shopping_payment->shopping_order->is_abo && $shopping_payment->shopping_order->abo_interval > 0){
|
||||
$payment_transaction = $shopping_payment->payment_transactions->last();
|
||||
|
||||
$user_abo = UserAbo::create([
|
||||
'user_id' => $shopping_payment->shopping_order->auth_user_id,
|
||||
'member_id' => $shopping_payment->shopping_order->member_id,
|
||||
'shopping_user_id' => $shopping_payment->shopping_order->shopping_user_id,
|
||||
'email' => $shopping_payment->shopping_order->shopping_user->billing_email,
|
||||
'is_for' => $shopping_payment->shopping_order->shopping_user->is_for,
|
||||
'payone_userid' => $payment_transaction->userid,
|
||||
'clearingtype' => $shopping_payment->clearingtype,
|
||||
'wallettype' => $shopping_payment->wallettype,
|
||||
'carddata' => $shopping_payment->carddata,
|
||||
'amount' => $shopping_payment->amount,
|
||||
'status' => 1,
|
||||
'abo_interval' => $shopping_payment->abo_interval,
|
||||
'start_date' => now(),
|
||||
'last_date' => now(),
|
||||
'next_date' => self::setNextDate(now(), $shopping_payment->abo_interval),
|
||||
]);
|
||||
|
||||
if($user_abo){
|
||||
self::createAboItems($user_abo, $shopping_payment);
|
||||
UserAboOrder::create([
|
||||
'user_abo_id' => $user_abo->id,
|
||||
'shopping_order_id' => $shopping_payment->shopping_order_id,
|
||||
'status' => 1,
|
||||
]);
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
public static function createAboItems($user_abo, ShoppingPayment $shopping_payment){
|
||||
foreach($shopping_payment->shopping_order->shopping_order_items as $item){
|
||||
UserAboItem::create([
|
||||
'user_abo_id' => $user_abo->id,
|
||||
'product_id' => $item->product_id,
|
||||
'comp' => $item->comp ?? 0,
|
||||
'qty' => $item->qty,
|
||||
'status' => 1,
|
||||
]);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
public static function getTransStatusFilterText(){
|
||||
$ret = [];
|
||||
foreach(self::$txaction_filter_text as $key=>$val){
|
||||
$ret[$key] = trans('payment.'.$val);
|
||||
}
|
||||
return $ret;
|
||||
}
|
||||
|
||||
}
|
||||
201
dev/app-bak/Services/AboOrderCart.php
Normal file
201
dev/app-bak/Services/AboOrderCart.php
Normal file
|
|
@ -0,0 +1,201 @@
|
|||
<?php
|
||||
namespace App\Services;
|
||||
|
||||
use Yard;
|
||||
use App\User;
|
||||
use Carbon\Carbon;
|
||||
use App\Models\Product;
|
||||
use App\Models\UserAbo;
|
||||
use App\Models\UserAboItem;
|
||||
use App\Models\ShoppingUser;
|
||||
use App\Models\UserAboOrder;
|
||||
use App\Models\ShoppingOrder;
|
||||
use App\Models\ShippingCountry;
|
||||
use App\Models\ShoppingPayment;
|
||||
|
||||
class AboOrderCart
|
||||
{
|
||||
private static $user_abo;
|
||||
private static $is_for;
|
||||
private static $customer_detail;
|
||||
|
||||
|
||||
public static function initYard($user_abo){
|
||||
|
||||
self::$user_abo = $user_abo;
|
||||
Yard::instance('shopping')->destroy();
|
||||
self::$customer_detail = self::makeCustomerDetail($user_abo);
|
||||
if($user_abo->is_for === 'me'){
|
||||
self::$is_for = 'abo-me';
|
||||
if($user_abo->user && $user_abo->user->account->same_as_billing){
|
||||
$country_id = $user_abo->user->account->country_id;
|
||||
}else{
|
||||
$country_id = $user_abo->user->account->shipping_country_id;
|
||||
}
|
||||
if($country_id && $shipping_country = ShippingCountry::whereCountryId($country_id)->first()){
|
||||
if($shipping_country->shipping && $shipping_country->shipping->active){
|
||||
UserService::initUserYard($user_abo->user, $shipping_country->id, 'abo-me');
|
||||
return true;
|
||||
}
|
||||
}
|
||||
abort(403, 'Fehler: Versandland nicht gefunden');
|
||||
}
|
||||
if($user_abo->is_for === 'ot'){
|
||||
self::$is_for = 'abo-ot-customer';
|
||||
UserService::initCustomerYard(self::$customer_detail, 'abo-ot-customer');
|
||||
return true;
|
||||
|
||||
}
|
||||
|
||||
return false;
|
||||
|
||||
}
|
||||
|
||||
public static function makeOrderYard($user_abo)
|
||||
{
|
||||
self::$user_abo = $user_abo;
|
||||
if($user_abo->is_for === 'ot'){
|
||||
self::$is_for = 'abo-ot-customer';
|
||||
}
|
||||
if($user_abo->is_for === 'me'){
|
||||
self::$is_for = 'abo-me';
|
||||
}
|
||||
foreach($user_abo->user_abo_items as $abo_item){
|
||||
self::addProductToCart($abo_item);
|
||||
}
|
||||
Yard::instance('shopping')->reCalculateShippingPrice();
|
||||
|
||||
$user_abo->amount = Yard::instance('shopping')->totalWithShipping(2, '.', '')*100;
|
||||
$user_abo->save();
|
||||
}
|
||||
|
||||
private static function addProductToCart($item){
|
||||
|
||||
$product = Product::find($item->product_id);
|
||||
$tax_free = Yard::instance('shopping')->getUserTaxFree();
|
||||
$user_country = Yard::instance('shopping')->getUserCountry();
|
||||
|
||||
if($product){
|
||||
if($item->comp){
|
||||
$cartItem = Yard::instance('shopping')->add($product->id, $product->getLang('name'), 1, 0, false, false,
|
||||
['image' => '', 'slug' => $product->slug, 'weight' => 0, 'points' => 0,
|
||||
'comp' => $item->comp, 'product_id' => $product->id]);
|
||||
Yard::setTax($cartItem->rowId, 0);
|
||||
return true;
|
||||
}
|
||||
if(self::$is_for === 'ot-customer' || self::$is_for === 'abo-ot-customer'){
|
||||
$cartItem = Yard::instance('shopping')
|
||||
->add($product->id, $product->getLang('name'), $item->qty,
|
||||
round($product->getPriceWith($tax_free, false, $user_country, false, self::$user_abo->user), 1), false, false,
|
||||
['image' => '', 'slug' => $product->slug, 'weight' => $product->weight, 'points' => $product->points, 'no_commission' => $product->no_commission, 'show_on' => $product->show_on]);
|
||||
}else{
|
||||
$cartItem = Yard::instance('shopping')
|
||||
->add($product->id, $product->getLang('name'), $item->qty,
|
||||
$product->getPriceWith($tax_free, true, $user_country, false, self::$user_abo->user), false, false,
|
||||
['image' => '', 'slug' => $product->slug, 'weight' => $product->weight, 'points' => $product->points, 'no_commission' => $product->no_commission, 'show_on' => $product->show_on]);
|
||||
}
|
||||
if($tax_free){
|
||||
Yard::setTax($cartItem->rowId, 0);
|
||||
}else{
|
||||
Yard::setTax($cartItem->rowId, $product->getTaxWith($user_country));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public static function checkNumOfCompProducts($user_abo){
|
||||
|
||||
if($user_abo->is_for === 'me'){
|
||||
$needNumComp = Yard::instance('shopping')->getNumComp();
|
||||
if($needNumComp > 0){
|
||||
$UserAboItems = UserAboItem::where('user_abo_id', $user_abo->id)->where('comp', '>', 0)->get();
|
||||
if(count($UserAboItems) === $needNumComp){
|
||||
return true;
|
||||
}
|
||||
|
||||
//need to add
|
||||
if(count($UserAboItems) < $needNumComp){
|
||||
$product = Product::whereActive(true)->where('shipping_addon', true)->whereJsonContains('show_on', '12')->orderBy('pos', 'DESC')->first();
|
||||
for($i = count($UserAboItems); $i <= $needNumComp; $i++){
|
||||
$UserAboItem = UserAboItem::create([
|
||||
'user_abo_id' => $user_abo->id,
|
||||
'product_id' => $product->id,
|
||||
'comp' => $i + 1,
|
||||
'qty' => 1,
|
||||
'status' => 1,
|
||||
]);
|
||||
self::addProductToCart($UserAboItem);
|
||||
}
|
||||
}
|
||||
//need to remove
|
||||
if(count($UserAboItems) > $needNumComp){
|
||||
foreach($UserAboItems as $UserAboItem){
|
||||
if($UserAboItem->comp > $needNumComp){
|
||||
$UserAboItem->delete();
|
||||
}
|
||||
}
|
||||
foreach (Yard::instance('shopping')->content() as $row) {
|
||||
if($row->options->comp > $needNumComp) {
|
||||
Yard::instance('shopping')->remove($row->rowId);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public static function getCustomerDetail(){
|
||||
return self::$customer_detail;
|
||||
}
|
||||
|
||||
/* Need this, can change the address */
|
||||
public static function makeCustomerDetail($user_abo){
|
||||
|
||||
if($user_abo->is_for === 'me'){
|
||||
//only on Abo!
|
||||
$user = $user_abo->user;
|
||||
$shopping_user = new ShoppingUser();
|
||||
$shopping_user->billing_salutation = $user->account->salutation;
|
||||
$shopping_user->billing_company = $user->account->company;
|
||||
$shopping_user->billing_firstname = $user->account->first_name;
|
||||
$shopping_user->billing_lastname = $user->account->last_name;
|
||||
$shopping_user->billing_address = $user->account->address;
|
||||
$shopping_user->billing_address_2 = $user->account->address_2;
|
||||
$shopping_user->billing_zipcode = $user->account->zipcode;
|
||||
$shopping_user->billing_city = $user->account->city;
|
||||
$shopping_user->billing_country_id = $user->account->country_id;
|
||||
$shopping_user->billing_phone = $user->account->phone;
|
||||
|
||||
if($user->account->same_as_billing){
|
||||
$shopping_user->shipping_salutation = $user->account->salutation;
|
||||
$shopping_user->shipping_company = $user->account->company;
|
||||
$shopping_user->shipping_firstname = $user->account->first_name;
|
||||
$shopping_user->shipping_lastname = $user->account->last_name;
|
||||
$shopping_user->shipping_address = $user->account->address;
|
||||
$shopping_user->shipping_address_2 = $user->account->address_2;
|
||||
$shopping_user->shipping_zipcode = $user->account->zipcode;
|
||||
$shopping_user->shipping_city = $user->account->city;
|
||||
$shopping_user->shipping_country_id = $user->account->country_id;
|
||||
$shopping_user->shipping_phone = $user->account->phone;
|
||||
}else{
|
||||
$shopping_user->shipping_salutation = $user->account->shipping_salutation;
|
||||
$shopping_user->shipping_company = $user->account->shipping_company;
|
||||
$shopping_user->shipping_firstname = $user->account->shipping_firstname;
|
||||
$shopping_user->shipping_lastname = $user->account->shipping_lastname;
|
||||
$shopping_user->shipping_address = $user->account->shipping_address;
|
||||
$shopping_user->shipping_address_2 = $user->account->shipping_address_2;
|
||||
$shopping_user->shipping_zipcode = $user->account->shipping_zipcode;
|
||||
$shopping_user->shipping_city = $user->account->shipping_city;
|
||||
$shopping_user->shipping_country_id = $user->account->shipping_country_id;
|
||||
$shopping_user->shipping_phone = $user->account->shipping_phone;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
if($user_abo->is_for === 'ot'){
|
||||
//look for the primary user of this abo
|
||||
$shopping_user = $user_abo->shopping_user->replicate();
|
||||
}
|
||||
return $shopping_user;
|
||||
}
|
||||
|
||||
}
|
||||
405
dev/app-bak/Services/BusinessPlan/BusinessUserItem.php
Normal file
405
dev/app-bak/Services/BusinessPlan/BusinessUserItem.php
Normal file
|
|
@ -0,0 +1,405 @@
|
|||
<?php
|
||||
namespace App\Services\BusinessPlan;
|
||||
|
||||
use App\User;
|
||||
use stdClass;
|
||||
use Carbon\Carbon;
|
||||
use App\Models\UserLevel;
|
||||
use App\Models\UserBusiness;
|
||||
use App\Services\TranslationHelper;
|
||||
use App\Models\UserBusinessStructure;
|
||||
|
||||
|
||||
class BusinessUserItem
|
||||
{
|
||||
public $businessUserItems = [];
|
||||
|
||||
private $date;
|
||||
private $b_user;
|
||||
private $user_level_active_pos;
|
||||
|
||||
|
||||
|
||||
public function __construct($date)
|
||||
{
|
||||
$this->date = $date;
|
||||
return $this;
|
||||
}
|
||||
|
||||
public function makeUser($user_id){
|
||||
|
||||
//check for user an load is saved
|
||||
$this->b_user = UserBusiness::where('user_id', $user_id)->where('month', $this->date->month)->where('year', $this->date->year)->first();
|
||||
if($this->b_user !== null){
|
||||
return;
|
||||
}
|
||||
//read User here, can delete in stored data.
|
||||
$user = User::find($user_id);
|
||||
if(!$user){
|
||||
return;
|
||||
}
|
||||
$user_level_active = $user->user_level ? $user->user_level : null;
|
||||
$this->user_level_active_pos = $user_level_active ? $user_level_active->pos : 0;
|
||||
$this->b_user = new UserBusiness();
|
||||
$fill = [
|
||||
'user_id' => $user->id,
|
||||
'month' => $this->date->month,
|
||||
'year' => $this->date->year,
|
||||
'm_level_id' => $user->m_level,
|
||||
'user_level_name' => $user_level_active ? $user_level_active->name : '',
|
||||
'active_account' => $user->payment_account ? Carbon::parse($user->payment_account)->gt(Carbon::parse($this->date->start_date)) : false,
|
||||
'payment_account_date' => $user->payment_account ? $user->getPaymentAccountDateFormat(false) : NULL,
|
||||
'active_date' => $user->active_date ? $user->active_date : NULL,
|
||||
'm_account' => $user->account->m_account,
|
||||
'email' => $user->email,
|
||||
'first_name' => $user->account->first_name,
|
||||
'last_name' => $user->account->last_name,
|
||||
'user_birthday' => $user->account->birthday,
|
||||
'user_phone' => $user->account->getPhoneNumber(),
|
||||
|
||||
'sales_volume_KP_points' => $user->getUserSalesVolumeBy($this->date->month, $this->date->year, 'sales_volume_KP_points'),
|
||||
'sales_volume_TP_points' => $user->getUserSalesVolumeBy($this->date->month, $this->date->year, 'sales_volume_TP_points'),
|
||||
'sales_volume_points_shop' => $user->getUserSalesVolumeBy($this->date->month, $this->date->year, 'sales_volume_points_shop'),
|
||||
|
||||
'sales_volume_points_KP_sum' => $user->getUserSalesVolumeBy($this->date->month, $this->date->year, 'sales_volume_points_KP_sum'), //KP + Shop Points
|
||||
'sales_volume_points_TP_sum' => $user->getUserSalesVolumeBy($this->date->month, $this->date->year, 'sales_volume_points_TP_sum'), //TP + Shop Points
|
||||
|
||||
'sales_volume_total' => $user->getUserSalesVolumeBy($this->date->month, $this->date->year, 'sales_volume_total'),
|
||||
'sales_volume_total_shop' => $user->getUserSalesVolumeBy($this->date->month, $this->date->year, 'sales_volume_total_shop'),
|
||||
'sales_volume_total_sum' => $user->getUserSalesVolumeBy($this->date->month, $this->date->year, 'sales_volume_total_sum'),
|
||||
|
||||
'margin' => $user_level_active ? $user_level_active->margin : 0, //is fix Rabatt für Kundenbestellungen
|
||||
'margin_shop' => $user_level_active ? $user_level_active->margin_shop : 0, //is fix Rabatt für Shopbestellungen
|
||||
'qual_kp' => $user_level_active ? $user_level_active->qual_kp : 0, //KP Kundenpoints from level
|
||||
'qual_pp' => $user_level_active ? $user_level_active->qual_pp : 0, //PP Payline Points from level
|
||||
|
||||
'payline_points' => 0,
|
||||
'commission_pp_total' => 0,
|
||||
'commission_shop_sales' => 0,
|
||||
'commission_growth_total' => 0,
|
||||
'version' => 2,
|
||||
];
|
||||
$this->b_user->fill($fill);
|
||||
$this->b_user->business_lines = [];
|
||||
$this->b_user->user_items = [];
|
||||
$this->b_user->commission_shop_sales = round($this->b_user->sales_volume_total_shop / 100 * $this->b_user->margin_shop, 2);
|
||||
|
||||
}
|
||||
|
||||
|
||||
public function getSalesVolumeTotalMargin(){
|
||||
return $this->b_user->getSalesVolumeTotalMargin();
|
||||
}
|
||||
|
||||
public function addUserID(){
|
||||
TreeCalcBot::addUserID($this->b_user->user_id);
|
||||
}
|
||||
|
||||
public function getBUser(){
|
||||
return $this->b_user;
|
||||
}
|
||||
|
||||
public function addBusinessLineToUser($line, $obj){
|
||||
$this->b_user->business_lines[$line] = $obj;
|
||||
}
|
||||
|
||||
public function addBusinessLinePoints($line, $points){
|
||||
$obj = $this->business_lines[$line];
|
||||
$obj->points += $points;
|
||||
$this->b_user->business_lines[$line] = $obj;
|
||||
}
|
||||
|
||||
public function addTotalTP($points){
|
||||
$this->b_user->total_pp += $points;
|
||||
}
|
||||
|
||||
public function isQualKP(){
|
||||
return ($this->sales_volume_points_KP_sum >= $this->qual_kp) ? true : false;
|
||||
}
|
||||
|
||||
public function isQualLevel(){
|
||||
return ($this->qual_user_level) ? true : false;
|
||||
}
|
||||
|
||||
public function isQualEqualLevel(){
|
||||
if($this->qual_user_level){
|
||||
return ($this->m_level_id == $this->qual_user_level['id']) ? true : false;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
public function getQualLevelPaylines(){
|
||||
if($this->qual_user_level){
|
||||
return $this->qual_user_level['paylines'];
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
public function isQualLevelGrowth($line){
|
||||
if(isset($this->business_lines[$line])){
|
||||
$object = $this->business_lines[$line];
|
||||
if(isset($object->growth_bonus)){
|
||||
return true;
|
||||
}
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
|
||||
public function getRestQualKP(){
|
||||
$ret = $this->sales_volume_points_KP_sum - $this->qual_kp;
|
||||
return $ret > 0 ? $ret : 0;
|
||||
}
|
||||
|
||||
public function getCommissionTotal(){
|
||||
return round($this->commission_shop_sales + $this->commission_pp_total + $this->commission_growth_total, 2);
|
||||
}
|
||||
//Provisierungslevel brechnen, Berechnung der Provisionen nach Level
|
||||
public function calcQualPP(){
|
||||
|
||||
//das ist der erreichte Provisierungslevel, nach paylinePoints und KP
|
||||
$qualUserLevel = $this->calcuQualLevel();
|
||||
if($qualUserLevel !== NULL){
|
||||
//prüfe einen Aufsieg im KarriereLevel
|
||||
$this->setNextUserLevel();
|
||||
$this->b_user->qual_user_level = $qualUserLevel->toArray();
|
||||
//setzen nächsten ProvisionsLevel wenn not isQualEqualLevel
|
||||
$this->setQualNextLevel();
|
||||
//Berechnung der Provisionen in der Payline
|
||||
$commission_pp_total = 0;
|
||||
$commission_growth_total = 0;
|
||||
for ($i=1; $i <= $qualUserLevel->paylines ; $i++) {
|
||||
if(isset($this->business_lines[$i])){
|
||||
$object = $this->business_lines[$i];
|
||||
$object->margin = $this->qual_user_level['pr_line_'.$i]; //provision in %
|
||||
$object->commission = round($object->points / 100 * $object->margin, 2); //provision in points/euro
|
||||
$object->payline = true;
|
||||
$commission_pp_total += $object->commission;
|
||||
$this->b_user->business_lines[$i] = $object;
|
||||
}
|
||||
}
|
||||
//Berechnung der Provisionen nach WB
|
||||
if($qualUserLevel->growth_bonus){
|
||||
//['growth_bonus'] //
|
||||
$payline = (int) $this->b_user->qual_user_level['paylines'] + 1;
|
||||
$maxlines = count($this->business_lines) + 1;
|
||||
$growth_bonus = (float) $this->b_user->qual_user_level['growth_bonus'];
|
||||
|
||||
for ($i=$payline; $i <= $maxlines ; $i++) {
|
||||
if(isset($this->business_lines[$i])){
|
||||
$object = $this->business_lines[$i];
|
||||
$object->margin = $growth_bonus; //provision in %
|
||||
$object->commission = round($object->points / 100 * $object->margin, 2); //provision in points/euro
|
||||
$object->growth_bonus = true;
|
||||
$commission_growth_total += $object->commission;
|
||||
$this->b_user->business_lines[$i] = $object;
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
$this->b_user->commission_pp_total = $commission_pp_total;
|
||||
$this->b_user->commission_growth_total = $commission_growth_total;
|
||||
|
||||
}else{
|
||||
//erste Provisierungslevel als next setzen, hat keine oder wenig points
|
||||
$qualUserLevelNext = UserLevel::where('pos', '=', 1)->orderBy('qual_pp', 'asc')->first();
|
||||
if($qualUserLevelNext){
|
||||
$this->b_user->qual_user_level_next = $qualUserLevelNext->toArray();
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
|
||||
//qualifikation nach qual_kp (KundenPoints) und qual_pp (PaylinePoints)
|
||||
public function calcuQualLevel(){
|
||||
//alle levels wo die qual_kp erreicht ist, sortiert nach Rang >
|
||||
$qualUserLevels = UserLevel::where('qual_kp', '<=', $this->sales_volume_points_KP_sum)->where('pos', '<=', $this->user_level_active_pos)->orderBy('qual_pp', 'desc')->get();
|
||||
foreach($qualUserLevels as $qualUserLevel){
|
||||
//brechnet die Points nach der Payline
|
||||
$payline_points = $this->getPointsforPayline($qualUserLevel->paylines);
|
||||
$payline_points_qual_kp = $payline_points + $this->getRestQualKP();
|
||||
if($payline_points_qual_kp >= $qualUserLevel->qual_pp){
|
||||
//match payline_points erreicht, ist der akutelle Level für die Provision
|
||||
$this->b_user->payline_points = $payline_points;
|
||||
$this->b_user->payline_points_qual_kp = $payline_points_qual_kp;
|
||||
|
||||
return $qualUserLevel;
|
||||
}
|
||||
}
|
||||
return NULL;
|
||||
}
|
||||
|
||||
|
||||
// PaylinePoints nach paylines / welche ebenen gezählt werden, 3,4,5,6 ...
|
||||
private function getPointsforPayline($paylines){
|
||||
$payline_points = 0;
|
||||
for ($i=1; $i <= $paylines ; $i++) {
|
||||
if(isset($this->business_lines[$i])){
|
||||
$payline_points += $this->business_lines[$i]->points;
|
||||
}
|
||||
}
|
||||
return $payline_points;
|
||||
}
|
||||
//wenn nicht erreicht, was wäre der nächste Provisionslevel?
|
||||
private function setQualNextLevel(){
|
||||
if(!$this->isQualEqualLevel()){
|
||||
$qualUserLevelNext = UserLevel::where('id', '=', $this->b_user->qual_user_level['next_id'])->orderBy('qual_pp', 'asc')->first();
|
||||
if($qualUserLevelNext){
|
||||
$this->b_user->qual_user_level_next = $qualUserLevelNext->toArray();
|
||||
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private function setNextUserLevel(){
|
||||
// $this->b_user->payline_points_qual_kp // das sind die Payline Points + Rest KP
|
||||
//$this->b_user->total_qual_pp = $this->total_pp + $this->getRestQualKP(); //hier werden alle Linien TP gezähle
|
||||
//$this->b_user->total_qual_pp = $this->total_pp + $this->getRestQualKP(); //hier werden alle Linien TP gezähle
|
||||
|
||||
$nextQualUserLevel = UserLevel::where('qual_pp', '<=', $this->payline_points_qual_kp)->where('pos', '>', $this->user_level_active_pos)->orderBy('qual_pp', 'desc')->first();
|
||||
if($nextQualUserLevel && $this->isQualKP()){
|
||||
$this->b_user->next_qual_user_level = $nextQualUserLevel->toArray();
|
||||
}else{
|
||||
//wenn nicht erreicht, was wäre der nächste Karrierelevel?
|
||||
$nextCanUserLevel = UserLevel::where('pos', '>', $this->user_level_active_pos)->orderBy('qual_pp', 'asc')->first();
|
||||
if($nextCanUserLevel){
|
||||
$this->b_user->next_can_user_level = $nextCanUserLevel->toArray();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/*public function storeUser(){
|
||||
$this->b_user->user_items = $this->storeUserItems($this->businessUserItems, 1);
|
||||
$this->b_user->save();
|
||||
}
|
||||
|
||||
private function storeUserItems($userItems, $line){
|
||||
$ret = [];
|
||||
foreach($userItems as $userItem){
|
||||
$temp = null;
|
||||
if(count($userItem->businessUserItems) > 0){
|
||||
$temp = $this->storeUserItems($userItem->businessUserItems, $line+1);
|
||||
}
|
||||
$obj = new stdClass();
|
||||
$obj->user_id = $userItem->user_id;
|
||||
$obj->line = $line;
|
||||
$obj->points = $userItem->sales_volume_points_sum;
|
||||
$obj->parents = $temp;
|
||||
$ret[] = $obj;
|
||||
}
|
||||
return $ret;
|
||||
}*/
|
||||
|
||||
public function readParentsBusinessUsers(){
|
||||
|
||||
$users = User::with('account')->select('users.*')
|
||||
->where('users.deleted_at', '=', null)
|
||||
->where('users.id', '!=', 1)
|
||||
->where('users.admin', "<", 4)
|
||||
->where('users.m_level', "!=", null)
|
||||
->where('users.m_sponsor', "=", $this->b_user->user_id) //<- need the id for parents / sponsors
|
||||
->where('users.payment_account', "!=", null)
|
||||
->where('users.active_date', "<=", $this->date->end_date) // wurde in dem Monat freigeschaltet
|
||||
->get();
|
||||
|
||||
if($users){
|
||||
foreach($users as $user){
|
||||
$BusinessUserItem = new BusinessUserItem($this->date);
|
||||
$BusinessUserItem->makeUser($user->id);
|
||||
$BusinessUserItem->addUserID();
|
||||
$this->businessUserItems[] = $BusinessUserItem;
|
||||
}
|
||||
}
|
||||
foreach($this->businessUserItems as $businessUserItem){
|
||||
$businessUserItem->readParentsBusinessUsers();
|
||||
}
|
||||
}
|
||||
|
||||
public function readStoredParentsBusinessUsers($structure){
|
||||
|
||||
$parents = $this->findParentsBusinessOnStored($this->b_user->user_id, $structure);
|
||||
if($parents){
|
||||
foreach($parents as $obj){
|
||||
$BusinessUserItem = new BusinessUserItem($this->date);
|
||||
$BusinessUserItem->makeUser($obj->user_id);
|
||||
$BusinessUserItem->addUserID();
|
||||
$this->businessUserItems[] = $BusinessUserItem;
|
||||
}
|
||||
foreach($this->businessUserItems as $businessUserItem){
|
||||
$businessUserItem->readStoredParentsBusinessUsers($parents);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private function findParentsBusinessOnStored($user_id, $structures){
|
||||
if($structures){
|
||||
foreach($structures as $obj){
|
||||
if($user_id === $obj->user_id){
|
||||
return $obj->parents;
|
||||
}
|
||||
if($obj->parents){
|
||||
if($ret = $this->findParentsBusinessOnStored($user_id, $obj->parents)){
|
||||
return $ret;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
public function checkSponsor($user){
|
||||
|
||||
//check is store? has ID
|
||||
if($this->b_user->isSave()){
|
||||
return;
|
||||
}
|
||||
$sponsor = new stdClass();
|
||||
|
||||
$sponsor->is_sponsor = false;
|
||||
$sponsor->user_id = false;
|
||||
$sponsor->first_name = '';
|
||||
$sponsor->last_name = '';
|
||||
$sponsor->email = '';
|
||||
$sponsor->m_account = '';
|
||||
$sponsor->full_name = 'Keinen Sponsor zugewiesen';
|
||||
|
||||
if($user->m_sponsor){
|
||||
|
||||
if($user->user_sponsor){
|
||||
$sponsor->is_sponsor = true;
|
||||
$sponsor->user_id = $user->user_sponsor->id;
|
||||
if($user->user_sponsor->account){
|
||||
$sponsor->full_name = substr('Sponsor: '.$user->user_sponsor->account->first_name.' '.$user->user_sponsor->account->last_name.' | '.$user->user_sponsor->email.' | '.$user->user_sponsor->account->m_account, 0, 250);
|
||||
$sponsor->first_name = $user->user_sponsor->account->last_name;
|
||||
$sponsor->last_name = $user->user_sponsor->account->first_name;
|
||||
$sponsor->m_account = $user->user_sponsor->account->m_account;
|
||||
}else{
|
||||
$sponsor->full_name = 'Sponsor: '.$user->user_sponsor->email;
|
||||
}
|
||||
$sponsor->email = $user->user_sponsor->email;
|
||||
}else{
|
||||
$sponsor->full_name = 'Sponsor wurde gelöscht.';
|
||||
}
|
||||
}
|
||||
$this->b_user->sponsor = $sponsor;
|
||||
return;
|
||||
}
|
||||
|
||||
public function isSave(){
|
||||
return $this->b_user->isSave();
|
||||
}
|
||||
|
||||
public function __get($property) {
|
||||
if($this->b_user === null){
|
||||
return null;
|
||||
}
|
||||
if (property_exists($this->b_user, $property)) {
|
||||
return $this->b_user->$property;
|
||||
}
|
||||
if (isset($this->b_user->{$property})) {
|
||||
return $this->b_user->{$property};
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
947
dev/app-bak/Services/BusinessPlan/BusinessUserItemOptimized.php
Normal file
947
dev/app-bak/Services/BusinessPlan/BusinessUserItemOptimized.php
Normal file
|
|
@ -0,0 +1,947 @@
|
|||
<?php
|
||||
|
||||
namespace App\Services\BusinessPlan;
|
||||
|
||||
use App\User;
|
||||
use stdClass;
|
||||
use Carbon\Carbon;
|
||||
use App\Models\UserLevel;
|
||||
use App\Models\UserBusiness;
|
||||
use App\Models\UserAccount;
|
||||
use App\Models\UserSalesVolume;
|
||||
use App\Services\TranslationHelper;
|
||||
use App\Models\UserBusinessStructure;
|
||||
use Illuminate\Support\Facades\Log;
|
||||
|
||||
/**
|
||||
* Optimierte Version der BusinessUserItem Klasse
|
||||
*
|
||||
* Hauptverbesserungen:
|
||||
* - makeUserFromModel() für bereits geladene User-Objekte
|
||||
* - Bessere Error-Behandlung mit Logging
|
||||
* - Optimierte Datenbankzugriffe durch Relations-Nutzung
|
||||
* - Input-Validierung und Boundary-Checks
|
||||
*/
|
||||
class BusinessUserItemOptimized
|
||||
{
|
||||
public $businessUserItems = [];
|
||||
|
||||
private $date;
|
||||
private $b_user;
|
||||
private ?TreeCalcBotOptimized $treeCalcBot = null;
|
||||
private $user_level_active_pos;
|
||||
private $needsQualificationRecalculation = false;
|
||||
|
||||
public function __construct($date, ?TreeCalcBotOptimized $treeCalcBot = null)
|
||||
{
|
||||
$this->date = $date;
|
||||
$this->treeCalcBot = $treeCalcBot;
|
||||
$this->businessUserItems = []; // Initialize array
|
||||
return $this;
|
||||
}
|
||||
|
||||
/**
|
||||
* Erstellt BusinessUser aus User-ID (Original-Methode für Rückwärtskompatibilität)
|
||||
*
|
||||
* @param int $user_id Die User-ID
|
||||
* @param bool $forceLiveCalculation Erzwingt Live-Berechnung und überspringt gespeicherte Daten
|
||||
*/
|
||||
public function makeUser($user_id, bool $forceLiveCalculation = false): void
|
||||
{
|
||||
try {
|
||||
// Prüfe nur nach gespeicherten Daten, wenn keine Live-Berechnung erzwungen wird
|
||||
if (!$forceLiveCalculation) {
|
||||
$this->b_user = UserBusiness::where('user_id', $user_id)
|
||||
->where('month', $this->date->month)
|
||||
->where('year', $this->date->year)
|
||||
->first();
|
||||
|
||||
if ($this->b_user !== null) {
|
||||
\Log::debug("BusinessUserItem: Using stored data for user {$user_id} ({$this->date->month}/{$this->date->year})");
|
||||
|
||||
// WICHTIG: Auch bei gespeicherten Daten User-Model laden für Grunddaten
|
||||
$user = User::with(['account', 'user_level'])->find($user_id);
|
||||
if ($user) {
|
||||
$this->enrichStoredDataWithUserModel($user);
|
||||
|
||||
// Prüfe ob Level-Qualifikationsdaten nachberechnet werden müssen
|
||||
if ($this->needsQualificationRecalculation) {
|
||||
\Log::debug("BusinessUserItem: Triggering qualification recalculation for user {$user_id}");
|
||||
$this->calcQualPP(); // Berechne fehlende Level-Qualifikationsdaten
|
||||
}
|
||||
}
|
||||
|
||||
return; // Bereits gespeicherte Daten verwenden
|
||||
}
|
||||
} else {
|
||||
\Log::debug("BusinessUserItem: Force live calculation for user {$user_id} ({$this->date->month}/{$this->date->year})");
|
||||
}
|
||||
|
||||
// Lade User mit Relations (weniger effizient als makeUserFromModel)
|
||||
$user = User::with(['account', 'user_level'])->find($user_id);
|
||||
|
||||
if (!$user) {
|
||||
\Log::warning("BusinessUserItem: User not found: {$user_id}");
|
||||
return;
|
||||
}
|
||||
|
||||
$this->initializeFromUserModel($user);
|
||||
|
||||
// WICHTIG: Bei Live-Berechnung auch Level-Qualifikationsdaten berechnen
|
||||
// (nicht bei forceLiveCalculation=false, da dort gespeicherte Daten bevorzugt werden)
|
||||
if ($forceLiveCalculation) {
|
||||
$this->calcQualPP();
|
||||
}
|
||||
} catch (\Exception $e) {
|
||||
\Log::error("BusinessUserItem: Error creating user {$user_id}: " . $e->getMessage());
|
||||
throw $e;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* NEUE OPTIMIERTE METHODE: Erstellt BusinessUser aus bereits geladenem User-Objekt
|
||||
* Konsistent zur ursprünglichen makeUser Logik - prüft explizit nach bereits berechneten Daten
|
||||
*
|
||||
* @param User $user Das User-Model
|
||||
* @param bool $forceLiveCalculation Erzwingt Live-Berechnung und überspringt gespeicherte Daten
|
||||
*/
|
||||
public function makeUserFromModel(User $user, bool $forceLiveCalculation = false): void
|
||||
{
|
||||
try {
|
||||
if (!$user || !$user->id) {
|
||||
throw new \InvalidArgumentException('Invalid user model provided');
|
||||
}
|
||||
|
||||
// Prüfe nur nach gespeicherten Daten, wenn keine Live-Berechnung erzwungen wird
|
||||
if (!$forceLiveCalculation) {
|
||||
$this->b_user = UserBusiness::where('user_id', $user->id)
|
||||
->where('month', $this->date->month)
|
||||
->where('year', $this->date->year)
|
||||
->first();
|
||||
|
||||
if ($this->b_user !== null) {
|
||||
\Log::debug("BusinessUserItem: Using stored data for user {$user->id} ({$this->date->month}/{$this->date->year})");
|
||||
|
||||
// WICHTIG: Auch bei gespeicherten Daten User-Grunddaten anreichern
|
||||
$this->enrichStoredDataWithUserModel($user);
|
||||
|
||||
// Prüfe ob Level-Qualifikationsdaten nachberechnet werden müssen
|
||||
if ($this->needsQualificationRecalculation) {
|
||||
\Log::debug("BusinessUserItem: Triggering qualification recalculation for user {$user->id}");
|
||||
$this->calcQualPP(); // Berechne fehlende Level-Qualifikationsdaten
|
||||
}
|
||||
|
||||
return; // Bereits berechnete Daten verwenden
|
||||
}
|
||||
} else {
|
||||
\Log::debug("BusinessUserItem: Force live calculation for user {$user->id} ({$this->date->month}/{$this->date->year})");
|
||||
}
|
||||
|
||||
// Erstelle neuen User und führe Live-Berechnung durch
|
||||
$this->initializeFromUserModel($user);
|
||||
|
||||
// WICHTIG: Bei Live-Berechnung auch Level-Qualifikationsdaten berechnen
|
||||
// (nicht bei forceLiveCalculation=false, da dort gespeicherte Daten bevorzugt werden)
|
||||
if ($forceLiveCalculation) {
|
||||
$this->calcQualPP();
|
||||
}
|
||||
} catch (\Exception $e) {
|
||||
\Log::error("BusinessUserItem: Error creating user from model {$user->id}: " . $e->getMessage());
|
||||
throw $e;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Initialisiert BusinessUser aus User-Model (gemeinsame Logik)
|
||||
*/
|
||||
private function initializeFromUserModel(User $user): void
|
||||
{
|
||||
// Nutze geladene Relations wenn verfügbar
|
||||
$user_level_active = null;
|
||||
if ($user->relationLoaded('user_level')) {
|
||||
$user_level_active = $user->user_level;
|
||||
} else {
|
||||
$user_level_active = $user->user_level; // Fallback auf Original-Relation
|
||||
}
|
||||
$this->user_level_active_pos = $user_level_active ? $user_level_active->pos : 0;
|
||||
|
||||
// Neues UserBusiness Objekt erstellen
|
||||
$this->b_user = new UserBusiness();
|
||||
|
||||
// Account-Daten (mit intelligentem Laden und Error-Handling)
|
||||
$account = $this->getAccountForUser($user);
|
||||
$fill = [
|
||||
'user_id' => $user->id,
|
||||
'month' => $this->date->month,
|
||||
'year' => $this->date->year,
|
||||
'm_level_id' => $user->m_level,
|
||||
'user_level_name' => $user_level_active ? $user_level_active->name : '',
|
||||
'active_account' => $this->calculateActiveAccount($user),
|
||||
'payment_account_date' => $user->payment_account ? $user->getPaymentAccountDateFormat(false) : null,
|
||||
'active_date' => $user->active_date,
|
||||
|
||||
// Account-Daten mit korrekten Fallback-Werten
|
||||
'm_account' => $account ? ($account->m_account ?? null) : null,
|
||||
'email' => $user->email,
|
||||
'first_name' => $account ? ($account->first_name ?? '') : '',
|
||||
'last_name' => $account ? ($account->last_name ?? '') : '',
|
||||
'user_birthday' => $account ? $account->birthday : null,
|
||||
'user_phone' => $account ? ($account->getPhoneNumber() ?? '') : '',
|
||||
|
||||
// Sales Volume (mit Caching falls möglich)
|
||||
'sales_volume_KP_points' => $this->getUserSalesVolumeOptimized($user, 'sales_volume_KP_points'),
|
||||
'sales_volume_TP_points' => $this->getUserSalesVolumeOptimized($user, 'sales_volume_TP_points'),
|
||||
'sales_volume_points_shop' => $this->getUserSalesVolumeOptimized($user, 'sales_volume_points_shop'),
|
||||
'sales_volume_points_KP_sum' => $this->getUserSalesVolumeOptimized($user, 'sales_volume_points_KP_sum'),
|
||||
'sales_volume_points_TP_sum' => $this->getUserSalesVolumeOptimized($user, 'sales_volume_points_TP_sum'),
|
||||
'sales_volume_total' => $this->getUserSalesVolumeOptimized($user, 'sales_volume_total'),
|
||||
'sales_volume_total_shop' => $this->getUserSalesVolumeOptimized($user, 'sales_volume_total_shop'),
|
||||
'sales_volume_total_sum' => $this->getUserSalesVolumeOptimized($user, 'sales_volume_total_sum'),
|
||||
|
||||
// Level-Daten mit Boundary-Checks
|
||||
'margin' => $user_level_active ? max(0, $user_level_active->margin) : 0,
|
||||
'margin_shop' => $user_level_active ? max(0, $user_level_active->margin_shop) : 0,
|
||||
'qual_kp' => $user_level_active ? max(0, $user_level_active->qual_kp) : 0,
|
||||
'qual_pp' => $user_level_active ? max(0, $user_level_active->qual_pp) : 0,
|
||||
|
||||
// Initialisierung
|
||||
'payline_points' => 0,
|
||||
'commission_pp_total' => 0,
|
||||
'commission_shop_sales' => 0,
|
||||
'commission_growth_total' => 0,
|
||||
'version' => 2,
|
||||
];
|
||||
|
||||
$this->b_user->fill($fill);
|
||||
$this->b_user->business_lines = [];
|
||||
$this->b_user->user_items = [];
|
||||
|
||||
// Shop-Provision berechnen (mit verbessertem Logging)
|
||||
$shopVolume = (float) $this->b_user->sales_volume_total_shop;
|
||||
$shopMargin = (float) $this->b_user->margin_shop;
|
||||
$calculatedCommission = round($shopVolume / 100 * $shopMargin, 2);
|
||||
$this->b_user->commission_shop_sales = $calculatedCommission;
|
||||
|
||||
\Log::debug("BusinessUserItem: Created optimized user {$user->id} for {$this->date->month}/{$this->date->year} - Shop commission: {$calculatedCommission} (Volume: {$shopVolume}, Margin: {$shopMargin}%)");
|
||||
}
|
||||
|
||||
/**
|
||||
* Ergänzt gespeicherte UserBusiness-Daten mit aktuellen User-Grunddaten
|
||||
* Erweitert um Level-Qualifikationsdaten-Validierung für Struktur-Ansicht
|
||||
*/
|
||||
private function enrichStoredDataWithUserModel(User $user): void
|
||||
{
|
||||
try {
|
||||
$account = $this->getAccountForUser($user);
|
||||
|
||||
// Ergänze fehlende User-Grunddaten in gespeicherten UserBusiness-Daten
|
||||
$this->b_user->user_id = $user->id;
|
||||
$this->b_user->email = $user->email;
|
||||
$this->b_user->first_name = $account ? ($account->first_name ?? '') : '';
|
||||
$this->b_user->last_name = $account ? ($account->last_name ?? '') : '';
|
||||
$this->b_user->user_birthday = $account ? $account->birthday : null;
|
||||
$this->b_user->user_phone = $account ? ($account->getPhoneNumber() ?? '') : '';
|
||||
$this->b_user->m_account = $account ? ($account->m_account ?? null) : null;
|
||||
|
||||
// Berechne aktiven Account-Status
|
||||
$this->b_user->active_account = $this->calculateActiveAccount($user);
|
||||
$this->b_user->payment_account_date = $user->payment_account;
|
||||
|
||||
// User-Level Informationen
|
||||
$user_level_active = $user->user_level;
|
||||
if ($user_level_active) {
|
||||
$this->b_user->user_level_name = $user_level_active->name;
|
||||
$this->user_level_active_pos = $user_level_active->pos;
|
||||
}
|
||||
|
||||
// WICHTIG: Validiere Level-Qualifikationsdaten für Struktur-Ansicht
|
||||
$this->validateLevelQualificationData();
|
||||
|
||||
// Prüfe ob Sales Volume Felder aktualisiert werden müssen
|
||||
$this->updateSalesVolumeFields($user);
|
||||
|
||||
\Log::debug("BusinessUserItem: Enriched stored data for user {$user->id} with current user model data");
|
||||
} catch (\Exception $e) {
|
||||
\Log::error("BusinessUserItem: Error enriching stored data for user {$user->id}: " . $e->getMessage());
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Aktualisiert Sales Volume und Commission Felder bei gespeicherten Daten
|
||||
*/
|
||||
private function updateSalesVolumeFields(User $user): void
|
||||
{
|
||||
try {
|
||||
// Prüfe ob Sales Volume Felder leer sind
|
||||
$fieldsToUpdate = [
|
||||
'sales_volume_KP_points',
|
||||
'sales_volume_TP_points',
|
||||
'sales_volume_points_shop',
|
||||
'sales_volume_points_KP_sum',
|
||||
'sales_volume_points_TP_sum',
|
||||
'sales_volume_total',
|
||||
'sales_volume_total_shop',
|
||||
'sales_volume_total_sum'
|
||||
];
|
||||
|
||||
$needsUpdate = false;
|
||||
foreach ($fieldsToUpdate as $field) {
|
||||
if (!isset($this->b_user->{$field}) || $this->b_user->{$field} === null || $this->b_user->{$field} === 0) {
|
||||
$newValue = $this->getUserSalesVolumeOptimized($user, $field);
|
||||
$this->b_user->{$field} = $newValue;
|
||||
|
||||
if ($newValue > 0) {
|
||||
$needsUpdate = true;
|
||||
\Log::debug("BusinessUserItem: Updated {$field} for user {$user->id}: {$newValue}");
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// Aktualisiere Shop Commission falls nötig
|
||||
if (!isset($this->b_user->commission_shop_sales) || $this->b_user->commission_shop_sales === 0) {
|
||||
$shopVolume = (float) $this->b_user->sales_volume_total_shop;
|
||||
$shopMargin = (float) $this->b_user->margin_shop;
|
||||
|
||||
if ($shopVolume > 0 && $shopMargin > 0) {
|
||||
$calculatedCommission = round($shopVolume / 100 * $shopMargin, 2);
|
||||
$this->b_user->commission_shop_sales = $calculatedCommission;
|
||||
$needsUpdate = true;
|
||||
\Log::debug("BusinessUserItem: Updated commission_shop_sales for user {$user->id}: {$calculatedCommission}");
|
||||
}
|
||||
}
|
||||
|
||||
if ($needsUpdate) {
|
||||
\Log::info("BusinessUserItem: Updated sales volume fields for user {$user->id}");
|
||||
}
|
||||
} catch (\Exception $e) {
|
||||
\Log::error("BusinessUserItem: Error updating sales volume fields for user {$user->id}: " . $e->getMessage());
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Validiert und aktualisiert Level-Qualifikationsdaten wenn nötig
|
||||
* Stellt sicher, dass next_qual_user_level und next_can_user_level für Struktur-Ansicht verfügbar sind
|
||||
*/
|
||||
private function validateLevelQualificationData(): void
|
||||
{
|
||||
try {
|
||||
// Prüfe ob Level-Qualifikationsdaten vorhanden sind
|
||||
$hasNextQual = !empty($this->b_user->next_qual_user_level);
|
||||
$hasNextCan = !empty($this->b_user->next_can_user_level);
|
||||
$hasQualUserLevel = !empty($this->b_user->qual_user_level);
|
||||
// Wenn Level-Qualifikationsdaten fehlen, führe Neuberechnung durch
|
||||
if (!$hasNextQual && !$hasNextCan && !$hasQualUserLevel) {
|
||||
\Log::debug("BusinessUserItem: Level qualification data missing for user {$this->b_user->user_id}, triggering recalculation");
|
||||
|
||||
// Setze Flag für notwendige Neuberechnung
|
||||
$this->needsQualificationRecalculation = true;
|
||||
}
|
||||
} catch (\Exception $e) {
|
||||
\Log::warning("BusinessUserItem: Error validating level qualification data for user {$this->b_user->user_id}: " . $e->getMessage());
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Berechnet ob Account aktiv ist (mit Error-Handling)
|
||||
*/
|
||||
private function calculateActiveAccount(User $user): bool
|
||||
{
|
||||
try {
|
||||
if (!$user->payment_account) {
|
||||
return false;
|
||||
}
|
||||
|
||||
// Verwende aktuelles Datum, nicht das Berechnungs-Startdatum
|
||||
return Carbon::parse($user->payment_account)->gt(Carbon::now());
|
||||
} catch (\Exception $e) {
|
||||
\Log::warning("BusinessUserItem: Error calculating active account for user {$user->id}: " . $e->getMessage());
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Optimierte Sales Volume Abfrage mit detailliertem Logging
|
||||
*/
|
||||
private function getUserSalesVolumeOptimized(User $user, string $field)
|
||||
{
|
||||
try {
|
||||
// Direkter Aufruf mit detailliertem Logging
|
||||
$value = $user->getUserSalesVolumeBy($this->date->month, $this->date->year, $field);
|
||||
|
||||
// Log nur bei ersten Aufruf für diesen User (Performance)
|
||||
static $loggedUsers = [];
|
||||
if (!isset($loggedUsers[$user->id])) {
|
||||
$loggedUsers[$user->id] = true;
|
||||
|
||||
// Prüfe ob UserSalesVolume Daten existieren
|
||||
$userSalesVolume = $user->getUserSalesVolume($this->date->month, $this->date->year, 'first');
|
||||
if (!$userSalesVolume) {
|
||||
\Log::info("BusinessUserItem: No UserSalesVolume found for user {$user->id} in {$this->date->month}/{$this->date->year}");
|
||||
|
||||
// Prüfe neueste verfügbare Daten
|
||||
$latestVolume = \App\Models\UserSalesVolume::where('user_id', $user->id)
|
||||
->orderBy('year', 'desc')
|
||||
->orderBy('month', 'desc')
|
||||
->first();
|
||||
|
||||
if ($latestVolume) {
|
||||
\Log::info("BusinessUserItem: Latest UserSalesVolume for user {$user->id}: {$latestVolume->month}/{$latestVolume->year}");
|
||||
} else {
|
||||
\Log::warning("BusinessUserItem: No UserSalesVolume records found for user {$user->id} at all");
|
||||
}
|
||||
} else {
|
||||
\Log::debug("BusinessUserItem: UserSalesVolume found for user {$user->id} in {$this->date->month}/{$this->date->year}");
|
||||
}
|
||||
}
|
||||
|
||||
return $value;
|
||||
} catch (\Exception $e) {
|
||||
\Log::error("BusinessUserItem: Error getting sales volume {$field} for user {$user->id}: " . $e->getMessage());
|
||||
return 0; // Sicherer Fallback
|
||||
}
|
||||
}
|
||||
|
||||
// ===== ORIGINALE METHODEN (unverändert für Kompatibilität) =====
|
||||
|
||||
public function getSalesVolumeTotalMargin()
|
||||
{
|
||||
return $this->b_user->getSalesVolumeTotalMargin();
|
||||
}
|
||||
|
||||
public function addUserID()
|
||||
{
|
||||
if ($this->treeCalcBot) {
|
||||
$this->treeCalcBot->addProcessedUserId($this->b_user->user_id);
|
||||
} else {
|
||||
// Fallback für Rückwärtskompatibilität - sollte in Logs sichtbar sein
|
||||
\Log::warning("BusinessUserItemOptimized: TreeCalcBotOptimized Referenz fehlt für User ID: " . $this->b_user->user_id);
|
||||
}
|
||||
}
|
||||
|
||||
public function getBUser()
|
||||
{
|
||||
return $this->b_user;
|
||||
}
|
||||
|
||||
public function addBusinessLineToUser($line, $obj)
|
||||
{
|
||||
$this->b_user->business_lines[$line] = $obj;
|
||||
}
|
||||
|
||||
public function addBusinessLinePoints($line, $points)
|
||||
{
|
||||
if (!isset($this->b_user->business_lines[$line])) {
|
||||
\Log::warning("BusinessUserItem: Trying to add points to non-existent line {$line}");
|
||||
return;
|
||||
}
|
||||
|
||||
$obj = $this->b_user->business_lines[$line];
|
||||
|
||||
// Handle both array and object types (JSON deserialization inconsistency)
|
||||
if (is_array($obj)) {
|
||||
$obj['points'] = ($obj['points'] ?? 0) + (float) $points;
|
||||
} else {
|
||||
// Ensure it's an object
|
||||
if (!is_object($obj)) {
|
||||
$obj = (object) $obj;
|
||||
}
|
||||
$obj->points = ($obj->points ?? 0) + (float) $points;
|
||||
}
|
||||
|
||||
$this->b_user->business_lines[$line] = $obj;
|
||||
}
|
||||
|
||||
public function addTotalTP($points)
|
||||
{
|
||||
$this->b_user->total_pp += (float) $points; // Type-Safety
|
||||
}
|
||||
|
||||
public function isQualKP(): bool
|
||||
{
|
||||
return ($this->b_user->sales_volume_points_KP_sum >= $this->b_user->qual_kp);
|
||||
}
|
||||
|
||||
public function isQualLevel(): bool
|
||||
{
|
||||
return !empty($this->b_user->qual_user_level);
|
||||
}
|
||||
|
||||
public function isQualEqualLevel(): bool
|
||||
{
|
||||
if (!$this->b_user->qual_user_level) {
|
||||
return false;
|
||||
}
|
||||
return ($this->b_user->m_level_id == $this->b_user->qual_user_level['id']);
|
||||
}
|
||||
|
||||
public function getQualPaylines(): int
|
||||
{
|
||||
if (!$this->b_user->qual_user_level) {
|
||||
return 0;
|
||||
}
|
||||
return (int) $this->b_user->qual_user_level['paylines'];
|
||||
}
|
||||
|
||||
public function getRestQualKP(): float
|
||||
{
|
||||
$ret = $this->b_user->sales_volume_points_KP_sum - $this->b_user->qual_kp;
|
||||
return max(0, $ret); // Boundary-Check
|
||||
}
|
||||
|
||||
public function getCommissionTotal(): float
|
||||
{
|
||||
return round(
|
||||
$this->b_user->commission_shop_sales +
|
||||
$this->b_user->commission_pp_total +
|
||||
$this->b_user->commission_growth_total,
|
||||
2
|
||||
);
|
||||
}
|
||||
|
||||
// ===== PROVISIONSBERECHNUNG (Original-Logik) =====
|
||||
|
||||
public function calcQualPP($force = false): void
|
||||
{
|
||||
try {
|
||||
$qualUserLevel = $this->calcuQualLevel();
|
||||
if ($qualUserLevel !== null) {
|
||||
//das erreichte level setzen
|
||||
$this->b_user->qual_user_level = $qualUserLevel->toArray();
|
||||
//next_qual_user_level nächster qualifizierten level
|
||||
$this->setNextUserLevel($force);
|
||||
//qual_user_level_next nächste Provisions-Stufe,
|
||||
$this->setQualNextLevel($force);
|
||||
//provisionen berechnen
|
||||
$this->calculateCommissions($qualUserLevel);
|
||||
} else {
|
||||
$this->setFirstQualLevel();
|
||||
}
|
||||
} catch (\Exception $e) {
|
||||
\Log::error("BusinessUserItem: Error calculating qualifications for user {$this->b_user->user_id}: " . $e->getMessage());
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Berechnet Provisionen mit Error-Handling
|
||||
* Erweitert um Array/Object-Kompatibilität für business_lines
|
||||
*/
|
||||
private function calculateCommissions($qualUserLevel): void
|
||||
{
|
||||
$commission_pp_total = 0;
|
||||
$commission_growth_total = 0;
|
||||
|
||||
// Payline-Provisionen
|
||||
for ($i = 1; $i <= $qualUserLevel->paylines; $i++) {
|
||||
if (isset($this->b_user->business_lines[$i])) {
|
||||
$object = $this->b_user->business_lines[$i];
|
||||
$margin = (float) $this->b_user->qual_user_level['pr_line_' . $i];
|
||||
|
||||
// Handle both array and object types (JSON deserialization inconsistency)
|
||||
if (is_array($object)) {
|
||||
$points = (float) ($object['points'] ?? 0);
|
||||
$object['margin'] = $margin;
|
||||
$object['commission'] = round($points / 100 * $margin, 2);
|
||||
$object['payline'] = true;
|
||||
$commission_pp_total += $object['commission'];
|
||||
} else {
|
||||
$points = (float) ($object->points ?? 0);
|
||||
$object->margin = $margin;
|
||||
$object->commission = round($points / 100 * $margin, 2);
|
||||
$object->payline = true;
|
||||
$commission_pp_total += $object->commission;
|
||||
}
|
||||
|
||||
$this->b_user->business_lines[$i] = $object;
|
||||
}
|
||||
}
|
||||
|
||||
// Growth Bonus
|
||||
if (!empty($qualUserLevel->growth_bonus)) {
|
||||
$payline = (int) $this->b_user->qual_user_level['paylines'] + 1;
|
||||
$maxlines = count($this->b_user->business_lines) + 1;
|
||||
$growth_bonus = (float) $this->b_user->qual_user_level['growth_bonus'];
|
||||
|
||||
for ($i = $payline; $i <= $maxlines; $i++) {
|
||||
if (isset($this->b_user->business_lines[$i])) {
|
||||
$object = $this->b_user->business_lines[$i];
|
||||
|
||||
// Handle both array and object types (JSON deserialization inconsistency)
|
||||
if (is_array($object)) {
|
||||
$points = (float) ($object['points'] ?? 0);
|
||||
$object['margin'] = $growth_bonus;
|
||||
$object['commission'] = round($points / 100 * $growth_bonus, 2);
|
||||
$object['growth_bonus'] = true;
|
||||
$commission_growth_total += $object['commission'];
|
||||
} else {
|
||||
$points = (float) ($object->points ?? 0);
|
||||
$object->margin = $growth_bonus;
|
||||
$object->commission = round($points / 100 * $growth_bonus, 2);
|
||||
$object->growth_bonus = true;
|
||||
$commission_growth_total += $object->commission;
|
||||
}
|
||||
|
||||
$this->b_user->business_lines[$i] = $object;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
$this->b_user->commission_pp_total = $commission_pp_total;
|
||||
$this->b_user->commission_growth_total = $commission_growth_total;
|
||||
}
|
||||
|
||||
// ===== WEITERE ORIGINAL-METHODEN (gekürzt, vollständige Implementation in Original) =====
|
||||
//aktuelles level berechnen, max das eigene level, wenn weniger Points dann darunter
|
||||
public function calcuQualLevel()
|
||||
{
|
||||
$qualUserLevels = UserLevel::where('qual_kp', '<=', $this->b_user->sales_volume_points_KP_sum)
|
||||
->where('pos', '<=', $this->user_level_active_pos)
|
||||
->orderBy('qual_pp', 'desc')
|
||||
->get();
|
||||
|
||||
foreach ($qualUserLevels as $qualUserLevel) {
|
||||
$payline_points = $this->getPointsforPayline($qualUserLevel->paylines);
|
||||
$payline_points_qual_kp = $payline_points + $this->getRestQualKP();
|
||||
|
||||
if ($payline_points_qual_kp >= $qualUserLevel->qual_pp) {
|
||||
$this->b_user->payline_points = $payline_points;
|
||||
$this->b_user->payline_points_qual_kp = $payline_points_qual_kp;
|
||||
return $qualUserLevel;
|
||||
}
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
private function getPointsforPayline($paylines): float
|
||||
{
|
||||
$payline_points = 0;
|
||||
for ($i = 1; $i <= $paylines; $i++) {
|
||||
if (isset($this->b_user->business_lines[$i])) {
|
||||
$line = $this->b_user->business_lines[$i];
|
||||
|
||||
// Handle both array and object types (JSON deserialization inconsistency)
|
||||
if (is_array($line)) {
|
||||
$payline_points += (float) ($line['points'] ?? 0);
|
||||
} else {
|
||||
$payline_points += (float) ($line->points ?? 0);
|
||||
}
|
||||
}
|
||||
}
|
||||
return $payline_points;
|
||||
}
|
||||
/**
|
||||
* Setzt das nächste Provision-Level
|
||||
* Wenn das aktuelle Level nicht erreicht ist, dann wird bei aktuelle Provisions-Stufe die erreichte level angezeigt und berechnet
|
||||
* Zur Info wird das nächste level angezeigt, der folgt, sonst leer
|
||||
*/
|
||||
private function setQualNextLevel($force = false): void
|
||||
{
|
||||
//ist der level nicht das aktuelle level, dann sucht es den nächsten level
|
||||
//isQualEqualLevel wenn das erreichte level das akutelle user level ist.
|
||||
if (!$this->isQualEqualLevel() && $this->b_user->qual_user_level['next_id'] != null) {
|
||||
$qualUserLevelNext = UserLevel::where('id', '=', $this->b_user->qual_user_level['next_id'])
|
||||
->orderBy('qual_pp', 'asc')
|
||||
->first();
|
||||
if ($qualUserLevelNext) {
|
||||
$this->b_user->qual_user_level_next = $qualUserLevelNext->toArray();
|
||||
} else {
|
||||
$this->b_user->qual_user_level_next = null;
|
||||
}
|
||||
} else {
|
||||
$this->b_user->qual_user_level_next = null;
|
||||
}
|
||||
}
|
||||
|
||||
private function setNextUserLevel($force = false): void
|
||||
{
|
||||
//sucht den nächsten level, der mehr points hat als das aktuelle level
|
||||
$nextQualUserLevel = UserLevel::where('qual_pp', '<=', $this->b_user->payline_points_qual_kp)
|
||||
->where('pos', '>', $this->user_level_active_pos)
|
||||
->orderBy('qual_pp', 'desc')
|
||||
->first();
|
||||
//wenn der nächste level qualifiziert ist und die KP-Qualifikation erfüllt ist, dann setzt es den nächsten level
|
||||
if ($nextQualUserLevel && $this->isQualKP()) {
|
||||
$this->b_user->next_qual_user_level = $nextQualUserLevel->toArray();
|
||||
$this->b_user->next_can_user_level = null;
|
||||
} else {
|
||||
//wenn der nächste level nicht qualifiziert ist, dann sucht es den nächsten level, nach pos
|
||||
$nextCanUserLevel = UserLevel::where('pos', '>', $this->user_level_active_pos)
|
||||
->orderBy('qual_pp', 'asc')
|
||||
->first();
|
||||
if ($nextCanUserLevel) {
|
||||
$this->b_user->next_can_user_level = $nextCanUserLevel->toArray();
|
||||
}
|
||||
$this->b_user->next_qual_user_level = null;
|
||||
}
|
||||
}
|
||||
|
||||
private function setFirstQualLevel(): void
|
||||
{
|
||||
$qualUserLevelNext = UserLevel::where('pos', '=', 1)
|
||||
->orderBy('qual_pp', 'asc')
|
||||
->first();
|
||||
if ($qualUserLevelNext) {
|
||||
$this->b_user->qual_user_level_next = $qualUserLevelNext->toArray();
|
||||
}
|
||||
}
|
||||
|
||||
// Magic Methods für Property-Zugriff (Rückwärtskompatibilität)
|
||||
public function __get($name)
|
||||
{
|
||||
if (isset($this->b_user->$name)) {
|
||||
return $this->b_user->$name;
|
||||
}
|
||||
|
||||
// Legacy-Properties
|
||||
$legacyMap = [
|
||||
'sales_volume_points_KP_sum' => 'sales_volume_points_KP_sum',
|
||||
'sales_volume_points_TP_sum' => 'sales_volume_points_TP_sum',
|
||||
'business_lines' => 'business_lines',
|
||||
'user_id' => 'user_id'
|
||||
];
|
||||
|
||||
if (isset($legacyMap[$name]) && isset($this->b_user->{$legacyMap[$name]})) {
|
||||
return $this->b_user->{$legacyMap[$name]};
|
||||
}
|
||||
|
||||
return null;
|
||||
}
|
||||
|
||||
/**
|
||||
* Prüft und setzt Sponsor-Informationen (Original-Implementation)
|
||||
*/
|
||||
public function checkSponsor($user): void
|
||||
{
|
||||
try {
|
||||
// Check if already stored
|
||||
if ($this->isSave()) {
|
||||
return;
|
||||
}
|
||||
|
||||
$sponsor = new stdClass();
|
||||
$sponsor->is_sponsor = false;
|
||||
$sponsor->user_id = false;
|
||||
$sponsor->first_name = '';
|
||||
$sponsor->last_name = '';
|
||||
$sponsor->email = '';
|
||||
$sponsor->m_account = '';
|
||||
$sponsor->full_name = 'Keinen Sponsor zugewiesen';
|
||||
|
||||
if ($user->m_sponsor) {
|
||||
if ($user->user_sponsor) {
|
||||
$sponsor->is_sponsor = true;
|
||||
$sponsor->user_id = $user->user_sponsor->id;
|
||||
|
||||
if ($user->user_sponsor->account) {
|
||||
$sponsor->full_name = substr(
|
||||
'Sponsor: ' . $user->user_sponsor->account->first_name . ' ' .
|
||||
$user->user_sponsor->account->last_name . ' | ' .
|
||||
$user->user_sponsor->email . ' | ' .
|
||||
$user->user_sponsor->account->m_account,
|
||||
0,
|
||||
250
|
||||
);
|
||||
$sponsor->first_name = $user->user_sponsor->account->first_name;
|
||||
$sponsor->last_name = $user->user_sponsor->account->last_name;
|
||||
$sponsor->m_account = $user->user_sponsor->account->m_account;
|
||||
} else {
|
||||
$sponsor->full_name = 'Sponsor: ' . $user->user_sponsor->email;
|
||||
}
|
||||
$sponsor->email = $user->user_sponsor->email;
|
||||
} else {
|
||||
$sponsor->full_name = 'Sponsor wurde gelöscht.';
|
||||
}
|
||||
}
|
||||
|
||||
$this->b_user->sponsor = $sponsor;
|
||||
} catch (\Exception $e) {
|
||||
Log::error("BusinessUserItem: Error checking sponsor for user {$user->id}: " . $e->getMessage());
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Lädt Parent Business Users rekursiv (Original-Implementation mit Optimierungen)
|
||||
* BUGFIX: Schutz vor unendlicher Rekursion durch zirkuläre Referenzen
|
||||
*/
|
||||
public function readParentsBusinessUsers($forceLiveCalculation = false, $depth = 0): void
|
||||
{
|
||||
// Schutz vor zu tiefer Rekursion (maximale Tiefe: 20 Levels)
|
||||
$maxDepth = 20;
|
||||
if ($depth > $maxDepth) {
|
||||
Log::warning("BusinessUserItem: Maximale Rekursionstiefe ({$maxDepth}) erreicht für User {$this->b_user->user_id}");
|
||||
return;
|
||||
}
|
||||
|
||||
try {
|
||||
// Optimiert: Lade mit Relations
|
||||
$users = User::with(['account'])
|
||||
->select('users.*')
|
||||
->where('users.deleted_at', '=', null)
|
||||
->where('users.id', '!=', 1)
|
||||
->where('users.admin', '<', 4)
|
||||
->where('users.m_level', '!=', null)
|
||||
->where('users.m_sponsor', '=', $this->b_user->user_id)
|
||||
->where('users.payment_account', '!=', null)
|
||||
->where('users.active_date', '<=', $this->date->end_date)
|
||||
->get();
|
||||
|
||||
if ($users->isNotEmpty()) {
|
||||
foreach ($users as $user) {
|
||||
// KRITISCHER BUGFIX: Prüfe ob User bereits verarbeitet wurde
|
||||
if ($this->treeCalcBot && $this->treeCalcBot->isUserProcessed($user->id)) {
|
||||
Log::debug("BusinessUserItem: Überspringe bereits verarbeiteten User {$user->id} (zirkuläre Referenz verhindert)");
|
||||
continue;
|
||||
}
|
||||
|
||||
$businessUserItem = new BusinessUserItemOptimized($this->date, $this->treeCalcBot);
|
||||
$businessUserItem->makeUserFromModel($user, $forceLiveCalculation);
|
||||
$businessUserItem->addUserID();
|
||||
$this->businessUserItems[] = $businessUserItem;
|
||||
}
|
||||
}
|
||||
|
||||
// Rekursiver Aufruf für alle Child-Items mit Tiefenprüfung
|
||||
foreach ($this->businessUserItems as $businessUserItem) {
|
||||
$businessUserItem->readParentsBusinessUsers($forceLiveCalculation, $depth + 1);
|
||||
}
|
||||
} catch (\Exception $e) {
|
||||
Log::error("BusinessUserItem: Error reading parent users for {$this->b_user->user_id} at depth {$depth}: " . $e->getMessage());
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Lädt Parent Business Users aus gespeicherter Struktur (Original-Implementation)
|
||||
* BUGFIX: Schutz vor unendlicher Rekursion durch zirkuläre Referenzen
|
||||
*/
|
||||
public function readStoredParentsBusinessUsers($structure, $depth = 0): void
|
||||
{
|
||||
// Schutz vor zu tiefer Rekursion (maximale Tiefe: 50 Levels)
|
||||
$maxDepth = 50;
|
||||
if ($depth > $maxDepth) {
|
||||
Log::warning("BusinessUserItem: Maximale Rekursionstiefe ({$maxDepth}) erreicht für gespeicherte User {$this->b_user->user_id}");
|
||||
return;
|
||||
}
|
||||
|
||||
try {
|
||||
$parents = $this->findParentsBusinessOnStored($this->b_user->user_id, $structure);
|
||||
|
||||
if ($parents) {
|
||||
foreach ($parents as $obj) {
|
||||
// KRITISCHER BUGFIX: Prüfe ob User bereits verarbeitet wurde
|
||||
if ($this->treeCalcBot && $this->treeCalcBot->isUserProcessed($obj->user_id)) {
|
||||
Log::debug("BusinessUserItem: Überspringe bereits verarbeiteten gespeicherten User {$obj->user_id} (zirkuläre Referenz verhindert)");
|
||||
continue;
|
||||
}
|
||||
|
||||
$businessUserItem = new BusinessUserItemOptimized($this->date, $this->treeCalcBot);
|
||||
$businessUserItem->makeUser($obj->user_id);
|
||||
$businessUserItem->addUserID();
|
||||
$this->businessUserItems[] = $businessUserItem;
|
||||
}
|
||||
|
||||
foreach ($this->businessUserItems as $businessUserItem) {
|
||||
$businessUserItem->readStoredParentsBusinessUsers($parents, $depth + 1);
|
||||
}
|
||||
}
|
||||
} catch (\Exception $e) {
|
||||
Log::error("BusinessUserItem: Error reading stored parent users at depth {$depth}: " . $e->getMessage());
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Findet Parent Business Items in gespeicherter Struktur (Original-Implementation)
|
||||
*/
|
||||
private function findParentsBusinessOnStored($user_id, $structures)
|
||||
{
|
||||
if (!$structures) {
|
||||
return null;
|
||||
}
|
||||
|
||||
foreach ($structures as $obj) {
|
||||
if ($user_id === $obj->user_id) {
|
||||
return $obj->parents ?? null;
|
||||
}
|
||||
|
||||
if (!empty($obj->parents)) {
|
||||
$result = $this->findParentsBusinessOnStored($user_id, $obj->parents);
|
||||
if ($result) {
|
||||
return $result;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return null;
|
||||
}
|
||||
|
||||
/**
|
||||
* Prüft ob User bereits gespeichert ist
|
||||
* Konsistent zur ursprünglichen BusinessUserItem Implementation
|
||||
*/
|
||||
public function isSave(): bool
|
||||
{
|
||||
return $this->b_user && $this->b_user->isSave();
|
||||
}
|
||||
|
||||
/**
|
||||
* Gibt die Anzahl der qualifizierten Paylines zurück
|
||||
*/
|
||||
public function getQualLevelPaylines()
|
||||
{
|
||||
if ($this->b_user && isset($this->b_user->qual_user_level) && $this->b_user->qual_user_level) {
|
||||
return $this->b_user->qual_user_level['paylines'] ?? 0;
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
/**
|
||||
* Prüft ob eine Line für Growth-Bonus qualifiziert ist
|
||||
*/
|
||||
public function isQualLevelGrowth($line)
|
||||
{
|
||||
if ($this->b_user && isset($this->b_user->business_lines[$line])) {
|
||||
$object = $this->b_user->business_lines[$line];
|
||||
if (isset($object->growth_bonus)) {
|
||||
return $object->growth_bonus > 0;
|
||||
}
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
/**
|
||||
* Intelligentes Laden des UserAccount für einen User
|
||||
* Prüft zuerst geladene Relations, lädt nach wenn nötig
|
||||
*/
|
||||
private function getAccountForUser(User $user): ?UserAccount
|
||||
{
|
||||
try {
|
||||
// Prüfe ob Account-Relation bereits geladen ist
|
||||
if ($user->relationLoaded('account')) {
|
||||
$account = $user->account;
|
||||
if ($account instanceof UserAccount) {
|
||||
\Log::debug("BusinessUserItem: Using pre-loaded account for user {$user->id}");
|
||||
return $account;
|
||||
}
|
||||
}
|
||||
|
||||
// Wenn User keine account_id hat, gibt es definitiv kein Account
|
||||
if (!$user->account_id) {
|
||||
\Log::info("BusinessUserItem: User {$user->id} has no account_id - no account available");
|
||||
return null;
|
||||
}
|
||||
|
||||
// Account nachladen falls nötig
|
||||
\Log::info("BusinessUserItem: Loading account for user {$user->id} (account_id: {$user->account_id})");
|
||||
$account = UserAccount::find($user->account_id);
|
||||
|
||||
if (!$account) {
|
||||
\Log::warning("BusinessUserItem: Account {$user->account_id} not found for user {$user->id}");
|
||||
return null;
|
||||
}
|
||||
|
||||
\Log::debug("BusinessUserItem: Successfully loaded account {$account->id} for user {$user->id}");
|
||||
return $account;
|
||||
} catch (\Exception $e) {
|
||||
\Log::error("BusinessUserItem: Error loading account for user {$user->id}: " . $e->getMessage());
|
||||
return null;
|
||||
}
|
||||
}
|
||||
}
|
||||
215
dev/app-bak/Services/BusinessPlan/BusinessUserRepository.php
Normal file
215
dev/app-bak/Services/BusinessPlan/BusinessUserRepository.php
Normal file
|
|
@ -0,0 +1,215 @@
|
|||
<?php
|
||||
|
||||
namespace App\Services\BusinessPlan;
|
||||
|
||||
use App\User;
|
||||
use App\Models\UserBusinessStructure;
|
||||
use Carbon\Carbon;
|
||||
use Illuminate\Support\Collection;
|
||||
use Illuminate\Support\LazyCollection;
|
||||
use Illuminate\Support\Facades\Log;
|
||||
|
||||
/**
|
||||
* Repository für effiziente Datenbankabfragen im Business-Kontext
|
||||
* Löst N+1 Probleme durch optimierte Eager Loading Strategien
|
||||
*/
|
||||
class BusinessUserRepository
|
||||
{
|
||||
private $startDate;
|
||||
private $endDate;
|
||||
private $month;
|
||||
private $year;
|
||||
|
||||
public function __construct(int $month, int $year)
|
||||
{
|
||||
$this->month = $month;
|
||||
$this->year = $year;
|
||||
|
||||
$date = Carbon::parse($year . '-' . $month . '-1');
|
||||
$this->startDate = $date->format('Y-m-d H:i:s');
|
||||
$this->endDate = $date->endOfMonth()->format('Y-m-d H:i:s');
|
||||
\Log::info("BusinessUserRepository: Start Date: " . $this->startDate);
|
||||
\Log::info("BusinessUserRepository: End Date: " . $this->endDate);
|
||||
}
|
||||
|
||||
/**
|
||||
* Lädt Root-User mit optimiertem Eager Loading und Caching
|
||||
*/
|
||||
public function getRootUsers(): Collection
|
||||
{
|
||||
$cacheKey = "root_users_{$this->month}_{$this->year}";
|
||||
//root hat keinen parent m_sponsor, hat
|
||||
return cache()->remember($cacheKey, 3600, function () {
|
||||
return User::with([
|
||||
'account',
|
||||
'user_level',
|
||||
'userBusiness' => function ($query) {
|
||||
$query->where('month', $this->month)
|
||||
->where('year', $this->year);
|
||||
}
|
||||
])
|
||||
->select('users.*')
|
||||
->where('users.deleted_at', '=', null)
|
||||
->where('users.id', '!=', 1)
|
||||
->where('users.admin', '<', 4)
|
||||
->where('users.m_level', '!=', null)
|
||||
->where('users.m_sponsor', '=', null)
|
||||
->where('users.payment_account', '!=', null)
|
||||
->where('users.active_date', '<=', $this->endDate)
|
||||
->where('users.payment_account', '>', $this->endDate)
|
||||
->get();
|
||||
});
|
||||
}
|
||||
|
||||
/**
|
||||
* Lädt User ohne Parent-Zuordnung (Lazy Loading für Memory-Effizienz)
|
||||
*/
|
||||
public function getParentlessUsers(array $excludeUserIds = []): LazyCollection
|
||||
{
|
||||
$query = User::with([
|
||||
'account',
|
||||
'user_level',
|
||||
'userBusiness' => function ($query) {
|
||||
$query->where('month', $this->month)
|
||||
->where('year', $this->year);
|
||||
}
|
||||
])
|
||||
->select('users.*')
|
||||
->where('users.deleted_at', '=', null)
|
||||
->where('users.id', '!=', 1)
|
||||
->where('users.admin', '<', 4)
|
||||
->where('users.payment_account', '!=', null)
|
||||
->where('users.active_date', '<=', $this->endDate);
|
||||
|
||||
if (!empty($excludeUserIds)) {
|
||||
$query->whereNotIn('users.id', $excludeUserIds);
|
||||
}
|
||||
|
||||
return $query->lazy(100);
|
||||
}
|
||||
|
||||
/**
|
||||
* Lädt einen einzelnen User mit Relations und Caching
|
||||
*/
|
||||
public function getUserWithRelations(int $userId): ?User
|
||||
{
|
||||
$cacheKey = "user_relations_{$userId}_{$this->month}_{$this->year}";
|
||||
|
||||
return cache()->remember($cacheKey, 1800, function () use ($userId) {
|
||||
\Log::debug("BusinessUserRepository: Loading user {$userId} with relations (cache miss)");
|
||||
|
||||
return User::with([
|
||||
'account',
|
||||
'user_level',
|
||||
'userBusiness' => function ($query) {
|
||||
$query->where('month', $this->month)
|
||||
->where('year', $this->year);
|
||||
}
|
||||
])->find($userId);
|
||||
});
|
||||
}
|
||||
|
||||
/**
|
||||
* Lädt Sponsor für einen User
|
||||
*/
|
||||
public function getSponsorForUser(int $userId): ?User
|
||||
{
|
||||
$user = $this->getUserWithRelations($userId);
|
||||
|
||||
if (!$user || !$user->m_sponsor) {
|
||||
return null;
|
||||
}
|
||||
|
||||
return $this->getUserWithRelations($user->m_sponsor);
|
||||
}
|
||||
|
||||
/**
|
||||
* Prüft ob gespeicherte Struktur existiert (mit Caching)
|
||||
*/
|
||||
public function getStoredStructure(): ?UserBusinessStructure
|
||||
{
|
||||
$cacheKey = "stored_structure_{$this->month}_{$this->year}";
|
||||
|
||||
return cache()->remember($cacheKey, 7200, function () {
|
||||
\Log::debug("BusinessUserRepository: Loading stored structure (cache miss)");
|
||||
|
||||
$structure = UserBusinessStructure::where('year', $this->year)
|
||||
->where('month', $this->month)
|
||||
->first();
|
||||
|
||||
return ($structure && $structure->completed) ? $structure : null;
|
||||
});
|
||||
}
|
||||
|
||||
/**
|
||||
* Lädt User-IDs aus gespeicherter Struktur
|
||||
*/
|
||||
public function getUserIdsFromStoredStructure(UserBusinessStructure $structure): array
|
||||
{
|
||||
$userIds = [];
|
||||
|
||||
if ($structure->structure) {
|
||||
$this->extractUserIdsFromStructure((array) $structure->structure, $userIds);
|
||||
}
|
||||
|
||||
if ($structure->parentless) {
|
||||
foreach ($structure->parentless as $item) {
|
||||
$userIds[] = $item->user_id;
|
||||
}
|
||||
}
|
||||
|
||||
return array_unique($userIds);
|
||||
}
|
||||
|
||||
/**
|
||||
* Rekursive Extraktion von User-IDs aus Struktur
|
||||
*/
|
||||
private function extractUserIdsFromStructure(array $structure, array &$userIds): void
|
||||
{
|
||||
foreach ($structure as $item) {
|
||||
$userIds[] = $item->user_id;
|
||||
|
||||
if (isset($item->parents) && is_array($item->parents)) {
|
||||
$this->extractUserIdsFromStructure($item->parents, $userIds);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Löscht alle Cache-Einträge für den aktuellen Monat/Jahr
|
||||
*/
|
||||
public function clearCache(): void
|
||||
{
|
||||
$cacheKeys = [
|
||||
"root_users_{$this->month}_{$this->year}",
|
||||
"stored_structure_{$this->month}_{$this->year}"
|
||||
];
|
||||
|
||||
foreach ($cacheKeys as $key) {
|
||||
cache()->forget($key);
|
||||
\Log::info("BusinessUserRepository: Cache cleared for key: {$key}");
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Batch-Loading für User-Kollektionen
|
||||
*/
|
||||
public function loadUsersInBatches(array $userIds, int $batchSize = 100): \Generator
|
||||
{
|
||||
$chunks = array_chunk($userIds, $batchSize);
|
||||
|
||||
foreach ($chunks as $chunk) {
|
||||
yield User::with([
|
||||
'account',
|
||||
'user_level',
|
||||
'userBusiness' => function ($query) {
|
||||
$query->where('month', $this->month)
|
||||
->where('year', $this->year);
|
||||
}
|
||||
])
|
||||
->whereIn('id', $chunk)
|
||||
->get()
|
||||
->keyBy('id');
|
||||
}
|
||||
}
|
||||
}
|
||||
121
dev/app-bak/Services/BusinessPlan/ExportBot.php
Normal file
121
dev/app-bak/Services/BusinessPlan/ExportBot.php
Normal file
|
|
@ -0,0 +1,121 @@
|
|||
<?php
|
||||
|
||||
namespace App\Services\BusinessPlan;
|
||||
|
||||
use App\User;
|
||||
use stdClass;
|
||||
use Carbon;
|
||||
|
||||
class ExportBot
|
||||
{
|
||||
public $date;
|
||||
private $init_from;
|
||||
private $order;
|
||||
|
||||
public $user_tree;
|
||||
public $user_list;
|
||||
|
||||
private $root_user;
|
||||
|
||||
|
||||
public function __construct($init_from = 'member')
|
||||
{
|
||||
$this->date = Carbon::now();
|
||||
$this->init_from = $init_from;
|
||||
}
|
||||
|
||||
public function initStructureUser(User $user, $order = 'list') //tree or list
|
||||
{
|
||||
$line = 0;
|
||||
$this->order = $order;
|
||||
$this->root_user = $user;
|
||||
|
||||
if ($this->order === 'tree') {
|
||||
$this->user_tree = $this->setUserValues($user, $line);
|
||||
$this->user_tree->childs = $this->readChildUsers($this->user_tree, $line + 1);
|
||||
}
|
||||
if ($this->order === 'list') {
|
||||
$this->user_list = $this->setUserValues($user, $line);
|
||||
$this->readChildUsers($this->user_list, $line + 1);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
private function readChildUsers($parent_user, $line)
|
||||
{
|
||||
|
||||
$childUsers = [];
|
||||
$users = User::with('account')->select('users.*')
|
||||
->where('users.deleted_at', '=', null)
|
||||
->where('users.id', '!=', 1)
|
||||
->where('users.admin', "<", 4)
|
||||
->where('users.m_level', "!=", null)
|
||||
->where('users.m_sponsor', "=", $parent_user->user_id) //<- need the id for childs / sponsors
|
||||
->where('users.payment_account', "!=", null)
|
||||
->where('users.active', "=", 1)
|
||||
->get();
|
||||
|
||||
if ($users) {
|
||||
foreach ($users as $user) {
|
||||
$user_values = $this->setUserValues($user, $line);
|
||||
$childUsers[] = $user_values;
|
||||
if ($this->order === 'list') {
|
||||
$this->user_list->childs[] = $user_values;
|
||||
$this->readChildUsers($user_values, $line + 1);
|
||||
}
|
||||
}
|
||||
}
|
||||
return $childUsers;
|
||||
}
|
||||
|
||||
private function setUserValues(User $user, $line)
|
||||
{
|
||||
|
||||
$sponsor_name = "";
|
||||
if ($user->m_sponsor && $user->user_sponsor->account) {
|
||||
$sponsor_name = $user->user_sponsor->account->m_first_name . " " . $user->user_sponsor->account->m_last_name;
|
||||
}
|
||||
$obj = new stdClass();
|
||||
$obj->line = $line;
|
||||
|
||||
$obj->user_id = $user->id;
|
||||
$obj->m_level = $user->m_level;
|
||||
$obj->level_name = $user->user_level ? $user->user_level->getLang('name') : '';
|
||||
$obj->m_sponsor = $user->m_sponsor;
|
||||
$obj->sponsor_name = $sponsor_name;
|
||||
$obj->m_account = $user->m_account;
|
||||
$obj->email = $user->email;
|
||||
$obj->active_account = $user->payment_account ? Carbon::parse($user->payment_account)->gt(Carbon::parse($this->date->format('Y-m-d H:i:s'))) : 0;
|
||||
$obj->payment_account_date = $user->payment_account ? $user->getPaymentAccountDateFormat(false) : "";
|
||||
$obj->first_name = $user->account->first_name;
|
||||
$obj->last_name = $user->account->last_name;
|
||||
$obj->address = $user->account->address;
|
||||
$obj->address_2 = $user->account->address_2;
|
||||
$obj->zipcode = $user->account->zipcode;
|
||||
$obj->city = $user->account->city;
|
||||
$obj->country_id = $user->account->country_id ? $user->account->country->getLocated() : "";
|
||||
$pre_phone = $user->account->pre_phone_id != "" ? $user->account->pre_phone->phone . " " : "";
|
||||
$pre_mobil = $user->account->pre_mobil_id != "" ? $user->account->pre_mobil->phone . " " : "";
|
||||
$obj->phone = $pre_phone . $user->account->phone;
|
||||
$obj->mobil = $pre_mobil . $user->account->mobil;
|
||||
$obj->birthday = $user->account->birthday;
|
||||
$obj->partner_since = $user->active_date ? $user->getActiveDateFormat(false) : "";
|
||||
|
||||
if ($this->order === 'tree') {
|
||||
$obj->childs = $this->readChildUsers($obj, $line + 1);
|
||||
}
|
||||
if ($this->order === 'list') {
|
||||
$obj->childs = [];
|
||||
}
|
||||
|
||||
return $obj;
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
public function getUser()
|
||||
{
|
||||
return $this->root_user;
|
||||
}
|
||||
}
|
||||
257
dev/app-bak/Services/BusinessPlan/SalesPointsVolume.php
Normal file
257
dev/app-bak/Services/BusinessPlan/SalesPointsVolume.php
Normal file
|
|
@ -0,0 +1,257 @@
|
|||
<?php
|
||||
namespace App\Services\BusinessPlan;
|
||||
|
||||
use App\User;
|
||||
use stdClass;
|
||||
use App\Services\Util;
|
||||
use App\Models\ShoppingOrder;
|
||||
use App\Models\UserSalesVolume;
|
||||
|
||||
class SalesPointsVolume
|
||||
{
|
||||
|
||||
public static function changeSalesPointsVolumeUser(ShoppingOrder $shoppingOrder, $to_user_id){
|
||||
|
||||
if($shoppingOrder->user_sales_volume){
|
||||
$to_user_id = intval($to_user_id);
|
||||
if($shoppingOrder->user_sales_volume->user_id === $to_user_id){
|
||||
\Session()->flash('alert-error', 'Keine Änderung: selber Berater');
|
||||
return;
|
||||
}
|
||||
if(!$shoppingOrder->user_sales_volume->isCurrentMonthYear()){
|
||||
\Session()->flash('alert-error', 'Änderung muss im selben Monat sein');
|
||||
return;
|
||||
}
|
||||
|
||||
$month = $shoppingOrder->user_sales_volume->month;
|
||||
$year = $shoppingOrder->user_sales_volume->year;
|
||||
$form_user_id = $shoppingOrder->user_sales_volume->user_id;
|
||||
|
||||
$to_user = User::find($to_user_id);
|
||||
$form_user = User::find($form_user_id);
|
||||
|
||||
$shoppingOrder->user_sales_volume->user_id = $to_user_id;
|
||||
$shoppingOrder->user_sales_volume->message = 'zugewiesen: '.date('d.m.Y');
|
||||
|
||||
$syslog = $shoppingOrder->user_sales_volume->syslog;
|
||||
$from_email = $form_user ? $form_user->email : '';
|
||||
$to_email = $to_user ? $to_user->email : '';
|
||||
$syslog[date('d.m.Y-h:i:s')] = 'change form: #'.$form_user_id.' '.$from_email.' to: #'.$to_user_id.' '.$to_email;
|
||||
$shoppingOrder->user_sales_volume->syslog = $syslog;
|
||||
|
||||
$shoppingOrder->user_sales_volume->save();
|
||||
|
||||
//recalculate
|
||||
self::reCalculateSalesPointsVolume($to_user_id, $month, $year);
|
||||
self::reCalculateSalesPointsVolume($form_user_id, $month, $year);
|
||||
\Session()->flash('alert-save', true);
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
private static function add_KP_TP_Points($userSalesVolume, $month_points){
|
||||
if($userSalesVolume->status_points === 2) { //KP
|
||||
$month_points->KP += $userSalesVolume->points;
|
||||
}else{
|
||||
// === 1 //TP + KP
|
||||
$month_points->KP += $userSalesVolume->points;
|
||||
$month_points->TP += $userSalesVolume->points;
|
||||
}
|
||||
return $month_points;
|
||||
}
|
||||
|
||||
public static function reCalculateSalesPointsVolume($user_id, $month, $year){
|
||||
|
||||
$userSalesVolumes = UserSalesVolume::where('user_id', $user_id)->where('month', $month)->where('year', $year)->orderBy('id', 'ASC')->get();
|
||||
$month_points = new stdClass();
|
||||
$month_points->KP = 0;
|
||||
$month_points->TP = 0;
|
||||
$month_total_net = 0;
|
||||
$month_shop_points = 0;
|
||||
$month_shop_total_net = 0;
|
||||
//TDOO Status === 3???
|
||||
|
||||
foreach($userSalesVolumes as $userSalesVolume){
|
||||
switch ($userSalesVolume->status) {
|
||||
case 1: //Bestellung Berater
|
||||
$month_points = self::add_KP_TP_Points($userSalesVolume, $month_points);
|
||||
$month_total_net += $userSalesVolume->total_net;
|
||||
break;
|
||||
case 2: //Shop
|
||||
$month_shop_points += $userSalesVolume->points;
|
||||
$month_shop_total_net += $userSalesVolume->total_net;
|
||||
break;
|
||||
case 4: //Gutschrift
|
||||
$month_points = self::add_KP_TP_Points($userSalesVolume, $month_points);
|
||||
|
||||
if($userSalesVolume->status_turnover === 2){
|
||||
$month_shop_total_net += $userSalesVolume->total_net;
|
||||
//ggf hier zu den Shop Points zählen wäre aber immer KP + TP kann nicht keine trennung bei month_shop_points
|
||||
}else{
|
||||
$month_total_net += $userSalesVolume->total_net;
|
||||
}
|
||||
|
||||
break;
|
||||
case 5: //Registrierung
|
||||
$month_points = self::add_KP_TP_Points($userSalesVolume, $month_points);
|
||||
$month_total_net += $userSalesVolume->total_net;
|
||||
break;
|
||||
}
|
||||
$userSalesVolume->month_shop_points = $month_shop_points;
|
||||
$userSalesVolume->month_shop_total_net = $month_shop_total_net;
|
||||
$userSalesVolume->month_KP_points = $month_points->KP;
|
||||
$userSalesVolume->month_TP_points = $month_points->TP;
|
||||
$userSalesVolume->month_total_net = $month_total_net;
|
||||
$userSalesVolume->save();
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
public static function addSalesPointsVolumeUser(ShoppingOrder $shoppingOrder){
|
||||
|
||||
/*
|
||||
status
|
||||
1 => 'hinzugefügt aus Bestellung',
|
||||
2 => 'hinzugefügt aus Shop',
|
||||
3 => 'hinzugefügt aus Shop / pending',
|
||||
*/
|
||||
|
||||
$status = self::getStatusByOrderPaymentFor($shoppingOrder);
|
||||
$user_id = $shoppingOrder->auth_user_id ? $shoppingOrder->auth_user_id : $shoppingOrder->member_id;
|
||||
//akuteller tag / Monat.
|
||||
$month = date('m');
|
||||
$year = date('Y');
|
||||
$date = date('d.m.Y');
|
||||
|
||||
|
||||
if($status === 3){ //shop bestellung User pending if is_like
|
||||
$user_id = NULL;
|
||||
}
|
||||
$user_sales_volume = UserSalesVolume::create([
|
||||
'user_id' => $user_id,
|
||||
'shopping_order_id' => $shoppingOrder->id,
|
||||
'month' => $month,
|
||||
'year' => $year,
|
||||
'date' => $date,
|
||||
'points' => $shoppingOrder->points,
|
||||
'total_net' => $shoppingOrder->subtotal,
|
||||
'status_points' => 1, //KP + TP
|
||||
'message' => '',
|
||||
'status' => $status,
|
||||
]);
|
||||
|
||||
if($status !== 3){
|
||||
self::reCalculateSalesPointsVolume($user_sales_volume->user_id, $user_sales_volume->month, $user_sales_volume->year);
|
||||
}
|
||||
|
||||
return $user_sales_volume;
|
||||
|
||||
}
|
||||
|
||||
public static function setToUserAndReCalculate(UserSalesVolume $user_sales_volume, $user_id){
|
||||
|
||||
//set month year date new, calculate it in the currently month!
|
||||
//If the month has changed, it can no longer be added to the month before
|
||||
$month = date('m');
|
||||
$year = date('Y');
|
||||
$date = date('d.m.Y');
|
||||
|
||||
$user_sales_volume->user_id = $user_id;
|
||||
$user_sales_volume->month = $month;
|
||||
$user_sales_volume->year = $year;
|
||||
$user_sales_volume->date = $date;
|
||||
$user_sales_volume->status = 2; //hinzugefügt aus Shop can only Pending
|
||||
$user_sales_volume->save();
|
||||
|
||||
self::reCalculateSalesPointsVolume($user_id, $month, $year);
|
||||
}
|
||||
|
||||
public static function getStatusByOrderPaymentFor(ShoppingOrder $shoppingOrder){
|
||||
if($shoppingOrder->payment_for){
|
||||
if($shoppingOrder->payment_for === 6){ //Kunde-Shop
|
||||
if($shoppingOrder->shopping_user && $shoppingOrder->shopping_user->is_like){
|
||||
return 3; //shop Kunden, berater zuordnen <- need?
|
||||
}
|
||||
return 2;
|
||||
}
|
||||
return 1;
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
||||
public static function editSalesPointsVolume($data){
|
||||
$user_sales_volume = UserSalesVolume::findOrFail($data['id']);
|
||||
if(!$user_sales_volume->isCurrentMonthYear()){
|
||||
\Session()->flash('alert-error', 'Änderung muss im selben Monat sein');
|
||||
return;
|
||||
}
|
||||
$old_points = $user_sales_volume->points;
|
||||
$old_total_net = $user_sales_volume->total_net;
|
||||
$user_sales_volume->total_net = Util::reFormatNumber($data['total_net']);
|
||||
$user_sales_volume->points = intval($data['points']);
|
||||
|
||||
$user_sales_volume->message = 'geändert: '.date('d.m.Y');
|
||||
$user_sales_volume->info = $data['info'];
|
||||
$user_sales_volume->status_points = $data['status_points'];
|
||||
$user_sales_volume->status_turnover = isset($data['status_turnover']) ? intval($data['status_turnover']) : null;
|
||||
|
||||
$syslog = $user_sales_volume->syslog;
|
||||
$syslog[date('d.m.Y-h:i:s')] = 'edit points: #'.$old_points.' '.$user_sales_volume->points .' total: #'.$old_total_net.' '.$user_sales_volume->total_net;
|
||||
$user_sales_volume->syslog = $syslog;
|
||||
|
||||
$user_sales_volume->save();
|
||||
|
||||
self::reCalculateSalesPointsVolume($user_sales_volume->user_id, $user_sales_volume->month, $user_sales_volume->year);
|
||||
|
||||
\Session()->flash('alert-success', "Points geändert");
|
||||
|
||||
return;
|
||||
|
||||
}
|
||||
|
||||
public static function addSalesPointsVolume($data){
|
||||
|
||||
if(!isset($data['user_id'])){
|
||||
\Session()->flash('alert-error', 'Kein Berater ausgewählt');
|
||||
return;
|
||||
}
|
||||
$user = User::findOrFail($data['user_id']);
|
||||
$month = date('m');
|
||||
$year = date('Y');
|
||||
$date = date('d.m.Y');
|
||||
|
||||
$total_net = isset($data['total_net']) ? Util::reFormatNumber($data['total_net']) : 0;
|
||||
$points = isset($data['points']) ? intval($data['points']) : 0;
|
||||
$syslog[date('d.m.Y-h:i:s')] = 'add points: #'.$points.' total: #'.$total_net;
|
||||
$status = isset($data['status']) ? intval($data['status']) : 4;
|
||||
$status_turnover = isset($data['status_turnover']) ? intval($data['status_turnover']) : null;
|
||||
|
||||
$user_sales_volume = UserSalesVolume::create([
|
||||
'user_id' => $user->id,
|
||||
'shopping_order_id' => null,
|
||||
'month' => $month,
|
||||
'year' => $year,
|
||||
'date' => $date,
|
||||
'points' => $points,
|
||||
'status_points' => $data['status_points'],
|
||||
'status_turnover' => $status_turnover,
|
||||
'total_net' => $total_net,
|
||||
'message' => 'hinzugefügt: '.date('d.m.Y'),
|
||||
'info' => $data['info'],
|
||||
'syslog' => $syslog,
|
||||
'status' => $status,
|
||||
]);
|
||||
|
||||
|
||||
self::reCalculateSalesPointsVolume($user_sales_volume->user_id, $user_sales_volume->month, $user_sales_volume->year);
|
||||
|
||||
\Session()->flash('alert-success', "Points hinzugefügt");
|
||||
|
||||
|
||||
}
|
||||
|
||||
|
||||
|
||||
}
|
||||
178
dev/app-bak/Services/BusinessPlan/SalesPointsVolumeHelper.php
Normal file
178
dev/app-bak/Services/BusinessPlan/SalesPointsVolumeHelper.php
Normal file
|
|
@ -0,0 +1,178 @@
|
|||
<?php
|
||||
namespace App\Services\BusinessPlan;
|
||||
|
||||
use App\Models\UserSalesVolume;
|
||||
|
||||
|
||||
|
||||
class SalesPointsVolumeHelper
|
||||
{
|
||||
|
||||
//protected static $business_users_table = [];
|
||||
/*
|
||||
$sort = 'structur' || 'line'
|
||||
structur: nach baumstruktur sortiert, wird übergeben
|
||||
line: nach reihenfolge sortiert,
|
||||
*/
|
||||
private static $business_users_line = [];
|
||||
private static $totalcommission = [];
|
||||
private static $totalpoints = [];
|
||||
private static $cbot = null;
|
||||
|
||||
|
||||
public static function getBusinessUsersTable($cbot, $sort = 'structur'){
|
||||
|
||||
self::$cbot = $cbot;
|
||||
if($sort == 'structur'){
|
||||
return self::getBusinessUsersTableStructur();
|
||||
}
|
||||
if($sort == 'line'){
|
||||
return self::getBusinessUsersTableLine();
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
/* getBusinessUsersTableStructur */
|
||||
private static function getBusinessUsersTableStructur(){
|
||||
$deep = 0;
|
||||
$ret = "";
|
||||
foreach(self::$cbot->business_users as $business_user){
|
||||
$ret .= self::addTableItemStructur($business_user, $deep);
|
||||
}
|
||||
return $ret;
|
||||
}
|
||||
|
||||
private static function addTableItemStructur($item, $deep) {
|
||||
$ret = self::setTableHTMLItemStructur($item, $deep);
|
||||
if($item->businessUserItems){
|
||||
foreach($item->businessUserItems as $parent){
|
||||
$ret .= self::addTableItemStructur($parent, $deep+1);
|
||||
}
|
||||
}
|
||||
return $ret;
|
||||
}
|
||||
|
||||
private static function setTableHTMLItemStructur($item, $deep){
|
||||
|
||||
$pp = '';
|
||||
$margin = 0;
|
||||
$points = $item->sales_volume_points_KP_sum;
|
||||
$commission = 0;
|
||||
if($deep > 0){
|
||||
$pp = str_repeat(' ', $deep-1).'<div class=" line-height-1 my-2 badge badge-outline-success text-dark font-weight-bolder">'.$deep.'. '.__('team.PP').'</div>';
|
||||
$margin = self::$cbot->getKeybyLine($deep, 'margin');
|
||||
$commission = $points / 100 * $margin;
|
||||
}
|
||||
|
||||
$ret = '<tr>
|
||||
<td><div class="no-line-break">'.$pp.'</div></td>
|
||||
<td><span class="mr-1 ion ion-ios-contact '.($item->active_account ? 'text-primary' : 'text-danger').'"></span>'.$item->first_name.' '.$item->last_name.'
|
||||
</td>
|
||||
<td><div class="no-line-break">'.formatNumber($points, 0).'</span></td>
|
||||
<td>'.formatNumber($margin, 1).' %</td>
|
||||
<td><div class="no-line-break">'.formatNumber($commission, 2).' €</span></td>
|
||||
<td><span class="small">'.$item->user_level_name.'</span></td>
|
||||
</tr>';
|
||||
|
||||
return $ret;
|
||||
}
|
||||
|
||||
private static function getBusinessUsersTableLine(){
|
||||
$deep = 0;
|
||||
$ret = "";
|
||||
foreach(self::$cbot->business_users as $business_user){
|
||||
self::addTableItemLine($business_user, $deep);
|
||||
}
|
||||
foreach(self::$business_users_line as $deep => $items){
|
||||
self::$totalcommission[$deep] = 0;
|
||||
self::$totalpoints[$deep] = 0;
|
||||
foreach($items as $item){
|
||||
$ret .= self::setTableHTMLItemLine($item, $deep);
|
||||
}
|
||||
if($deep > 0){
|
||||
$ret .= self::addTableHTMLTotalItemLine($deep, 'line');
|
||||
}
|
||||
}
|
||||
$ret .= self::addTableHTMLTotalItemLine($deep, 'end');
|
||||
return $ret;
|
||||
}
|
||||
|
||||
private static function addTableItemLine($item, $deep) {
|
||||
$item->deep = $deep;
|
||||
self::$business_users_line[$deep][] = $item;
|
||||
if($item->businessUserItems){
|
||||
foreach($item->businessUserItems as $parent){
|
||||
self::addTableItemLine($parent, $deep+1);
|
||||
}
|
||||
}
|
||||
}
|
||||
private static function addTableHTMLTotalItemLine($deep, $type){
|
||||
$points = 0;
|
||||
$commission = 0;
|
||||
if($type == 'end'){
|
||||
$pp = '<div class=" line-height-1 my-2 badge badge-outline-success text-dark font-weight-bolder">'.__('team.PP').'</div>';
|
||||
$style = ' style="background-color:#d7d700;"';
|
||||
$text = __('order.total');
|
||||
foreach(self::$totalpoints as $key => $value){
|
||||
$points += $value;
|
||||
$commission += self::$totalcommission[$key];
|
||||
}
|
||||
|
||||
}else{
|
||||
$pp = '<div class=" line-height-1 my-2 badge badge-outline-success text-dark font-weight-bolder">'.$deep.'. '.__('team.PP').'</div>';
|
||||
$style = 'style="background-color:#e5e4e4"';
|
||||
$text = __('order.sum');
|
||||
$points = self::$totalpoints[$deep];
|
||||
$commission = self::$totalcommission[$deep];
|
||||
}
|
||||
|
||||
|
||||
|
||||
$ret = '<tr '.$style.'>
|
||||
<td><div class="no-line-break">'.$pp.'</div></td>
|
||||
<td><b>'.$text.'</b></td>
|
||||
<td><div class="no-line-break"><b>'.formatNumber($points, 0).'</b></span></td>
|
||||
<td> </td>
|
||||
<td><div class="no-line-break"><b>'.formatNumber($commission, 2).' €</b></span></td>
|
||||
<td> </td>
|
||||
</tr>';
|
||||
|
||||
return $ret;
|
||||
}
|
||||
|
||||
private static function setTableHTMLItemLine($item, $deep){
|
||||
|
||||
$pp = '';
|
||||
$margin = 0;
|
||||
$points = $item->sales_volume_points_KP_sum;
|
||||
$commission = 0;
|
||||
if($deep > 0){
|
||||
$pp = '<div class=" line-height-1 my-2 badge badge-outline-success text-dark font-weight-bolder">'.$deep.'. '.__('team.PP').'</div>';
|
||||
$margin = self::$cbot->getKeybyLine($deep, 'margin');
|
||||
$commission = $points / 100 * $margin;
|
||||
self::$totalcommission[$deep] += $commission;
|
||||
self::$totalpoints[$deep] += $points;
|
||||
}
|
||||
//
|
||||
/*
|
||||
<th>{{__('tables.line')}}</th>
|
||||
<th>{{ __('shop.name') }}</th>
|
||||
<th>{{__('tables.points')}}</th>
|
||||
<th>{{__('tables.commission')}} %</th>
|
||||
<th>{{__('tables.commission')}} €</th>
|
||||
<th>{{ __('tables.level') }}</th>
|
||||
*/
|
||||
|
||||
$ret = '<tr>
|
||||
<td><div class="no-line-break">'.$pp.'</div></td>
|
||||
<td><span class="mr-1 ion ion-ios-contact '.($item->active_account ? 'text-primary' : 'text-danger').'"></span>'.$item->first_name.' '.$item->last_name.'
|
||||
</td>
|
||||
<td><div class="no-line-break">'.formatNumber($points, 0).'</span></td>
|
||||
<td>'.formatNumber($margin, 1).' %</td>
|
||||
<td><div class="no-line-break">'.formatNumber($commission, 2).' €</span></td>
|
||||
<td><span class="small">'.$item->user_level_name.'</span></td>
|
||||
</tr>';
|
||||
|
||||
return $ret;
|
||||
}
|
||||
}
|
||||
391
dev/app-bak/Services/BusinessPlan/TreeCalcBot.php
Normal file
391
dev/app-bak/Services/BusinessPlan/TreeCalcBot.php
Normal file
|
|
@ -0,0 +1,391 @@
|
|||
<?php
|
||||
namespace App\Services\BusinessPlan;
|
||||
|
||||
use App\User;
|
||||
use stdClass;
|
||||
use Carbon;
|
||||
use App\Models\UserBusinessStructure;
|
||||
|
||||
class TreeCalcBot
|
||||
{
|
||||
public $date;
|
||||
public $business_user;
|
||||
|
||||
public $business_users = [];
|
||||
public $parentless = [];
|
||||
|
||||
private $sponsor;
|
||||
private $init_from;
|
||||
private static $userIDs = [];
|
||||
|
||||
public static function addUserID($id){
|
||||
self::$userIDs[$id] = $id;
|
||||
}
|
||||
|
||||
public function __construct($month, $year, $init_from = 'member')
|
||||
{
|
||||
$this->date = new stdClass();
|
||||
$date = Carbon::parse($year.'-'.$month.'-1');
|
||||
$this->date->month = $month;
|
||||
$this->date->year = $year;
|
||||
$this->date->start_date = $date->format('Y-m-d H:i:s');
|
||||
$this->date->end_date = $date->endOfMonth()->format('Y-m-d H:i:s');
|
||||
$this->init_from = $init_from;
|
||||
|
||||
}
|
||||
|
||||
public function initStructureAdmin($check = true, $forceLiveCalculation = false)
|
||||
{
|
||||
//check is month is saved.
|
||||
if($check && $UserBusinessStructure = self::isFromStored($this->date->month, $this->date->year)){
|
||||
$this->readStoredRootUsers($UserBusinessStructure);
|
||||
$this->readStoredParentsUsers($UserBusinessStructure);
|
||||
$this->readStoredParentlessUser($UserBusinessStructure);
|
||||
}else{
|
||||
$this->readRootUsers();
|
||||
$this->readParentsUsers();
|
||||
$this->readParentlessUser();
|
||||
}
|
||||
}
|
||||
|
||||
public function initStructureUser($user_id)
|
||||
{
|
||||
|
||||
$BusinessUserItem = new BusinessUserItem($this->date);
|
||||
$BusinessUserItem->makeUser($user_id);
|
||||
$BusinessUserItem->addUserID();
|
||||
$this->business_users[] = $BusinessUserItem;
|
||||
|
||||
//check is month is saved.
|
||||
if($UserBusinessStructure = self::isFromStored($this->date->month, $this->date->year)){
|
||||
$this->readStoredParentsUsers($UserBusinessStructure);
|
||||
|
||||
if(isset($this->business_users[0]) && $this->business_users[0]->sponsor){
|
||||
$this->readStoredSponsorUser($this->business_users[0]->sponsor->user_id);
|
||||
}
|
||||
}else{
|
||||
$this->readParentsUsers();
|
||||
$this->readSponsorUser($user_id);
|
||||
}
|
||||
}
|
||||
|
||||
public function initBusinesslUserDetail($user)
|
||||
{
|
||||
$this->business_user = new BusinessUserItem($this->date);
|
||||
$this->business_user->makeUser($user->id);
|
||||
$this->business_user->checkSponsor($user);
|
||||
if(!$this->business_user->isSave()){
|
||||
//Aufbau der Struktur für den User in die unendliche Tiefe.
|
||||
$this->business_user->readParentsBusinessUsers();
|
||||
//calculate Points in Lines
|
||||
if(count($this->business_user->businessUserItems) > 0){
|
||||
$this->calcUserPoints($this->business_user->businessUserItems, 1);
|
||||
}
|
||||
//qualifikation nach qual_kp (KundenPoints) und qual_pp (PaylinePoints)
|
||||
$this->business_user->calcQualPP();
|
||||
}
|
||||
}
|
||||
|
||||
/*public function storeBusinesslUser()
|
||||
{
|
||||
$this->business_user->storeUser();
|
||||
}*/
|
||||
|
||||
public static function isFromStored($month, $year){
|
||||
//when is stored an completed
|
||||
$UserBusinessStructure = UserBusinessStructure::where('year', $year)->where('month', $month)->first();
|
||||
if($UserBusinessStructure && $UserBusinessStructure->completed){
|
||||
return $UserBusinessStructure;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
private function calcUserPoints($businessUserItems, $line){
|
||||
if(!isset($this->business_user->business_lines[$line])){
|
||||
$obj = new stdClass();
|
||||
$obj->points = 0;
|
||||
$this->business_user->addBusinessLineToUser($line, $obj);
|
||||
}
|
||||
foreach($businessUserItems as $business_user_item){
|
||||
if(count($business_user_item->businessUserItems) > 0){
|
||||
$this->calcUserPoints($business_user_item->businessUserItems, $line+1);
|
||||
}
|
||||
//business_lines points nach line
|
||||
$this->business_user->addBusinessLinePoints($line, $business_user_item->sales_volume_points_TP_sum); //TP + Shop Points
|
||||
//total_pp gesamte Punkte
|
||||
$this->business_user->addTotalTP($business_user_item->sales_volume_points_TP_sum); //TP + Shop Points
|
||||
}
|
||||
}
|
||||
|
||||
public function getGrowthBonus(){
|
||||
if(count($this->business_user->business_lines) > 6){
|
||||
$b_lines = $this->business_user->business_lines->toArray();
|
||||
return array_slice($b_lines, 6);
|
||||
}
|
||||
return [];
|
||||
}
|
||||
|
||||
|
||||
public function getKeybyLine($line, $key){
|
||||
if($this->business_user->business_lines){
|
||||
$b_lines = $this->business_user->business_lines;
|
||||
if(isset($b_lines[$line])){
|
||||
if($b_lines[$line] instanceof stdClass){
|
||||
if(isset($b_lines[$line]->{$key})){
|
||||
return $b_lines[$line]->{$key};
|
||||
}
|
||||
}else{
|
||||
if(isset($b_lines[$line][$key])){
|
||||
return $b_lines[$line][$key];
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
//* reading from current*//
|
||||
private function readRootUsers(){
|
||||
$users = User::with('account')->select('users.*')
|
||||
->where('users.deleted_at', '=', null)
|
||||
->where('users.id', '!=', 1)
|
||||
->where('users.admin', "<", 4)
|
||||
->where('users.m_level', "!=", null)
|
||||
->where('users.m_sponsor', "=", null)
|
||||
->where('users.payment_account', "!=", null)
|
||||
->where('users.active_date', "<=", $this->date->end_date)
|
||||
->get();
|
||||
if($users){
|
||||
foreach($users as $user){
|
||||
$BusinessUserItem = new BusinessUserItem($this->date);
|
||||
$BusinessUserItem->makeUser($user->id);
|
||||
$BusinessUserItem->addUserID();
|
||||
$this->business_users[] = $BusinessUserItem;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private function readParentsUsers(){
|
||||
foreach($this->business_users as $business_user){
|
||||
$business_user->readParentsBusinessUsers();
|
||||
}
|
||||
}
|
||||
|
||||
private function readParentlessUser(){
|
||||
$users = User::with('account')->select('users.*')
|
||||
->where('users.deleted_at', '=', null)
|
||||
->where('users.id', '!=', 1)
|
||||
->where('users.admin', "<", 4)
|
||||
->where('users.payment_account', "!=", null)
|
||||
->where('users.active_date', "<=", $this->date->end_date)
|
||||
->get();
|
||||
|
||||
foreach($users as $user){
|
||||
if(!isset(self::$userIDs[$user->id])){
|
||||
$BusinessUserItem = new BusinessUserItem($this->date);
|
||||
$BusinessUserItem->makeUser($user->id);
|
||||
$this->parentless[] = $BusinessUserItem;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
//* reading from stored*//
|
||||
private function readStoredRootUsers(UserBusinessStructure $userBusinessStructure){
|
||||
//first level is root
|
||||
if($userBusinessStructure->structure){
|
||||
foreach($userBusinessStructure->structure as $obj){
|
||||
$BusinessUserItem = new BusinessUserItem($this->date);
|
||||
$BusinessUserItem->makeUser($obj->user_id);
|
||||
$BusinessUserItem->addUserID();
|
||||
$this->business_users[] = $BusinessUserItem;
|
||||
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private function readStoredParentsUsers(UserBusinessStructure $userBusinessStructure){
|
||||
foreach($this->business_users as $business_user){
|
||||
$business_user->readStoredParentsBusinessUsers($userBusinessStructure->structure);
|
||||
}
|
||||
}
|
||||
|
||||
private function readStoredParentlessUser(UserBusinessStructure $userBusinessStructure){
|
||||
if($userBusinessStructure->parentless){
|
||||
foreach($userBusinessStructure->parentless as $obj){
|
||||
if(!isset(self::$userIDs[$obj->user_id])){
|
||||
$BusinessUserItem = new BusinessUserItem($this->date);
|
||||
$BusinessUserItem->makeUser($obj->user_id);
|
||||
$this->parentless[] = $BusinessUserItem;
|
||||
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
public function readSponsorUser($user_id){
|
||||
$user = User::find($user_id);
|
||||
$userSponsor = User::find($user->m_sponsor);
|
||||
if($userSponsor){
|
||||
$this->sponsor = new BusinessUserItem($this->date);
|
||||
$this->sponsor->makeUser($userSponsor->id);
|
||||
}
|
||||
}
|
||||
|
||||
public function readStoredSponsorUser($user_id){
|
||||
|
||||
$this->sponsor = new BusinessUserItem($this->date);
|
||||
$this->sponsor->makeUser($user_id);
|
||||
|
||||
}
|
||||
|
||||
|
||||
public function getItems(){
|
||||
return $this->business_users;
|
||||
}
|
||||
|
||||
public function makeHtmlTree(){
|
||||
$deep = 0;
|
||||
$ret = '<ol class="dd-list">';
|
||||
foreach($this->business_users as $business_user){
|
||||
$ret .= $this->addItem($business_user, $deep);
|
||||
|
||||
}
|
||||
$ret .= '</ol>';
|
||||
return $ret;
|
||||
}
|
||||
|
||||
private function addItem($item, $deep){
|
||||
|
||||
$button = '';
|
||||
|
||||
if(($this->init_from === 'admin' && \Auth::user()->isAdmin()) || ($this->init_from === 'member')){ // && \Auth::user()->id === $item->user_id
|
||||
$button = ' | <button type="button" class="btn icon-btn btn-xs btn-secondary" data-toggle="modal" data-target="#modals-load-content"
|
||||
data-id="'.$item->user_id.'"
|
||||
data-action="business-user-detail"
|
||||
data-back=""
|
||||
data-modal="modal-xl"
|
||||
data-init_from="'.$this->init_from .'"
|
||||
data-route="'.route('modal_load').'"><span class="fa fa-calculator"></span></button>';
|
||||
}
|
||||
return '<li class="dd-item dd-nodrag" data-id="'.$item->user_id.'">'.
|
||||
'<div class="dd-handle">
|
||||
<div class="media align-items-center">
|
||||
<div class="d-flex flex-column justify-content-center align-items-center">
|
||||
'.(($deep > 0) ? '<div class="text-large font-weight-bolder line-height-1 my-2 text-secondary badge badge-outline-secondary">'.$deep.'</div>' : '').'
|
||||
</div>
|
||||
<div class="media-body ml-2">
|
||||
<span class="'.($item->active_account ? '' : 'text-muted').'">
|
||||
<a href="#" class="text-black" data-toggle="modal" data-target="#modals-load-content" data-id="'.$item->user_id.'" data-action="business-user-show" data-back="" data-modal="modal-md" data-init_from="'.$this->init_from .'" data-route="'.route('modal_load').'">
|
||||
<span class="mr-1 ion ion-ios-contact '.($item->active_account ? 'text-primary' : 'text-danger').'"></span> <strong>'.$item->first_name.' '.$item->last_name.'</strong>
|
||||
</a>
|
||||
<a href="mailto: '.$item->email.'">'.$item->email.'</a>
|
||||
'.($item->user_birthday ? ' | <i class="ion ion-ios-gift text-primary"></i> '.$item->user_birthday : '').'
|
||||
'.($item->user_phone ? ' | <i class="ion ion-ios-call text-primary"></i> '.$item->user_phone : '').'
|
||||
<span class="badge badge-outline-default '.($item->active_account ? '' : 'text-muted').'">'.\App\Services\TranslationHelper::transUserLevelName($item->user_level_name).' | '.$item->m_account.'</span>
|
||||
<br><span class="small">'.
|
||||
($item->active_account ?
|
||||
'<strong>'.__('team.total_points').': '.$item->sales_volume_points_KP_sum.'</strong> | '.__('team.e').': '.$item->sales_volume_KP_points.' | '.__('team.s').': '.$item->sales_volume_points_shop.' <strong>
|
||||
| '.__('team.net_turnover').': '.formatNumber($item->sales_volume_total_sum).' €</strong> | '.__('team.e').': '.formatNumber($item->sales_volume_total).' € | '.__('team.s').': '.formatNumber($item->sales_volume_total_shop).' €'.
|
||||
$button
|
||||
:
|
||||
__('team.account_to').': '.$item->payment_account_date).
|
||||
'</span>
|
||||
</span>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
|
||||
</div>'.
|
||||
$this->addParentItem($item, $deep).
|
||||
'</li>';
|
||||
|
||||
}
|
||||
|
||||
private function addParentItem($item, $deep){
|
||||
if($item->businessUserItems){
|
||||
$ret = '<ol class="dd-list dd-nodrag">';
|
||||
foreach($item->businessUserItems as $parent){
|
||||
$ret .= $this->addItem($parent, $deep+1);
|
||||
}
|
||||
$ret .='</ol>';
|
||||
return $ret;
|
||||
}
|
||||
return;
|
||||
}
|
||||
|
||||
|
||||
public function isParentless(){
|
||||
return $this->parentless ? true : false;
|
||||
}
|
||||
|
||||
public function makeParentlessHtml(){
|
||||
$ret = "";
|
||||
foreach($this->parentless as $item){
|
||||
$ret .= '<li class="dd-item dd-nodrag" data-id="'.$item->user_id.'">'.
|
||||
'<div class="dd-handle">
|
||||
<span class="'.($item->active_account ? '' : 'text-muted').'">
|
||||
<a href="#" class="text-black" data-toggle="modal" data-target="#modals-load-content" data-id="'.$item->user_id.'" data-action="business-user-show" data-back="" data-modal="modal-md" data-init_from="'.$this->init_from .'" data-route="'.route('modal_load').'">
|
||||
<span class="mr-1 ion ion-ios-contact '.($item->active_account ? 'text-primary' : 'text-danger').'"></span> <strong>'.$item->first_name.' '.$item->last_name.'</strong>
|
||||
</a>
|
||||
<a href="mailto: '.$item->email.'">'.$item->email.'</a>
|
||||
'.($item->user_birthday ? ' | <i class="ion ion-ios-gift text-primary"></i> '.$item->user_birthday : '').'
|
||||
'.($item->user_phone ? ' | <i class="ion ion-ios-call text-primary"></i> '.$item->user_phone : '').'
|
||||
<span class="badge badge-outline-default '.($item->active_account ? '' : 'text-muted').'">'.\App\Services\TranslationHelper::transUserLevelName($item->user_level_name).' | '.$item->m_account.'</span>
|
||||
<br><span class="small">'.
|
||||
($item->active_account ?
|
||||
'<strong>'.__('team.total_points').': '.$item->sales_volume_points_KP_sum.'</strong> | '.__('team.e').': '.$item->sales_volume_KP_points.' | '.__('team.s').': '.$item->sales_volume_points_shop.' <strong>
|
||||
| '.__('team.net_turnover').': '.formatNumber($item->sales_volume_total_sum).' €</strong> | '.__('team.e').': '.formatNumber($item->sales_volume_total).' € | '.__('team.s').': '.formatNumber($item->sales_volume_total_shop).' €'.
|
||||
' | <button type="button" class="btn icon-btn btn-xs btn-secondary" data-toggle="modal" data-target="#modals-load-content"
|
||||
data-id="'.$item->user_id.'"
|
||||
data-action="business-user-detail"
|
||||
data-back=""
|
||||
data-modal="modal-xl"
|
||||
data-route="'.route('modal_load').'"><span class="fa fa-calculator"></span></button>'
|
||||
:
|
||||
__('team.account_to').' '.$item->payment_account_date).
|
||||
'<br>'.$item->m_sponsor_name.
|
||||
'</span>
|
||||
</span>
|
||||
</div>'.
|
||||
'</li>';
|
||||
}
|
||||
return $ret;
|
||||
}
|
||||
|
||||
public function makeSponsorHtml(){
|
||||
|
||||
if($this->sponsor){
|
||||
//' | <a href="' . route('admin_business_user_detail', [$this->sponsor->id]) . '" class="btn icon-btn btn-xs btn-secondary"><span class="fa fa-calculator"></span></a>'
|
||||
$ret = '<li class="dd-item dd-nodrag" data-id="">'.
|
||||
'<div class="dd-handle">
|
||||
<span class="'.($this->sponsor->active_account ? '' : 'text-muted').'">
|
||||
<a href="#" class="text-black" data-toggle="modal" data-target="#modals-load-content" data-id="'.$this->sponsor->user_id.'" data-action="business-user-show" data-back="" data-init_from="'.$this->init_from .'" data-modal="modal-md" data-route="'.route('modal_load').'">
|
||||
<span class="mr-1 ion ion-ios-contact '.($this->sponsor->active_account ? 'text-primary' : 'text-danger').'"></span> <strong>'.$this->sponsor->first_name.' '.$this->sponsor->last_name.'</strong>
|
||||
</a>
|
||||
<a href="mailto: '.$this->sponsor->email.'">'.$this->sponsor->email.'</a>
|
||||
'.($this->sponsor->user_birthday ? ' | <i class="ion ion-ios-gift text-primary"></i> '.$this->sponsor->user_birthday : '').'
|
||||
'.($this->sponsor->user_phone ? ' | <i class="ion ion-ios-call text-primary"></i> '.$this->sponsor->user_phone : '').'
|
||||
<span class="badge badge-outline-default '.($this->sponsor->active_account ? '' : 'text-muted').'">'.\App\Services\TranslationHelper::transUserLevelName($this->sponsor->user_level_name).' | '.$this->sponsor->m_account.'</span>';
|
||||
|
||||
if($this->init_from === 'admin'){
|
||||
$ret .= '<br><span class="small">'.
|
||||
($this->sponsor->active_account ?
|
||||
'<strong>'.__('team.total_points').': '.$this->sponsor->sales_volume_points_KP_sum.'</strong> | '.__('team.e').': '.$this->sponsor->sales_volume_KP_points.' | '.__('team.s').': '.$this->sponsor->sales_volume_points_shop.' <strong>
|
||||
| '.__('team.net_turnover').': '.formatNumber($this->sponsor->sales_volume_total_sum).' €</strong> | '.__('team.e').': '.formatNumber($this->sponsor->sales_volume_total).' € | '.__('team.s').': '.formatNumber($this->sponsor->sales_volume_total_shop).' €'
|
||||
:
|
||||
__('team.account_to').' '.$this->sponsor->payment_account_date).
|
||||
'</span>';
|
||||
}
|
||||
$ret .= '</span>
|
||||
</div>
|
||||
</li>';
|
||||
|
||||
return $ret;
|
||||
}
|
||||
return __('team.no_sponsor_assigned');
|
||||
}
|
||||
|
||||
}
|
||||
912
dev/app-bak/Services/BusinessPlan/TreeCalcBotOptimized.php
Normal file
912
dev/app-bak/Services/BusinessPlan/TreeCalcBotOptimized.php
Normal file
|
|
@ -0,0 +1,912 @@
|
|||
<?php
|
||||
|
||||
namespace App\Services\BusinessPlan;
|
||||
|
||||
use App\User;
|
||||
use stdClass;
|
||||
use Carbon\Carbon;
|
||||
use App\Models\UserBusinessStructure;
|
||||
use Psr\Log\LoggerInterface;
|
||||
|
||||
/**
|
||||
* Optimierte Version der TreeCalcBot Klasse
|
||||
*
|
||||
* Verbesserungen:
|
||||
* - Trennung von Datenzugriff (Repository Pattern)
|
||||
* - Trennung von HTML-Rendering (Renderer Pattern)
|
||||
* - Optimierte Datenbankabfragen (N+1 Problem gelöst)
|
||||
* - Memory-effiziente Verarbeitung großer Datenmengen
|
||||
* - Robuste Fehlerbehandlung mit Logging
|
||||
* - Dependency Injection für bessere Testbarkeit
|
||||
*/
|
||||
class TreeCalcBotOptimized
|
||||
{
|
||||
private stdClass $date;
|
||||
private string $initFrom;
|
||||
private array $businessUsers = [];
|
||||
private array $parentless = [];
|
||||
private ?BusinessUserItemOptimized $businessUser = null;
|
||||
private ?BusinessUserItemOptimized $sponsor = null;
|
||||
private array $processedUserIds = [];
|
||||
private bool $forceLiveCalculation = false;
|
||||
|
||||
private BusinessUserRepository $repository;
|
||||
private TreeHtmlRenderer $renderer;
|
||||
private LoggerInterface $logger;
|
||||
|
||||
public function __construct(
|
||||
int $month,
|
||||
int $year,
|
||||
string $initFrom = 'member',
|
||||
bool $forceLiveCalculation = false,
|
||||
?BusinessUserRepository $repository = null,
|
||||
?TreeHtmlRenderer $renderer = null,
|
||||
?LoggerInterface $logger = null
|
||||
) {
|
||||
$this->validateInput($month, $year);
|
||||
$this->initializeDate($month, $year);
|
||||
$this->initFrom = $initFrom;
|
||||
$this->forceLiveCalculation = $forceLiveCalculation;
|
||||
|
||||
// Dependency Injection mit Fallback
|
||||
$this->repository = $repository ?? new BusinessUserRepository($month, $year);
|
||||
$this->renderer = $renderer ?? new TreeHtmlRenderer($initFrom, $forceLiveCalculation);
|
||||
$this->logger = $logger ?? app(LoggerInterface::class);
|
||||
}
|
||||
|
||||
/**
|
||||
* Initialisiert die Business-Struktur für Admin-Ansicht
|
||||
*
|
||||
* @param bool $check Prüft auf gespeicherte Struktur
|
||||
* @param bool $forceLiveCalculation Erzwingt Live-Berechnung und überspringt gespeicherte Daten
|
||||
*/
|
||||
public function initStructureAdmin(bool $check = true, bool $forceLiveCalculation = false): void
|
||||
{
|
||||
|
||||
try {
|
||||
$this->forceLiveCalculation = $forceLiveCalculation;
|
||||
|
||||
if ($forceLiveCalculation) {
|
||||
$this->logger->info("Building fresh business structure for {$this->date->month}/{$this->date->year} with forced live calculation");
|
||||
$this->buildFreshStructure();
|
||||
return;
|
||||
}
|
||||
|
||||
$storedStructure = null;
|
||||
if ($check) {
|
||||
$storedStructure = $this->repository->getStoredStructure();
|
||||
}
|
||||
if ($storedStructure) {
|
||||
$this->logger->info("Loading stored business structure for {$this->date->month}/{$this->date->year}");
|
||||
$this->loadStoredStructure($storedStructure);
|
||||
} else {
|
||||
$this->logger->info("Building fresh business structure for {$this->date->month}/{$this->date->year}");
|
||||
$this->buildFreshStructure();
|
||||
}
|
||||
} catch (\Exception $e) {
|
||||
$this->logger->error("Error initializing admin structure: " . $e->getMessage());
|
||||
throw $e;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Initialisiert die Struktur für einen spezifischen User
|
||||
*
|
||||
* @param int $userId Die User-ID
|
||||
* @param bool $forceLiveCalculation Erzwingt Live-Berechnung und überspringt gespeicherte Daten
|
||||
*/
|
||||
public function initStructureUser(int $userId, bool $forceLiveCalculation = false): void
|
||||
{
|
||||
try {
|
||||
$this->forceLiveCalculation = $forceLiveCalculation;
|
||||
|
||||
if ($forceLiveCalculation) {
|
||||
$this->logger->info("Initializing structure for user: {$userId} with forced live calculation");
|
||||
} else {
|
||||
$this->logger->info("Initializing structure for user: {$userId}");
|
||||
}
|
||||
|
||||
$user = $this->repository->getUserWithRelations($userId);
|
||||
|
||||
if (!$user) {
|
||||
$this->logger->warning("User not found: {$userId}");
|
||||
return;
|
||||
}
|
||||
|
||||
$businessUserItem = new BusinessUserItemOptimized($this->date, $this);
|
||||
$businessUserItem->makeUserFromModel($user); // Erst User-Model laden, ohne forceLiveCalculation
|
||||
$this->addUserIdToProcessed($userId);
|
||||
$this->businessUsers[] = $businessUserItem;
|
||||
|
||||
$this->logger->info("Created businessUserItem for user {$userId}, total businessUsers: " . count($this->businessUsers));
|
||||
|
||||
// Prüfe gespeicherte Struktur nur, wenn Live-Berechnung nicht erzwungen wird
|
||||
$storedStructure = null;
|
||||
if (!$forceLiveCalculation) {
|
||||
$storedStructure = $this->repository->getStoredStructure();
|
||||
$this->logger->info("Stored structure " . ($storedStructure ? "found" : "not found"));
|
||||
}
|
||||
|
||||
if ($storedStructure && !$forceLiveCalculation) {
|
||||
$this->loadStoredParentsUsers($storedStructure);
|
||||
if (isset($this->businessUsers[0]) && $this->businessUsers[0]->sponsor) {
|
||||
$this->loadStoredSponsorUser($this->businessUsers[0]->sponsor->user_id);
|
||||
}
|
||||
} else {
|
||||
if ($forceLiveCalculation) {
|
||||
$this->logger->info("Forcing live calculation - skipping stored structure for user {$userId}");
|
||||
}
|
||||
$this->loadParentsUsers();
|
||||
$this->loadSponsorUser($userId);
|
||||
|
||||
$totalSubUsers = 0;
|
||||
foreach ($this->businessUsers as $businessUser) {
|
||||
$totalSubUsers += count($businessUser->businessUserItems);
|
||||
}
|
||||
$this->logger->info("After loadParentsUsers: {$totalSubUsers} total sub-users loaded across " . count($this->businessUsers) . " business users");
|
||||
|
||||
// WICHTIG: calcQualPP() erst NACH loadParentsUsers() aufrufen, da Points benötigt werden
|
||||
if ($forceLiveCalculation) {
|
||||
$this->logger->info("Calculating qualification levels for all business users");
|
||||
foreach ($this->businessUsers as $businessUser) {
|
||||
$businessUser->calcQualPP();
|
||||
}
|
||||
//wird nicht benötigt, da hier nur die Points berechnet werden
|
||||
//$this->calculateQualPPForAllUsers(); // Auch für alle Sub-User
|
||||
}
|
||||
}
|
||||
} catch (\Exception $e) {
|
||||
$this->logger->error("Error initializing user structure for {$userId}: " . $e->getMessage());
|
||||
throw $e;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Initialisiert detaillierte Business-User-Informationen
|
||||
*
|
||||
* @param User $user Das User-Model
|
||||
* @param bool $forceLiveCalculation Erzwingt Live-Berechnung und überspringt gespeicherte Daten
|
||||
*/
|
||||
public function initBusinesslUserDetail(User $user, bool $forceLiveCalculation = false): void
|
||||
{
|
||||
try {
|
||||
$this->logger->info("Initializing business user details for: {$user->id}");
|
||||
|
||||
$this->businessUser = new BusinessUserItemOptimized($this->date, $this);
|
||||
$this->businessUser->makeUserFromModel($user, $forceLiveCalculation); // ✅ Nutzt bereits User-Objekt
|
||||
$this->businessUser->checkSponsor($user);
|
||||
|
||||
// Führe vollständige Berechnung durch, wenn:
|
||||
// 1. Daten nicht gespeichert sind ODER
|
||||
// 2. Live-Berechnung erzwungen wird
|
||||
if (!$this->businessUser->isSave() || $forceLiveCalculation) {
|
||||
if ($forceLiveCalculation) {
|
||||
$this->logger->info("Forcing live calculation for user {$user->id}");
|
||||
}
|
||||
|
||||
// Aufbau der Struktur für den User in die unendliche Tiefe
|
||||
$this->businessUser->readParentsBusinessUsers($forceLiveCalculation);
|
||||
|
||||
// Calculate Points in Lines (optimiert für Memory-Effizienz)
|
||||
if (count($this->businessUser->businessUserItems) > 0) {
|
||||
$this->calculateUserPointsOptimized($this->businessUser->businessUserItems, 1, $this->businessUser);
|
||||
}
|
||||
// Qualifikation nach qual_kp (KundenPoints) und qual_pp (PaylinePoints)
|
||||
$this->businessUser->calcQualPP();
|
||||
}
|
||||
} catch (\Exception $e) {
|
||||
$this->logger->error("Error initializing business user details for {$user->id}: " . $e->getMessage());
|
||||
throw $e;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Gibt Growth Bonus zurück (ab Linie 6)
|
||||
* Erweitert um Array/Object-Kompatibilität für business_lines
|
||||
*/
|
||||
public function getGrowthBonus(): array
|
||||
{
|
||||
if (!$this->businessUser || !$this->businessUser->business_lines) {
|
||||
return [];
|
||||
}
|
||||
|
||||
if (count($this->businessUser->business_lines) > 6) {
|
||||
// Handle both array and object types (JSON deserialization inconsistency)
|
||||
if (is_array($this->businessUser->business_lines)) {
|
||||
$bLines = $this->businessUser->business_lines;
|
||||
} else {
|
||||
$bLines = $this->businessUser->business_lines->toArray();
|
||||
}
|
||||
return array_slice($bLines, 6);
|
||||
}
|
||||
|
||||
return [];
|
||||
}
|
||||
|
||||
/**
|
||||
* Gibt Wert für spezifische Linie zurück
|
||||
*/
|
||||
public function getKeybyLine(int $line, string $key)
|
||||
{
|
||||
if (!$this->businessUser || !$this->businessUser->business_lines) {
|
||||
return 0;
|
||||
}
|
||||
|
||||
$bLines = $this->businessUser->business_lines;
|
||||
if (!isset($bLines[$line])) {
|
||||
return 0;
|
||||
}
|
||||
|
||||
$lineData = $bLines[$line];
|
||||
|
||||
if ($lineData instanceof stdClass) {
|
||||
return $lineData->{$key} ?? 0;
|
||||
}
|
||||
|
||||
if (is_array($lineData)) {
|
||||
return $lineData[$key] ?? 0;
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
/**
|
||||
* HTML-Rendering Methoden (Delegation an Renderer)
|
||||
*/
|
||||
public function makeHtmlTree(): string
|
||||
{
|
||||
return $this->renderer->renderTree($this->businessUsers);
|
||||
}
|
||||
|
||||
public function makeParentlessHtml(): string
|
||||
{
|
||||
return $this->renderer->renderParentless($this->parentless);
|
||||
}
|
||||
|
||||
public function makeSponsorHtml(): string
|
||||
{
|
||||
return $this->renderer->renderSponsor($this->sponsor);
|
||||
}
|
||||
|
||||
/**
|
||||
* Getter-Methoden (Rückwärtskompatibilität)
|
||||
*/
|
||||
public function getItems(): array
|
||||
{
|
||||
return $this->businessUsers;
|
||||
}
|
||||
|
||||
/**
|
||||
* Zählt die Gesamtanzahl aller User in der Struktur (rekursiv)
|
||||
*/
|
||||
public function getTotalUserCount(): int
|
||||
{
|
||||
$totalCount = 0;
|
||||
|
||||
// Zähle alle Root-User
|
||||
$totalCount += count($this->businessUsers);
|
||||
|
||||
// Zähle alle Unter-User rekursiv
|
||||
foreach ($this->businessUsers as $businessUser) {
|
||||
$totalCount += $this->countBusinessUserItems($businessUser);
|
||||
}
|
||||
|
||||
// Zähle parentless User
|
||||
$totalCount += count($this->parentless);
|
||||
|
||||
return $totalCount;
|
||||
}
|
||||
|
||||
/**
|
||||
* Zählt BusinessUserItems rekursiv
|
||||
*/
|
||||
private function countBusinessUserItems($businessUserItem): int
|
||||
{
|
||||
$count = 0;
|
||||
|
||||
if (isset($businessUserItem->businessUserItems) && is_array($businessUserItem->businessUserItems)) {
|
||||
$count += count($businessUserItem->businessUserItems);
|
||||
|
||||
// Rekursiv durch alle Unter-Items zählen
|
||||
foreach ($businessUserItem->businessUserItems as $subItem) {
|
||||
$count += $this->countBusinessUserItems($subItem);
|
||||
}
|
||||
}
|
||||
|
||||
return $count;
|
||||
}
|
||||
|
||||
public function isParentless(): bool
|
||||
{
|
||||
return !empty($this->parentless);
|
||||
}
|
||||
|
||||
/**
|
||||
* Static Methoden (Rückwärtskompatibilität)
|
||||
*/
|
||||
public static function isFromStored(int $month, int $year): ?UserBusinessStructure
|
||||
{
|
||||
$structure = UserBusinessStructure::where('year', $year)
|
||||
->where('month', $month)
|
||||
->first();
|
||||
|
||||
return ($structure && $structure->completed) ? $structure : null;
|
||||
}
|
||||
|
||||
/**
|
||||
* Öffentliche Methode zum Hinzufügen einer User ID zu den verarbeiteten IDs
|
||||
*/
|
||||
public function addProcessedUserId(int $id): void
|
||||
{
|
||||
$this->addUserIdToProcessed($id);
|
||||
}
|
||||
|
||||
public static function addUserID(int $id): void
|
||||
{
|
||||
// Deprecated: Statische Methode kann nicht auf Instanz-Variable zugreifen
|
||||
// Verwende stattdessen die Instanz-Methode addProcessedUserId()
|
||||
throw new \BadMethodCallException('addUserID ist deprecated. Verwende Instanz-Methode addProcessedUserId() stattdessen.');
|
||||
}
|
||||
|
||||
// ===== Private Methoden =====
|
||||
|
||||
/**
|
||||
* Validiert Eingabeparameter
|
||||
*/
|
||||
private function validateInput(int $month, int $year): void
|
||||
{
|
||||
if ($month < 1 || $month > 12) {
|
||||
throw new \InvalidArgumentException("Invalid month: {$month}");
|
||||
}
|
||||
|
||||
$currentYear = (int) date('Y');
|
||||
if ($year < 2020 || $year > $currentYear + 1) {
|
||||
throw new \InvalidArgumentException("Invalid year: {$year}");
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Initialisiert Datums-Objekt
|
||||
*/
|
||||
private function initializeDate(int $month, int $year): void
|
||||
{
|
||||
$this->date = new stdClass();
|
||||
$date = Carbon::parse($year . '-' . $month . '-1');
|
||||
$this->date->month = $month;
|
||||
$this->date->year = $year;
|
||||
$this->date->start_date = $date->format('Y-m-d H:i:s');
|
||||
$this->date->end_date = $date->endOfMonth()->format('Y-m-d H:i:s');
|
||||
}
|
||||
|
||||
/**
|
||||
* Lädt gespeicherte Struktur
|
||||
*/
|
||||
private function loadStoredStructure(UserBusinessStructure $structure): void
|
||||
{
|
||||
$this->loadStoredRootUsers($structure);
|
||||
$this->loadStoredParentsUsers($structure);
|
||||
$this->loadStoredParentlessUsers($structure);
|
||||
|
||||
// Prüfe ob gespeicherte Daten vollständig sind, ansonsten berechne neu
|
||||
$this->validateAndRecalculateIfNeeded();
|
||||
$this->validateAndRecalculateParentlessIfNeeded();
|
||||
}
|
||||
|
||||
/**
|
||||
* Baut frische Struktur auf
|
||||
*/
|
||||
private function buildFreshStructure(): void
|
||||
{
|
||||
$this->loadRootUsers();
|
||||
$this->loadParentsUsers();
|
||||
$this->loadParentlessUsers();
|
||||
|
||||
// WICHTIG: Berechne Punkte und Qualifikationen für alle Business-Users
|
||||
$this->calculateAllBusinessUsers();
|
||||
$this->calculateAllParentlessUsers();
|
||||
}
|
||||
|
||||
/**
|
||||
* Lädt Root-Users (optimiert mit Memory-Monitoring)
|
||||
*/
|
||||
private function loadRootUsers(): void
|
||||
{
|
||||
$startMemory = memory_get_usage();
|
||||
$users = $this->repository->getRootUsers();
|
||||
foreach ($users as $user) {
|
||||
// Memory-Check vor jeder User-Verarbeitung
|
||||
$this->checkMemoryUsage('loadRootUsers', $user->id);
|
||||
|
||||
$businessUserItem = new BusinessUserItemOptimized($this->date, $this);
|
||||
$businessUserItem->makeUserFromModel($user, $this->forceLiveCalculation); // ✅ Nutzt bereits geladene Relations mit forceLiveCalculation
|
||||
$this->addUserIdToProcessed($user->id);
|
||||
$this->businessUsers[] = $businessUserItem;
|
||||
}
|
||||
|
||||
$endMemory = memory_get_usage();
|
||||
$memoryUsed = $this->formatBytes($endMemory - $startMemory);
|
||||
|
||||
$this->logger->info("Loaded " . count($users) . " root users with optimized relations. Memory used: {$memoryUsed}");
|
||||
}
|
||||
|
||||
/**
|
||||
* Lädt Parent-Users für alle Business-Users
|
||||
*/
|
||||
private function loadParentsUsers(): void
|
||||
{
|
||||
$this->logger->info("Loading parent users for " . count($this->businessUsers) . " business users");
|
||||
|
||||
foreach ($this->businessUsers as $businessUser) {
|
||||
$businessUser->readParentsBusinessUsers($this->forceLiveCalculation);
|
||||
|
||||
$this->logger->debug("Loaded " . count($businessUser->businessUserItems) . " parent users for user " . ($businessUser->b_user->user_id ?? 'unknown'));
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Lädt parentlose Users (Memory-optimiert)
|
||||
*/
|
||||
private function loadParentlessUsers(): void
|
||||
{
|
||||
$count = 0;
|
||||
$excludeIds = array_keys($this->processedUserIds);
|
||||
|
||||
foreach ($this->repository->getParentlessUsers($excludeIds) as $user) {
|
||||
$businessUserItem = new BusinessUserItemOptimized($this->date, $this);
|
||||
$businessUserItem->makeUserFromModel($user, $this->forceLiveCalculation); // ✅ Nutzt bereits geladene Relations mit forceLiveCalculation
|
||||
$this->parentless[] = $businessUserItem;
|
||||
$count++;
|
||||
}
|
||||
|
||||
$this->logger->info("Loaded {$count} parentless users with optimized relations");
|
||||
}
|
||||
|
||||
/**
|
||||
* Berechnet Punkte und Qualifikationen für alle Business-Users
|
||||
*/
|
||||
private function calculateAllBusinessUsers(): void
|
||||
{
|
||||
$startTime = microtime(true);
|
||||
$this->logger->info("Starting calculation for " . count($this->businessUsers) . " business users");
|
||||
|
||||
foreach ($this->businessUsers as $businessUser) {
|
||||
try {
|
||||
// Berechne Punkte in Linien (wie bei initBusinesslUserDetail)
|
||||
if (count($businessUser->businessUserItems) > 0) {
|
||||
$this->calculateUserPointsOptimized($businessUser->businessUserItems, 1, $businessUser);
|
||||
}
|
||||
|
||||
// Qualifikation nach qual_kp und qual_pp berechnen
|
||||
$businessUser->calcQualPP();
|
||||
} catch (\Exception $e) {
|
||||
$this->logger->error("Error calculating business user {$businessUser->__get('user_id')}: " . $e->getMessage());
|
||||
// Weiter mit dem nächsten User, nicht abbrechen
|
||||
continue;
|
||||
}
|
||||
}
|
||||
|
||||
$endTime = microtime(true);
|
||||
$executionTime = round(($endTime - $startTime) * 1000, 2);
|
||||
$this->logger->info("Completed calculations for all business users in {$executionTime}ms");
|
||||
}
|
||||
|
||||
/**
|
||||
* Berechnet Punkte und Qualifikationen für alle Parentless-Users
|
||||
*/
|
||||
private function calculateAllParentlessUsers(): void
|
||||
{
|
||||
if (empty($this->parentless)) {
|
||||
return;
|
||||
}
|
||||
|
||||
$startTime = microtime(true);
|
||||
$this->logger->info("Starting calculation for " . count($this->parentless) . " parentless users");
|
||||
|
||||
foreach ($this->parentless as $parentlessUser) {
|
||||
try {
|
||||
// Berechne Punkte in Linien
|
||||
if (count($parentlessUser->businessUserItems) > 0) {
|
||||
$this->calculateUserPointsOptimized($parentlessUser->businessUserItems, 1, $parentlessUser);
|
||||
}
|
||||
|
||||
// Qualifikation berechnen
|
||||
$parentlessUser->calcQualPP();
|
||||
} catch (\Exception $e) {
|
||||
$this->logger->error("Error calculating parentless user {$parentlessUser->__get('user_id')}: " . $e->getMessage());
|
||||
continue;
|
||||
}
|
||||
}
|
||||
|
||||
$endTime = microtime(true);
|
||||
$executionTime = round(($endTime - $startTime) * 1000, 2);
|
||||
$this->logger->info("Completed calculations for all parentless users in {$executionTime}ms");
|
||||
}
|
||||
|
||||
/**
|
||||
* Validiert gespeicherte Daten und berechnet bei Bedarf neu
|
||||
*/
|
||||
private function validateAndRecalculateIfNeeded(): void
|
||||
{
|
||||
$incompleteUsers = 0;
|
||||
|
||||
foreach ($this->businessUsers as $businessUser) {
|
||||
// Prüfe ob grundlegende Berechnungen vorhanden sind
|
||||
if ($this->isBusinessUserIncomplete($businessUser)) {
|
||||
$incompleteUsers++;
|
||||
|
||||
try {
|
||||
// Führe fehlende Berechnungen durch
|
||||
if (count($businessUser->businessUserItems) > 0) {
|
||||
$this->calculateUserPointsOptimized($businessUser->businessUserItems, 1, $businessUser);
|
||||
}
|
||||
$businessUser->calcQualPP();
|
||||
} catch (\Exception $e) {
|
||||
$this->logger->error("Error recalculating business user {$businessUser->__get('user_id')}: " . $e->getMessage());
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if ($incompleteUsers > 0) {
|
||||
$this->logger->info("Recalculated {$incompleteUsers} incomplete business users from stored data");
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Prüft ob ein BusinessUser unvollständige Daten hat
|
||||
* Erweitert um Level-Qualifikationsdaten für Struktur-Ansicht
|
||||
*/
|
||||
private function isBusinessUserIncomplete($businessUser): bool
|
||||
{
|
||||
// Prüfe grundlegende Felder die nach Berechnungen vorhanden sein sollten
|
||||
$salesVolumeSum = $businessUser->__get('sales_volume_points_sum');
|
||||
$qualKp = $businessUser->__get('qual_kp');
|
||||
|
||||
// Prüfe Level-Qualifikationsdaten für Struktur-Ansicht
|
||||
$nextQualUserLevel = $businessUser->__get('next_qual_user_level');
|
||||
$nextCanUserLevel = $businessUser->__get('next_can_user_level');
|
||||
$hasLevelQualificationData = !empty($nextQualUserLevel) || !empty($nextCanUserLevel);
|
||||
|
||||
// User ist unvollständig wenn:
|
||||
// 1. Grundlegende berechnete Werte fehlen ODER
|
||||
// 2. Level-Qualifikationsdaten fehlen (wichtig für Struktur-Ansicht mit grünen Pfeilen)
|
||||
$missingBasicData = ($salesVolumeSum === null || $salesVolumeSum === 0) &&
|
||||
($qualKp === null || $qualKp === 0);
|
||||
|
||||
$missingLevelData = !$hasLevelQualificationData;
|
||||
|
||||
return $missingBasicData || $missingLevelData;
|
||||
}
|
||||
|
||||
/**
|
||||
* Validiert und berechnet parentless Users bei Bedarf neu
|
||||
*/
|
||||
private function validateAndRecalculateParentlessIfNeeded(): void
|
||||
{
|
||||
if (empty($this->parentless)) {
|
||||
return;
|
||||
}
|
||||
|
||||
$incompleteUsers = 0;
|
||||
|
||||
foreach ($this->parentless as $parentlessUser) {
|
||||
if ($this->isBusinessUserIncomplete($parentlessUser)) {
|
||||
$incompleteUsers++;
|
||||
|
||||
try {
|
||||
if (count($parentlessUser->businessUserItems) > 0) {
|
||||
$this->calculateUserPointsOptimized($parentlessUser->businessUserItems, 1, $parentlessUser);
|
||||
}
|
||||
$parentlessUser->calcQualPP();
|
||||
} catch (\Exception $e) {
|
||||
$this->logger->error("Error recalculating parentless user {$parentlessUser->__get('user_id')}: " . $e->getMessage());
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if ($incompleteUsers > 0) {
|
||||
$this->logger->info("Recalculated {$incompleteUsers} incomplete parentless users from stored data");
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Lädt Sponsor für User
|
||||
*/
|
||||
private function loadSponsorUser(int $userId): void
|
||||
{
|
||||
try {
|
||||
$sponsorUser = $this->repository->getSponsorForUser($userId);
|
||||
|
||||
if ($sponsorUser) {
|
||||
$this->sponsor = new BusinessUserItemOptimized($this->date, $this);
|
||||
$this->sponsor->makeUser($sponsorUser->id);
|
||||
$this->logger->info("Loaded sponsor {$sponsorUser->id} for user {$userId}");
|
||||
}
|
||||
} catch (\Exception $e) {
|
||||
$this->logger->warning("Could not load sponsor for user {$userId}: " . $e->getMessage());
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Gespeicherte Root-Users laden
|
||||
*/
|
||||
private function loadStoredRootUsers(UserBusinessStructure $structure): void
|
||||
{
|
||||
if (!$structure->structure) {
|
||||
return;
|
||||
}
|
||||
|
||||
foreach ($structure->structure as $obj) {
|
||||
$businessUserItem = new BusinessUserItemOptimized($this->date, $this);
|
||||
$businessUserItem->makeUser($obj->user_id);
|
||||
$this->addUserIdToProcessed($obj->user_id);
|
||||
$this->businessUsers[] = $businessUserItem;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Gespeicherte Parent-Users laden
|
||||
*/
|
||||
private function loadStoredParentsUsers(UserBusinessStructure $structure): void
|
||||
{
|
||||
foreach ($this->businessUsers as $businessUser) {
|
||||
$businessUser->readStoredParentsBusinessUsers($structure->structure);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Gespeicherte parentlose Users laden
|
||||
*/
|
||||
private function loadStoredParentlessUsers(UserBusinessStructure $structure): void
|
||||
{
|
||||
if (!$structure->parentless) {
|
||||
return;
|
||||
}
|
||||
|
||||
foreach ($structure->parentless as $obj) {
|
||||
if (!isset($this->processedUserIds[$obj->user_id])) {
|
||||
$businessUserItem = new BusinessUserItemOptimized($this->date, $this);
|
||||
$businessUserItem->makeUser($obj->user_id);
|
||||
$this->parentless[] = $businessUserItem;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Gespeicherten Sponsor laden
|
||||
*/
|
||||
private function loadStoredSponsorUser(int $userId): void
|
||||
{
|
||||
$this->sponsor = new BusinessUserItemOptimized($this->date, $this);
|
||||
$this->sponsor->makeUser($userId);
|
||||
}
|
||||
|
||||
/**
|
||||
* Optimierte Punkte-Berechnung (Stack-basiert mit korrekter Depth-First Reihenfolge)
|
||||
*
|
||||
* KRITISCH: Stack muss gleiche Reihenfolge wie Original-Rekursion produzieren
|
||||
* Original: Depth-First Traversierung (erst tief, dann Punkte addieren)
|
||||
* Stack: Muss umgekehrt arbeiten - erst alle Kinder sammeln, dann von tief zu flach verarbeiten
|
||||
*/
|
||||
private function calculateUserPointsOptimized(array $businessUserItems, int $startLine, BusinessUserItemOptimized $businessUserToUpdate): void
|
||||
{
|
||||
$processingStack = [];
|
||||
$collectionStack = []; // Sammelt Items in korrekter Reihenfolge
|
||||
|
||||
// Phase 1: Sammle alle Items in Depth-First Reihenfolge
|
||||
foreach ($businessUserItems as $item) {
|
||||
$collectionStack[] = ['item' => $item, 'line' => $startLine, 'depth' => 0];
|
||||
}
|
||||
|
||||
// Expandiere alle Kinder (Depth-First)
|
||||
$processedItems = [];
|
||||
while (!empty($collectionStack)) {
|
||||
$current = array_shift($collectionStack); // FIFO für Breadth-First Sammlung
|
||||
$item = $current['item'];
|
||||
$line = $current['line'];
|
||||
$depth = $current['depth'];
|
||||
|
||||
// Markiere für Verarbeitung (mit Tiefe für spätere Sortierung)
|
||||
$processingStack[] = [
|
||||
'item' => $item,
|
||||
'line' => $line,
|
||||
'depth' => $depth,
|
||||
'id' => $item->user_id ?? uniqid()
|
||||
];
|
||||
|
||||
// Füge Kinder hinzu (werden später verarbeitet = Depth-First)
|
||||
if (isset($item->businessUserItems) && count($item->businessUserItems) > 0) {
|
||||
// Kinder in umgekehrter Reihenfolge hinzufügen für korrekte Stack-Verarbeitung
|
||||
$children = array_reverse($item->businessUserItems);
|
||||
foreach ($children as $childItem) {
|
||||
array_unshift($collectionStack, [
|
||||
'item' => $childItem,
|
||||
'line' => $line + 1,
|
||||
'depth' => $depth + 1
|
||||
]);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// Phase 2: Sortiere nach Tiefe (tiefste zuerst, wie bei Rekursion)
|
||||
usort($processingStack, function ($a, $b) {
|
||||
return $b['depth'] <=> $a['depth']; // Tiefste zuerst
|
||||
});
|
||||
|
||||
// Phase 3: Verarbeite in korrekter Reihenfolge (von tief zu flach)
|
||||
foreach ($processingStack as $current) {
|
||||
$item = $current['item'];
|
||||
$line = $current['line'];
|
||||
|
||||
try {
|
||||
// Business Line initialisieren falls nötig
|
||||
if (!isset($businessUserToUpdate->business_lines[$line])) {
|
||||
$obj = new stdClass();
|
||||
$obj->points = 0;
|
||||
$businessUserToUpdate->addBusinessLineToUser($line, $obj);
|
||||
}
|
||||
|
||||
// Punkte hinzufügen (mit Validierung)
|
||||
$points = (float) ($item->sales_volume_points_TP_sum ?? 0);
|
||||
if ($points > 0) {
|
||||
$businessUserToUpdate->addBusinessLinePoints($line, $points);
|
||||
$businessUserToUpdate->addTotalTP($points);
|
||||
}
|
||||
|
||||
$this->logger->debug("Processed user {$current['id']} at line {$line} with {$points} points");
|
||||
} catch (\Exception $e) {
|
||||
$this->logger->error("Error processing user points for {$current['id']}: " . $e->getMessage());
|
||||
}
|
||||
}
|
||||
|
||||
$this->logger->info("Processed " . count($processingStack) . " business user items in depth-first order");
|
||||
}
|
||||
|
||||
/**
|
||||
* User-ID zu verarbeiteten IDs hinzufügen
|
||||
*/
|
||||
private function addUserIdToProcessed(int $id): void
|
||||
{
|
||||
$this->processedUserIds[$id] = true;
|
||||
}
|
||||
|
||||
/**
|
||||
* Prüft ob User bereits verarbeitet wurde (Public für BusinessUserItemOptimized)
|
||||
*/
|
||||
public function isUserProcessed(int $id): bool
|
||||
{
|
||||
return isset($this->processedUserIds[$id]);
|
||||
}
|
||||
|
||||
/**
|
||||
* Memory-Monitoring Methoden
|
||||
*/
|
||||
private function checkMemoryUsage(string $operation, $identifier = null): void
|
||||
{
|
||||
$currentMemory = memory_get_usage();
|
||||
$memoryLimit = $this->parseMemoryLimit(ini_get('memory_limit'));
|
||||
$memoryPercent = ($currentMemory / $memoryLimit) * 100;
|
||||
|
||||
if ($memoryPercent > 80) {
|
||||
$currentFormatted = $this->formatBytes($currentMemory);
|
||||
$limitFormatted = $this->formatBytes($memoryLimit);
|
||||
|
||||
$this->logger->warning("High memory usage detected in {$operation}", [
|
||||
'identifier' => $identifier,
|
||||
'current_memory' => $currentFormatted,
|
||||
'memory_limit' => $limitFormatted,
|
||||
'usage_percent' => round($memoryPercent, 2)
|
||||
]);
|
||||
|
||||
// Garbage Collection bei hohem Memory-Verbrauch
|
||||
if ($memoryPercent > 90) {
|
||||
$this->logger->warning("Critical memory usage - forcing garbage collection");
|
||||
gc_collect_cycles();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private function parseMemoryLimit(string $limit): int
|
||||
{
|
||||
$limit = trim($limit);
|
||||
$last = strtolower($limit[strlen($limit) - 1]);
|
||||
$number = (int) $limit;
|
||||
|
||||
switch ($last) {
|
||||
case 'g':
|
||||
$number *= 1024;
|
||||
case 'm':
|
||||
$number *= 1024;
|
||||
case 'k':
|
||||
$number *= 1024;
|
||||
}
|
||||
|
||||
return $number;
|
||||
}
|
||||
|
||||
private function formatBytes(int $bytes, int $precision = 2): string
|
||||
{
|
||||
$units = array('B', 'KB', 'MB', 'GB', 'TB');
|
||||
|
||||
for ($i = 0; $bytes > 1024 && $i < count($units) - 1; $i++) {
|
||||
$bytes /= 1024;
|
||||
}
|
||||
|
||||
return round($bytes, $precision) . ' ' . $units[$i];
|
||||
}
|
||||
|
||||
/**
|
||||
* Public Properties für Rückwärtskompatibilität
|
||||
*/
|
||||
public function __get(string $name)
|
||||
{
|
||||
switch ($name) {
|
||||
case 'date':
|
||||
return $this->date;
|
||||
case 'business_user':
|
||||
return $this->businessUser;
|
||||
case 'business_users':
|
||||
return $this->businessUsers;
|
||||
case 'parentless':
|
||||
return $this->parentless;
|
||||
default:
|
||||
throw new \InvalidArgumentException("Property {$name} does not exist");
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Berechnet calcQualPP() für alle BusinessUsers rekursiv
|
||||
* Muss NACH loadParentsUsers() aufgerufen werden, da Points benötigt werden
|
||||
*/
|
||||
private function calculateQualPPForAllUsers(): void
|
||||
{
|
||||
$this->logger->info("Starting recursive calcQualPP for all users");
|
||||
$totalCalculated = 0;
|
||||
|
||||
foreach ($this->businessUsers as $businessUser) {
|
||||
$totalCalculated += $this->calculateQualPPRecursive($businessUser);
|
||||
}
|
||||
|
||||
$this->logger->info("Completed calcQualPP for {$totalCalculated} users");
|
||||
}
|
||||
|
||||
/**
|
||||
* Rekursive Hilfsmethode für calcQualPP
|
||||
*/
|
||||
private function calculateQualPPRecursive($businessUser): int
|
||||
{
|
||||
$calculated = 0;
|
||||
|
||||
if (isset($businessUser->businessUserItems) && is_array($businessUser->businessUserItems)) {
|
||||
foreach ($businessUser->businessUserItems as $subBusinessUser) {
|
||||
if ($subBusinessUser->b_user && $subBusinessUser->b_user->user_id) {
|
||||
try {
|
||||
$subBusinessUser->calcQualPP();
|
||||
$calculated++;
|
||||
$this->logger->debug("Calculated calcQualPP for user " . $subBusinessUser->b_user->user_id);
|
||||
} catch (\Exception $e) {
|
||||
$this->logger->warning("Error calculating calcQualPP for user " . $subBusinessUser->b_user->user_id . ": " . $e->getMessage());
|
||||
}
|
||||
|
||||
// Rekursiver Aufruf
|
||||
$calculated += $this->calculateQualPPRecursive($subBusinessUser);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return $calculated;
|
||||
}
|
||||
|
||||
public function __set(string $name, $value)
|
||||
{
|
||||
switch ($name) {
|
||||
case 'business_users':
|
||||
$this->businessUsers = $value;
|
||||
break;
|
||||
case 'parentless':
|
||||
$this->parentless = $value;
|
||||
break;
|
||||
default:
|
||||
throw new \InvalidArgumentException("Property {$name} cannot be set");
|
||||
}
|
||||
}
|
||||
}
|
||||
185
dev/app-bak/Services/BusinessPlan/TreeHelperOptimized.php
Normal file
185
dev/app-bak/Services/BusinessPlan/TreeHelperOptimized.php
Normal file
|
|
@ -0,0 +1,185 @@
|
|||
<?php
|
||||
|
||||
namespace App\Services\BusinessPlan;
|
||||
|
||||
use App\User;
|
||||
use App\Models\UserBusiness;
|
||||
|
||||
|
||||
/**
|
||||
* Klasse für die HTML-Darstellung von Business-Trees
|
||||
* Trennt Präsentationslogik von Geschäftslogik
|
||||
*/
|
||||
class TreeHelperOptimized
|
||||
{
|
||||
/**
|
||||
* Generiert QualKP Badge für UserBusiness
|
||||
*/
|
||||
public static function generateQualKPBadge(UserBusiness $userBusiness): string
|
||||
{
|
||||
if (!$userBusiness->m_level_id) {
|
||||
return '-';
|
||||
}
|
||||
|
||||
|
||||
$qualKP = (int) $userBusiness->qual_kp;
|
||||
$pointsSum = (int) $userBusiness->sales_volume_points_KP_sum;
|
||||
$isQual = $pointsSum >= $qualKP;
|
||||
$badgeClass = $isQual ? 'badge-outline-success' : 'badge-outline-info';
|
||||
|
||||
return '<span class="badge ' . $badgeClass . '"> KU ' . $qualKP . "/" . $pointsSum . '</span>';
|
||||
}
|
||||
|
||||
/**
|
||||
* Generiert QualKP Badge für User
|
||||
*/
|
||||
public static function generateQualKPBadgeForUser(User $user, int $month, int $year): string
|
||||
{
|
||||
if (!$user->user_level) {
|
||||
return '-';
|
||||
}
|
||||
|
||||
$qualKP = (int) $user->user_level->qual_kp;
|
||||
$pointsSum = (int) $user->getUserSalesVolumeBy($month, $year, 'sales_volume_points_KP_sum');
|
||||
$isQual = $pointsSum >= $qualKP;
|
||||
|
||||
$badgeClass = $isQual ? 'badge-outline-success' : 'badge-outline-warning-dark';
|
||||
|
||||
return '<span class="badge ' . $badgeClass . '"> KU ' . $qualKP . '</span>';
|
||||
}
|
||||
|
||||
/**
|
||||
* Generiert Sales Volume Display für UserBusiness
|
||||
*/
|
||||
public static function generateSalesVolumeDisplay(UserBusiness $userBusiness, string $type): string
|
||||
{
|
||||
if ($type === 'points') {
|
||||
$total = (int) $userBusiness->sales_volume_points_KP_sum;
|
||||
$individual = (int) $userBusiness->sales_volume_KP_points;
|
||||
$shop = (int) $userBusiness->sales_volume_points_shop;
|
||||
} else {
|
||||
$total = (float) $userBusiness->sales_volume_total_sum;
|
||||
$individual = (float) $userBusiness->sales_volume_total;
|
||||
$shop = (float) $userBusiness->sales_volume_total_shop;
|
||||
$suffix = ' €';
|
||||
}
|
||||
|
||||
$totalFormatted = $type === 'points' ? $total : formatNumber($total);
|
||||
$individualFormatted = $type === 'points' ? $individual : formatNumber($individual);
|
||||
$shopFormatted = $type === 'points' ? $shop : formatNumber($shop);
|
||||
$suffix = $type === 'points' ? '' : ' €';
|
||||
|
||||
return '<div class="no-line-break">' . $totalFormatted . $suffix . '</div>' .
|
||||
'<span class="small no-line-break">E: ' . $individualFormatted . ' | S: ' . $shopFormatted . $suffix . '</span>';
|
||||
}
|
||||
|
||||
/**
|
||||
* Generiert Sales Volume Display für User
|
||||
*/
|
||||
public static function generateSalesVolumeDisplayForUser(User $user, string $type, int $month, int $year): string
|
||||
{
|
||||
if ($type === 'points') {
|
||||
$total = (int) $user->getUserSalesVolumeBy($month, $year, 'sales_volume_points_KP_sum');
|
||||
$individual = (int) $user->getUserSalesVolumeBy($month, $year, 'sales_volume_KP_points');
|
||||
$shop = (int) $user->getUserSalesVolumeBy($month, $year, 'sales_volume_points_shop');
|
||||
} else {
|
||||
$total = (float) $user->getUserSalesVolumeBy($month, $year, 'sales_volume_total_sum');
|
||||
$individual = (float) $user->getUserSalesVolumeBy($month, $year, 'sales_volume_total');
|
||||
$shop = (float) $user->getUserSalesVolumeBy($month, $year, 'sales_volume_total_shop');
|
||||
}
|
||||
|
||||
$totalFormatted = $type === 'points' ? $total : formatNumber($total);
|
||||
$individualFormatted = $type === 'points' ? $individual : formatNumber($individual);
|
||||
$shopFormatted = $type === 'points' ? $shop : formatNumber($shop);
|
||||
$suffix = $type === 'points' ? '' : ' €';
|
||||
|
||||
return '<div class="no-line-break">' . $totalFormatted . $suffix . '</div>' .
|
||||
'<span class="small no-line-break">E: ' . $individualFormatted . ' | S: ' . $shopFormatted . $suffix . '</span>';
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
/**
|
||||
* Generiert Action Buttons (mit XSS-Schutz)
|
||||
*/
|
||||
public static function generateActionButtons($userId): string
|
||||
{
|
||||
$userId = (int) $userId; // Sicherheit: Nur Integer
|
||||
|
||||
$html = '<button type="button" class="btn icon-btn btn-xs btn-secondary" data-toggle="modal" data-target="#modals-load-content"
|
||||
data-id="' . $userId . '"
|
||||
data-action="business-user-detail"
|
||||
data-back=""
|
||||
data-modal="modal-xl"
|
||||
data-init_from="admin"
|
||||
data-optimized="true"
|
||||
data-route="' . route('modal_load') . '"><span class="fa fa-calculator"></span></button>';
|
||||
|
||||
if (config('app.debug') === true) {
|
||||
$html .= '<a href="' . route('admin_business_optimized_user_detail', [$userId]) . '" class="btn icon-btn btn-xs btn-primary"><span class="fa fa-calculator"></span></a>';
|
||||
}
|
||||
|
||||
return $html;
|
||||
}
|
||||
|
||||
/**
|
||||
* Generiert Sponsor Display für UserBusiness
|
||||
*/
|
||||
public static function generateSponsorDisplay(UserBusiness $userBusiness): string
|
||||
{
|
||||
if (!$userBusiness->sponsor || !$userBusiness->sponsor->is_sponsor) {
|
||||
return '-';
|
||||
}
|
||||
|
||||
$sponsor = $userBusiness->sponsor;
|
||||
$html = e($sponsor->first_name . ' ' . $sponsor->last_name);
|
||||
|
||||
$html .= ' <button type="button" class="btn icon-btn btn-xs btn-secondary" data-toggle="modal" data-target="#modals-load-content"
|
||||
data-id="' . (int) $sponsor->user_id . '"
|
||||
data-action="business-user-detail"
|
||||
data-back=""
|
||||
data-modal="modal-xl"
|
||||
data-init_from="admin"
|
||||
data-optimized="true"
|
||||
data-route="' . route('modal_load') . '"><span class="fa fa-calculator"></span></button><br>';
|
||||
|
||||
$html .= '<span class="small no-line-break">' . e($sponsor->email);
|
||||
$html .= ' | ' . e($sponsor->m_account);
|
||||
$html .= '</span>';
|
||||
|
||||
return $html;
|
||||
}
|
||||
|
||||
/**
|
||||
* Generiert Sponsor Display für User
|
||||
*/
|
||||
public static function generateSponsorDisplayForUser(User $user): string
|
||||
{
|
||||
if (!$user->user_sponsor) {
|
||||
return '-';
|
||||
}
|
||||
|
||||
$sponsor = $user->user_sponsor;
|
||||
$html = '';
|
||||
|
||||
if ($sponsor->account) {
|
||||
$html .= e($sponsor->account->first_name . ' ' . $sponsor->account->last_name);
|
||||
$html .= ' <button type="button" class="btn icon-btn btn-xs btn-secondary" data-toggle="modal" data-target="#modals-load-content"
|
||||
data-id="' . (int) $sponsor->id . '"
|
||||
data-action="business-user-detail"
|
||||
data-back=""
|
||||
data-modal="modal-xl"
|
||||
data-init_from="admin"
|
||||
data-route="' . route('modal_load') . '"><span class="fa fa-calculator"></span></button><br>';
|
||||
}
|
||||
|
||||
$html .= '<span class="small no-line-break">' . e($sponsor->email);
|
||||
if ($sponsor->account) {
|
||||
$html .= ' | ' . e($sponsor->account->m_account);
|
||||
}
|
||||
$html .= '</span>';
|
||||
|
||||
return $html;
|
||||
}
|
||||
}
|
||||
391
dev/app-bak/Services/BusinessPlan/TreeHtmlRenderer.php
Normal file
391
dev/app-bak/Services/BusinessPlan/TreeHtmlRenderer.php
Normal file
|
|
@ -0,0 +1,391 @@
|
|||
<?php
|
||||
|
||||
namespace App\Services\BusinessPlan;
|
||||
|
||||
use App\Services\TranslationHelper;
|
||||
|
||||
/**
|
||||
* Klasse für die HTML-Darstellung von Business-Trees
|
||||
* Trennt Präsentationslogik von Geschäftslogik
|
||||
*/
|
||||
class TreeHtmlRenderer
|
||||
{
|
||||
private string $initFrom;
|
||||
private bool $forceLiveCalculation;
|
||||
|
||||
public function __construct(string $initFrom = 'member', bool $forceLiveCalculation = false)
|
||||
{
|
||||
$this->initFrom = $initFrom;
|
||||
$this->forceLiveCalculation = $forceLiveCalculation;
|
||||
}
|
||||
|
||||
/**
|
||||
* Rendert den kompletten Business-Tree als HTML
|
||||
*/
|
||||
public function renderTree(array $businessUsers): string
|
||||
{
|
||||
if (empty($businessUsers)) {
|
||||
return '<div class="alert alert-info">Keine Business-User gefunden.</div>';
|
||||
}
|
||||
|
||||
$html = '<ol class="dd-list">';
|
||||
foreach ($businessUsers as $businessUser) {
|
||||
$html .= $this->renderUserItem($businessUser, 0);
|
||||
}
|
||||
$html .= '</ol>';
|
||||
|
||||
return $html;
|
||||
}
|
||||
|
||||
/**
|
||||
* Rendert parentlose User als HTML
|
||||
*/
|
||||
public function renderParentless(array $parentless): string
|
||||
{
|
||||
if (empty($parentless)) {
|
||||
return '<div class="alert alert-info">Keine parentlosen User gefunden.</div>';
|
||||
}
|
||||
|
||||
$html = '';
|
||||
foreach ($parentless as $item) {
|
||||
$html .= $this->renderParentlessItem($item);
|
||||
}
|
||||
|
||||
return $html;
|
||||
}
|
||||
|
||||
/**
|
||||
* Rendert Sponsor-Information als HTML
|
||||
*/
|
||||
public function renderSponsor($sponsor): string
|
||||
{
|
||||
if (!$sponsor) {
|
||||
return '<div class="alert alert-warning">' . __('team.no_sponsor_assigned') . '</div>';
|
||||
}
|
||||
|
||||
return '<li class="dd-item dd-nodrag" data-id="">' .
|
||||
'<div class="dd-handle">' .
|
||||
$this->renderUserInfo($sponsor, false, true) .
|
||||
'</div>' .
|
||||
'</li>';
|
||||
}
|
||||
|
||||
/**
|
||||
* Rendert User Team Tree (für UserTeamCalcBot)
|
||||
*/
|
||||
public function renderUserTeamTree(array $teamMembers): string
|
||||
{
|
||||
if (empty($teamMembers)) {
|
||||
return '<div class="alert alert-info">Keine Team-Mitglieder gefunden.</div>';
|
||||
}
|
||||
|
||||
$html = '<ol class="dd-list">';
|
||||
foreach ($teamMembers as $member) {
|
||||
$html .= $this->renderTeamMemberItem($member, 0);
|
||||
}
|
||||
$html .= '</ol>';
|
||||
|
||||
return $html;
|
||||
}
|
||||
|
||||
/**
|
||||
* Rendert User Sponsor (für UserTeamCalcBot)
|
||||
*/
|
||||
public function renderUserSponsor(\App\User $sponsor): string
|
||||
{
|
||||
if (!$sponsor || !$sponsor->account) {
|
||||
return '<div class="alert alert-info">Kein Sponsor gefunden.</div>';
|
||||
}
|
||||
|
||||
$html = '<div class="dd-item">';
|
||||
$html .= '<div class="dd-handle">';
|
||||
$html .= '<div class="row">';
|
||||
|
||||
// Sponsor Info
|
||||
$html .= '<div class="col-md-3">';
|
||||
$html .= '<strong>' . e($sponsor->account->first_name . ' ' . $sponsor->account->last_name) . '</strong><br>';
|
||||
$html .= '<small>' . e($sponsor->email) . '</small>';
|
||||
$html .= '</div>';
|
||||
|
||||
// Account Info
|
||||
$html .= '<div class="col-md-2">';
|
||||
$html .= '<span class="badge badge-secondary">' . e($sponsor->account->m_account ?? '') . '</span>';
|
||||
$html .= '</div>';
|
||||
|
||||
// Level Info
|
||||
$html .= '<div class="col-md-2">';
|
||||
if ($sponsor->user_level) {
|
||||
$html .= '<span class="badge badge-primary">' . e($sponsor->user_level->getLang('name')) . '</span>';
|
||||
}
|
||||
$html .= '</div>';
|
||||
|
||||
// Status
|
||||
$html .= '<div class="col-md-2">';
|
||||
$html .= get_active_badge($sponsor->isActiveAccount());
|
||||
$html .= '</div>';
|
||||
|
||||
$html .= '</div>';
|
||||
$html .= '</div>';
|
||||
$html .= '</div>';
|
||||
|
||||
return $html;
|
||||
}
|
||||
|
||||
/**
|
||||
* Rendert einzelnes Team-Mitglied
|
||||
*/
|
||||
private function renderTeamMemberItem($member, int $depth): string
|
||||
{
|
||||
$html = '<li class="dd-item" data-id="' . ($member->user_id ?? 0) . '">';
|
||||
$html .= '<div class="dd-handle">';
|
||||
$html .= '<div class="row">';
|
||||
|
||||
// Einrückung basierend auf Tiefe
|
||||
$indent = str_repeat(' ', $depth);
|
||||
|
||||
// Name und Email
|
||||
$html .= '<div class="col-md-3">';
|
||||
$html .= $indent;
|
||||
$html .= '<strong>' . e(($member->first_name ?? '') . ' ' . ($member->last_name ?? '')) . '</strong><br>';
|
||||
$html .= $indent . '<small>' . e($member->email ?? '') . '</small>';
|
||||
$html .= '</div>';
|
||||
|
||||
// Account ID
|
||||
$html .= '<div class="col-md-2">';
|
||||
$html .= '<span class="badge badge-secondary">' . e($member->m_account ?? '') . '</span>';
|
||||
$html .= '</div>';
|
||||
|
||||
// Level
|
||||
$html .= '<div class="col-md-2">';
|
||||
if (!empty($member->user_level_name)) {
|
||||
$html .= '<span class="badge badge-primary">' . e($member->user_level_name) . '</span>';
|
||||
|
||||
if ($member->next_qual_user_level) {
|
||||
$html .= '<span class="badge badge-outline-success ml-2"><i class="fa fa-arrow-up text-success" title="Karriere-Level erreicht!"></i></span>';
|
||||
}
|
||||
}
|
||||
$html .= '</div>';
|
||||
|
||||
// Qualifikation
|
||||
$html .= '<div class="col-md-2">';
|
||||
if (!empty($member->qual_kp)) {
|
||||
$pointsSum = (int) ($member->sales_volume_points_KP_sum ?? 0);
|
||||
$qualKP = (int) $member->qual_kp;
|
||||
$isQual = $pointsSum >= $qualKP;
|
||||
$badgeClass = $isQual ? 'badge-success' : 'badge-warning';
|
||||
$html .= '<span class="badge ' . $badgeClass . '">KU ' . $qualKP . '</span>';
|
||||
}
|
||||
$html .= '</div>';
|
||||
|
||||
// Status
|
||||
$html .= '<div class="col-md-2">';
|
||||
$html .= get_active_badge($member->active_account ?? 0);
|
||||
$html .= '</div>';
|
||||
|
||||
$html .= '</div>';
|
||||
$html .= '</div>';
|
||||
|
||||
// Kinder rendern
|
||||
if (!empty($member->businessUserItems) && is_array($member->businessUserItems)) {
|
||||
$html .= '<ol class="dd-list">';
|
||||
foreach ($member->businessUserItems as $child) {
|
||||
$html .= $this->renderTeamMemberItem($child, $depth + 1);
|
||||
}
|
||||
$html .= '</ol>';
|
||||
}
|
||||
|
||||
$html .= '</li>';
|
||||
|
||||
return $html;
|
||||
}
|
||||
|
||||
/**
|
||||
* Rendert einen einzelnen User-Item mit Hierarchie
|
||||
*/
|
||||
private function renderUserItem($item, int $deep): string
|
||||
{
|
||||
$childrenHtml = '';
|
||||
if ($item->businessUserItems && count($item->businessUserItems) > 0) {
|
||||
$childrenHtml = '<ol class="dd-list dd-nodrag">';
|
||||
foreach ($item->businessUserItems as $child) {
|
||||
$childrenHtml .= $this->renderUserItem($child, $deep + 1);
|
||||
}
|
||||
$childrenHtml .= '</ol>';
|
||||
}
|
||||
|
||||
return '<li class="dd-item dd-nodrag" data-id="' . $item->user_id . '">' .
|
||||
'<div class="dd-handle">' .
|
||||
$this->renderUserCardWithDepth($item, $deep) .
|
||||
'</div>' .
|
||||
$childrenHtml .
|
||||
'</li>';
|
||||
}
|
||||
|
||||
/**
|
||||
* Rendert parentlosen User-Item
|
||||
*/
|
||||
private function renderParentlessItem($item): string
|
||||
{
|
||||
return '<li class="dd-item dd-nodrag" data-id="' . $item->user_id . '">' .
|
||||
'<div class="dd-handle">' .
|
||||
$this->renderUserInfo($item, true, false) .
|
||||
'</div>' .
|
||||
'</li>';
|
||||
}
|
||||
|
||||
/**
|
||||
* Rendert User-Card mit Tiefe-Anzeige
|
||||
*/
|
||||
private function renderUserCardWithDepth($item, int $deep): string
|
||||
{
|
||||
$depthBadge = '';
|
||||
if ($deep > 0) {
|
||||
$depthBadge = '<div class="d-flex flex-column justify-content-center align-items-center">' .
|
||||
'<div class="text-large font-weight-bolder line-height-1 my-2 text-secondary badge badge-outline-secondary">' . $deep . '</div>' .
|
||||
'</div>';
|
||||
}
|
||||
|
||||
return '<div class="media align-items-center">' .
|
||||
$depthBadge .
|
||||
'<div class="media-body ml-2">' .
|
||||
$this->renderUserInfo($item, false, false) .
|
||||
'</div>' .
|
||||
'</div>';
|
||||
}
|
||||
|
||||
/**
|
||||
* Rendert die Basis-User-Informationen
|
||||
*/
|
||||
private function renderUserInfo($item, bool $showSponsor = false, bool $isSponsor = false): string
|
||||
{
|
||||
$statusClass = $item->active_account ? '' : 'text-muted';
|
||||
$iconClass = $item->active_account ? 'text-primary' : 'text-danger';
|
||||
|
||||
\Log::debug("TreeHtmlRenderer: Rendering user info for user {$item->user_id}");
|
||||
|
||||
$html = '<span class="' . $statusClass . '">';
|
||||
|
||||
// User Link
|
||||
$html .= '<a href="#" class="text-black" data-toggle="modal" data-target="#modals-load-content" ' .
|
||||
'data-id="' . $item->user_id . '" data-action="business-user-show" data-back="" ' .
|
||||
'data-modal="modal-md" data-init_from="' . $this->initFrom . '" data-route="' . route('modal_load') . '">' .
|
||||
'<span class="mr-1 ion ion-ios-contact ' . $iconClass . '"></span> ' .
|
||||
'<strong>' . e($item->first_name . ' ' . $item->last_name) . '</strong>' .
|
||||
'</a>';
|
||||
|
||||
// Email
|
||||
$html .= ' <a href="mailto:' . e($item->email) . '">' . e($item->email) . '</a>';
|
||||
|
||||
// Optional: Geburtstag
|
||||
$birthday = $item->user_birthday; // Magic Method __get() verwenden
|
||||
if ($birthday && trim($birthday) !== '') {
|
||||
$html .= ' | <i class="ion ion-ios-gift text-primary"></i> ' . e($birthday);
|
||||
}
|
||||
|
||||
// Optional: Telefon
|
||||
$phone = $item->user_phone; // Magic Method __get() verwenden
|
||||
if ($phone && trim($phone) !== '') {
|
||||
$html .= ' | <i class="ion ion-ios-call text-primary"></i> ' . e($phone);
|
||||
}
|
||||
|
||||
// Level Badge
|
||||
$levelName = $item->user_level_name ? TranslationHelper::transUserLevelName($item->user_level_name) : '';
|
||||
$account = $item->m_account ?: '';
|
||||
$html .= ' <span class="badge badge-outline-default ' . $statusClass . '">' . e($levelName . ' | ' . $account) . '</span>';
|
||||
|
||||
// Karriere-Aufstiegs-Icon für qualifizierte User (nur in Struktur-Ansicht)#
|
||||
|
||||
if ($item->next_qual_user_level) {
|
||||
$html .= '<span class="badge badge-outline-success ml-2"><i class="fa fa-arrow-up text-success" title="Karriere-Level erreicht!"></i></span>';
|
||||
}
|
||||
|
||||
// Details für aktive Accounts
|
||||
if ($item->active_account) {
|
||||
$html .= '<br><span class="small">';
|
||||
if(!$isSponsor){
|
||||
$html .= $this->renderAccountDetails($item);
|
||||
}
|
||||
|
||||
// Action Button (außer für Sponsor-Ansicht)
|
||||
if (!$isSponsor && $this->shouldShowActionButton()) {
|
||||
$html .= $this->renderActionButton($item->user_id);
|
||||
}
|
||||
|
||||
$html .= '</span>';
|
||||
} else {
|
||||
// Inaktive Accounts
|
||||
$paymentDate = $item->payment_account_date ?: '';
|
||||
$html .= '<br><span class="small">' . __('team.account_to') . ': ' . e($paymentDate) . '</span>';
|
||||
}
|
||||
|
||||
// Sponsor für parentlose User
|
||||
if ($showSponsor && $item->m_sponsor_name) {
|
||||
$html .= '<br>' . e($item->m_sponsor_name);
|
||||
}
|
||||
|
||||
$html .= '</span>';
|
||||
|
||||
return $html;
|
||||
}
|
||||
|
||||
/**
|
||||
* Rendert Account-Details (Punkte, Umsatz)
|
||||
*/
|
||||
private function renderAccountDetails($item): string
|
||||
{
|
||||
$totalPoints = $item->sales_volume_points_KP_sum ?: 0;
|
||||
$ePoints = $item->sales_volume_KP_points ?: 0;
|
||||
$sPoints = $item->sales_volume_points_shop ?: 0;
|
||||
|
||||
$totalSum = $item->sales_volume_total_sum ?: 0;
|
||||
$eSum = $item->sales_volume_total ?: 0;
|
||||
$sSum = $item->sales_volume_total_shop ?: 0;
|
||||
|
||||
return '<strong>' . __('team.total_points') . ': ' . $totalPoints . '</strong> | ' .
|
||||
__('team.e') . ': ' . $ePoints . ' | ' .
|
||||
__('team.s') . ': ' . $sPoints . ' <strong> | ' .
|
||||
__('team.net_turnover') . ': ' . formatNumber($totalSum) . ' €</strong> | ' .
|
||||
__('team.e') . ': ' . formatNumber($eSum) . ' € | ' .
|
||||
__('team.s') . ': ' . formatNumber($sSum) . ' €';
|
||||
}
|
||||
|
||||
/**
|
||||
* Rendert Action-Button für User-Details
|
||||
*/
|
||||
private function renderActionButton(int $userId): string
|
||||
{
|
||||
return ' | <button type="button" class="btn icon-btn btn-xs btn-secondary" ' .
|
||||
'data-toggle="modal" data-target="#modals-load-content" ' .
|
||||
'data-id="' . $userId . '" data-action="business-user-detail" ' .
|
||||
'data-back="" data-modal="modal-xl" ' .
|
||||
'data-init_from="' . $this->initFrom . '" ' .
|
||||
'data-live="' . $this->forceLiveCalculation . '" ' .
|
||||
'data-optimized="1" ' .
|
||||
'data-route="' . route('modal_load') . '">' .
|
||||
'<span class="fa fa-calculator"></span>' .
|
||||
'</button>';
|
||||
}
|
||||
|
||||
/**
|
||||
* Prüft ob Action-Button angezeigt werden soll
|
||||
*/
|
||||
private function shouldShowActionButton(): bool
|
||||
{
|
||||
try {
|
||||
return ($this->initFrom === 'admin' && \Auth::check() && \Auth::user()->isAdmin()) ||
|
||||
($this->initFrom === 'member');
|
||||
} catch (\Exception $e) {
|
||||
// Fallback for tests or when no user is authenticated
|
||||
return $this->initFrom === 'member';
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Setzt den Kontext für die Darstellung
|
||||
*/
|
||||
public function setInitFrom(string $initFrom): self
|
||||
{
|
||||
$this->initFrom = $initFrom;
|
||||
return $this;
|
||||
}
|
||||
}
|
||||
92
dev/app-bak/Services/Credit.php
Normal file
92
dev/app-bak/Services/Credit.php
Normal file
|
|
@ -0,0 +1,92 @@
|
|||
<?php
|
||||
namespace App\Services;
|
||||
|
||||
use App\Services\Util;
|
||||
use App\Models\Setting;
|
||||
use App\Mail\MailCredit;
|
||||
use App\Models\UserCredit;
|
||||
use Illuminate\Support\Facades\Mail;
|
||||
|
||||
class Credit
|
||||
{
|
||||
|
||||
public static function getCreditNumber(){
|
||||
//return (int) Setting::getContentBySlug('credit-number');
|
||||
return (int) Setting::getContentBySlug('invoice-number');
|
||||
}
|
||||
|
||||
|
||||
public static function makeNextCreditNumber(){
|
||||
$credit_number = self::getCreditNumber();
|
||||
$credit_number = $credit_number+1;
|
||||
//Setting::setContentBySlug('credit-number', $credit_number, 'int');
|
||||
Setting::setContentBySlug('invoice-number', $credit_number, 'int');
|
||||
return $credit_number;
|
||||
}
|
||||
|
||||
public static function createCreditNumber($credit_number, $credit_date){
|
||||
|
||||
$prefix = "GS".\Carbon::parse($credit_date)->format('Y');
|
||||
$credit_number = str_pad($credit_number, 5, '0', STR_PAD_LEFT);
|
||||
return $prefix.$credit_number;
|
||||
}
|
||||
|
||||
public static function getCreditStorageDir($credit_date){
|
||||
return "/credit/".\Carbon::parse($credit_date)->format('Y/m/');
|
||||
}
|
||||
|
||||
public static function getCreditDetailStorageDir($credit_date){
|
||||
return "/credit_details/".\Carbon::parse($credit_date)->format('Y/m/');
|
||||
}
|
||||
|
||||
public static function makeCreditFilename($credit_number){
|
||||
return $credit_number."-MIVITA-Gutschrift.pdf";
|
||||
}
|
||||
|
||||
public static function makeCreditDetailFilename($credit_number){
|
||||
return $credit_number."-MIVITA-Report.pdf";
|
||||
}
|
||||
|
||||
public static function isCredit(UserCredit $user_credit){
|
||||
return $user_credit->isCredit();
|
||||
}
|
||||
|
||||
/*public static function getFilename(UserCredit $user_credit){
|
||||
return $user_credit->filename;
|
||||
}
|
||||
|
||||
|
||||
public static function getDir(UserCredit $user_credit){
|
||||
return $user_credit->dir;
|
||||
}
|
||||
|
||||
public static function getDownloadURL(UserCredit $user_credit, $do = false){
|
||||
return route('storage_file', [$user_credit->id, 'cms_download_file', $do]);
|
||||
}
|
||||
|
||||
public static function getDownloadPath(UserCredit $user_credit, $full = false){
|
||||
$dir = self::getDir($user_credit);
|
||||
$filename = self::getFilename($user_credit);
|
||||
if(!$full){
|
||||
return $dir.$filename;
|
||||
}
|
||||
return \Storage::disk('public')->path($dir.$filename);
|
||||
}*/
|
||||
|
||||
public static function sendCreditMail(UserCredit $user_credit){
|
||||
$bcc = [];
|
||||
$email = $user_credit->user->email;
|
||||
if(!$email){
|
||||
if($user_credit->user->mode === 'test'){
|
||||
}else{
|
||||
$email = config('app.checkout_mail');
|
||||
}
|
||||
}
|
||||
if($user_credit->user->mode === 'test'){
|
||||
$bcc[] = config('app.checkout_test_mail');
|
||||
}else{
|
||||
$bcc[] = config('app.checkout_mail');
|
||||
}
|
||||
Mail::to($email)->bcc($bcc)->locale($user_credit->user->getLocale())->send(new MailCredit($user_credit));
|
||||
}
|
||||
}
|
||||
336
dev/app-bak/Services/CustomerPriority.php
Normal file
336
dev/app-bak/Services/CustomerPriority.php
Normal file
|
|
@ -0,0 +1,336 @@
|
|||
<?php
|
||||
namespace App\Services;
|
||||
|
||||
|
||||
use App\Mail\MailCheckout;
|
||||
use App\Mail\MailInfo;
|
||||
use App\Models\ShoppingUser;
|
||||
use App\Services\BusinessPlan\SalesPointsVolume;
|
||||
use App\Services\Shop;
|
||||
use App\User;
|
||||
use Auth;
|
||||
use Illuminate\Support\Facades\Mail;
|
||||
|
||||
|
||||
|
||||
class CustomerPriority
|
||||
{
|
||||
|
||||
protected static $start_number = 1000;
|
||||
protected static $user_notice_key = 'like';
|
||||
|
||||
public static function checkForAll(){
|
||||
//only extern no members with no numbers
|
||||
$shopping_users = ShoppingUser::where('auth_user_id', '=', NULL)->where('number', '=', NULL)->orderBy('created_at', 'ASC')->get();
|
||||
foreach ($shopping_users as $shopping_user){
|
||||
if($shopping_user->shopping_order && $shopping_user->shopping_order->user_shop){
|
||||
self::checkOne($shopping_user);
|
||||
}
|
||||
}
|
||||
return $shopping_users;
|
||||
}
|
||||
|
||||
public static function checkOne($shopping_user, $mail=false, $newCustomer = true, $entryExistsLike = false){
|
||||
//ist die Mail ein Berater, dann sich selbst zuweisen.
|
||||
if(self::entryIsMember($shopping_user)){
|
||||
return 'self';
|
||||
}
|
||||
//look for entry
|
||||
if($entryExistsLike){
|
||||
if(self::entryExistsLike($shopping_user)){ //existiert die Email bei einem anderem member?
|
||||
if($mail){ //send mail
|
||||
Mail::to(config('app.priority_mail'))->send(new MailInfo($shopping_user, 'check_is_like_customer'));
|
||||
}
|
||||
return 'exists';
|
||||
}
|
||||
}else{
|
||||
if(self::entryExists($shopping_user)){ //Berater zuweisen, wenn die Mail existiert
|
||||
return 'exists';
|
||||
}
|
||||
}
|
||||
if(self::entryLike($shopping_user)){ //existiert die Adresse bei einem anderem member?
|
||||
if($mail){ //send mail
|
||||
Mail::to(config('app.priority_mail'))->send(new MailInfo($shopping_user, 'check_is_like_customer'));
|
||||
}
|
||||
return 'like'.$shopping_user->member_id;
|
||||
}
|
||||
if($newCustomer){
|
||||
self::newCustomer($shopping_user);
|
||||
}
|
||||
return 'new';
|
||||
|
||||
}
|
||||
|
||||
public static function setIsLike($shopping_user, $set_like_shopping_user, $send_member_mail, $change_shopping_user=false)
|
||||
{
|
||||
if ($shopping_user->id === $set_like_shopping_user->id) {
|
||||
//set new customer for shopping_user
|
||||
if($change_shopping_user){
|
||||
self::newCustomerNumber($shopping_user);
|
||||
$send_member_mail = false;
|
||||
}else{
|
||||
self::newCustomer($shopping_user);
|
||||
}
|
||||
} else {
|
||||
//set existing customer for shopping_user
|
||||
self::existingCustomer($shopping_user, $set_like_shopping_user);
|
||||
}
|
||||
self::clearIsLike($shopping_user);
|
||||
//SEND MAIL TO MEMBER
|
||||
if ($send_member_mail){
|
||||
if ($shopping_user->shopping_order && $shopping_user->shopping_order->shopping_payments) {
|
||||
Mail::to($shopping_user->member->email)->send(new MailCheckout($shopping_user->shopping_order->txaction, $shopping_user->shopping_order, $shopping_user->shopping_order->shopping_payments->last(), false, $shopping_user->shopping_order->mode));
|
||||
}
|
||||
}
|
||||
//set Points and Volume
|
||||
if ($shopping_user->shopping_order && $user_sales_volume = $shopping_user->shopping_order->user_sales_volume_no_userid()) {
|
||||
SalesPointsVolume::setToUserAndReCalculate($user_sales_volume, $shopping_user->member_id);
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
public static function newMemberForOrder($shopping_order, $member_id, Bool $all = false){
|
||||
if($all){
|
||||
if($shopping_order->shopping_user && $shopping_order->shopping_user->number){
|
||||
$shopping_users = ShoppingUser::where('number', '=', $shopping_order->shopping_user->number)->get();
|
||||
$new_number = self::nextNumber();
|
||||
foreach ($shopping_users as $shopping_user) {
|
||||
self::changeCustomer($shopping_user, $member_id, $new_number);
|
||||
}
|
||||
}
|
||||
}else{
|
||||
$shopping_order->member_id = $member_id;
|
||||
$shopping_order->save();
|
||||
if($shopping_order->shopping_user){
|
||||
$shopping_order->shopping_user->member_id = $member_id;
|
||||
$shopping_order->shopping_user->number = self::nextNumber();
|
||||
$shopping_order->shopping_user->save();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public static function newMemberForCustomer($shopping_user, $member_id, Bool $all = false){
|
||||
if($all){
|
||||
if($shopping_user && $shopping_user->number){
|
||||
$shopping_users = ShoppingUser::where('number', '=', $shopping_user->number)->get();
|
||||
$new_number = self::nextNumber();
|
||||
foreach ($shopping_users as $s_user) {
|
||||
self::changeCustomer($s_user, $member_id, $new_number);
|
||||
}
|
||||
}
|
||||
}else{
|
||||
$shopping_user->member_id = $member_id;
|
||||
$shopping_user->number = self::nextNumber();
|
||||
$shopping_user->save();
|
||||
if($shopping_user->shopping_order){
|
||||
$shopping_user->shopping_order->member_id = $member_id;
|
||||
$shopping_user->shopping_order->save();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public static function checkChangeOne($shopping_user, $data, $mail=false){
|
||||
|
||||
$matches = [];
|
||||
$change = [];
|
||||
$ret = 'update';
|
||||
|
||||
//email geändert
|
||||
if(isset($data['billing_email']) && $shopping_user->billing_email != $data['billing_email']){
|
||||
$found = ShoppingUser::where('auth_user_id', '=', NULL)
|
||||
->where('number', '!=', NULL) //has number
|
||||
->where('id', '!=', $shopping_user->id)
|
||||
->where('billing_email', '=', $data['billing_email'])
|
||||
->where('member_id', '!=', $shopping_user->member_id)
|
||||
->get()->pluck('number', 'id')->unique()->toArray();
|
||||
if($found && count($found)){
|
||||
foreach ($found as $key=>$val){
|
||||
$matches[$key] = $val;
|
||||
}
|
||||
$ret = 'exists';
|
||||
$change['billing_email'] = $data['billing_email'];
|
||||
}
|
||||
}
|
||||
//Anschrift geändert
|
||||
if(isset($data['billing_lastname']) && isset($data['billing_zipcode']) && ($shopping_user->billing_lastname != $data['billing_lastname'] || $shopping_user->billing_zipcode != $data['billing_zipcode'])){
|
||||
$found = ShoppingUser::select('*')
|
||||
->where('auth_user_id', '=', NULL)
|
||||
->where('number', '!=', NULL) //has number
|
||||
->where('id', '!=', $shopping_user->id)
|
||||
->where('billing_lastname', '=', $data['billing_lastname'])
|
||||
->where('billing_zipcode', '=', $data['billing_zipcode'])
|
||||
->where('member_id', '!=', $shopping_user->member_id)
|
||||
->get()->pluck('number', 'id')->unique()->toArray();
|
||||
if($found && count($found)){
|
||||
foreach ($found as $key=>$val){
|
||||
$matches[$key] = $val;
|
||||
}
|
||||
$ret = 'like';
|
||||
$change['billing_lastname'] = $data['billing_lastname'];
|
||||
$change['billing_zipcode'] = $data['billing_zipcode'];
|
||||
}
|
||||
}
|
||||
if($matches){
|
||||
$shopping_user->is_like = true;
|
||||
$shopping_user->setNotice(self::$user_notice_key, $matches);
|
||||
$shopping_user->save();
|
||||
}
|
||||
//look for entry
|
||||
if($matches && $mail){ //send mail
|
||||
Mail::to(config('app.priority_mail'))->send(new MailInfo($shopping_user, 'change_is_like_customer', $change));
|
||||
}
|
||||
|
||||
return $ret;
|
||||
|
||||
}
|
||||
|
||||
|
||||
|
||||
public static function checkNewOne($shopping_user, $mail=false){
|
||||
if(self::entryLike($shopping_user)){
|
||||
if($mail){ //send mail
|
||||
Mail::to(config('app.priority_mail'))->send(new MailInfo($shopping_user, 'check_is_like_customer'));
|
||||
}
|
||||
//return 'like';
|
||||
}
|
||||
$shopping_user->number = self::nextNumber();
|
||||
$shopping_user->save();
|
||||
return true;
|
||||
}
|
||||
|
||||
public static function entryIsMember($shopping_user){
|
||||
if($user = User::whereEmail($shopping_user->billing_email)->whereActive(1)->first()){
|
||||
$member_id = $user->id;
|
||||
$shopping_user->member_id = $member_id;
|
||||
$shopping_user->number = self::nextNumber();
|
||||
$shopping_user->save();
|
||||
if($shopping_user->shopping_order){
|
||||
$shopping_user->shopping_order->member_id = $member_id;
|
||||
$shopping_user->shopping_order->save();
|
||||
}
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
private static function entryExists($shopping_user){
|
||||
//check same email
|
||||
$matches = ShoppingUser::where('auth_user_id', '=', NULL)
|
||||
->where('number', '!=', NULL) //has number
|
||||
->where('id', '!=', $shopping_user->id)
|
||||
->where('billing_email', '=', $shopping_user->billing_email)->get();
|
||||
|
||||
if($matches && count($matches)){
|
||||
$match = $matches->last();
|
||||
$shopping_user->member_id = $match->member_id;
|
||||
$shopping_user->number = $match->number;
|
||||
$shopping_user->save();
|
||||
//has order
|
||||
if($shopping_user->shopping_order){
|
||||
$shopping_user->shopping_order->member_id = $match->member_id;
|
||||
$shopping_user->shopping_order->save();
|
||||
}
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
private static function entryExistsLike($shopping_user)
|
||||
{
|
||||
//existiert die Email bei einem anderem member?
|
||||
$matches = ShoppingUser::where('auth_user_id', '=', NULL)
|
||||
->where('number', '!=', NULL) //has number
|
||||
->where('id', '!=', $shopping_user->id)
|
||||
->where('member_id', '!=', $shopping_user->member_id)
|
||||
->where('billing_email', '=', $shopping_user->billing_email)
|
||||
->get()->pluck('number', 'id')->unique()->toArray();
|
||||
|
||||
if($matches && count($matches)){
|
||||
$shopping_user->is_like = true;
|
||||
$shopping_user->setNotice(self::$user_notice_key, $matches);
|
||||
$shopping_user->save();
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
private static function entryLike($shopping_user){
|
||||
//check same last name und PLZ
|
||||
$matches = ShoppingUser::select('*')
|
||||
->where('auth_user_id', '=', NULL)
|
||||
->where('number', '!=', NULL) //has number
|
||||
->where('id', '!=', $shopping_user->id)
|
||||
->where('member_id', '!=', $shopping_user->member_id)
|
||||
->where('billing_lastname', '=', $shopping_user->billing_lastname)
|
||||
->where('billing_zipcode', '=', $shopping_user->billing_zipcode)
|
||||
->get()->pluck('number', 'id')->unique()->toArray();
|
||||
if($matches && count($matches)){
|
||||
$shopping_user->is_like = true;
|
||||
$shopping_user->setNotice(self::$user_notice_key, $matches);
|
||||
$shopping_user->save();
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
private static function newCustomer($shopping_user){
|
||||
if($shopping_user->shopping_order && $shopping_user->shopping_order->user_shop) {
|
||||
$member_id = $shopping_user->shopping_order->user_shop->user_id;
|
||||
$shopping_user->member_id = $member_id;
|
||||
$shopping_user->number = self::nextNumber();
|
||||
$shopping_user->save();
|
||||
$shopping_user->shopping_order->member_id = $member_id;
|
||||
$shopping_user->shopping_order->save();
|
||||
}
|
||||
}
|
||||
|
||||
private static function newCustomerNumber($shopping_user)
|
||||
{
|
||||
\App\Services\Shop::newUserOrder($shopping_user->number);
|
||||
$shopping_user->number = self::nextNumber();
|
||||
$shopping_user->save();
|
||||
\App\Services\Shop::newUserOrder($shopping_user->number);
|
||||
|
||||
}
|
||||
|
||||
private static function changeCustomer($shopping_user, $member_id, $number){
|
||||
$old_number = $shopping_user->number;
|
||||
$shopping_user->member_id = $member_id;
|
||||
$shopping_user->number = $number;
|
||||
$shopping_user->save();
|
||||
if($shopping_user->shopping_order) {
|
||||
$shopping_user->shopping_order->member_id = $member_id;
|
||||
$shopping_user->shopping_order->save();
|
||||
}
|
||||
\App\Services\Shop::newUserOrder($old_number);
|
||||
\App\Services\Shop::newUserOrder($number);
|
||||
}
|
||||
|
||||
private static function existingCustomer($shopping_user, $set_like_shopping_user){
|
||||
$old_number = $shopping_user->number;
|
||||
$shopping_user->member_id = $set_like_shopping_user->member_id;
|
||||
$shopping_user->number = $set_like_shopping_user->number;
|
||||
$shopping_user->save();
|
||||
if($shopping_user->shopping_order) {
|
||||
$shopping_user->shopping_order->member_id = $set_like_shopping_user->member_id;
|
||||
$shopping_user->shopping_order->save();
|
||||
}
|
||||
\App\Services\Shop::newUserOrder($old_number);
|
||||
\App\Services\Shop::newUserOrder($set_like_shopping_user->number);
|
||||
}
|
||||
|
||||
private static function clearIsLike($shopping_user){
|
||||
$shopping_user->is_like = false;
|
||||
$shopping_user->removeNotice(self::$user_notice_key);
|
||||
$shopping_user->save();
|
||||
|
||||
}
|
||||
|
||||
private static function nextNumber (){
|
||||
if(!$number = ShoppingUser::max('number')){
|
||||
$number = self::$start_number;
|
||||
}
|
||||
return $number+1;
|
||||
}
|
||||
|
||||
}
|
||||
108
dev/app-bak/Services/DcHelper.php
Normal file
108
dev/app-bak/Services/DcHelper.php
Normal file
|
|
@ -0,0 +1,108 @@
|
|||
<?php
|
||||
namespace App\Services;
|
||||
|
||||
use App\Models\Tag;
|
||||
use App\Models\DcTag;
|
||||
use App\Models\FileTag;
|
||||
use App\Models\DcFileTag;
|
||||
|
||||
class DcHelper {
|
||||
|
||||
|
||||
public static $points;
|
||||
|
||||
public static function getTransChange(){
|
||||
|
||||
$langs = [
|
||||
'de' => ['name' => 'German', 'script' => 'Latn', 'native' => 'Deutsch', 'regional' => 'de_DE'],
|
||||
'en' => ['name' => 'English', 'script' => 'Latn', 'native' => 'English', 'regional' => 'en_GB'],
|
||||
'es' => ['name' => 'Spanish', 'script' => 'Latn', 'native' => 'español', 'regional' => 'es_ES'],
|
||||
];
|
||||
|
||||
$ret = [];
|
||||
foreach($langs as $code => $lang){
|
||||
$ret[strtolower($code)] = strtolower($lang['native']);
|
||||
}
|
||||
return $ret;
|
||||
}
|
||||
|
||||
public static function makeNestableList($category_id){
|
||||
$tags = DcTag::where('category_id', $category_id)->orderBy('pos')->get();
|
||||
$out = "";
|
||||
foreach ($tags as $tag){
|
||||
|
||||
$out .= '<li class="dd-item" data-id="'.$tag->id.'">
|
||||
<span class="pull-right">
|
||||
<a href="#" class="btn btn-sm mt-1 nestable_update_btn" data-action="update-tag-active" data-target="self" data-id="'.$tag->id.'" data-url="'.route('admin_downloadcenter_item_store', ['update_ajax']).'">
|
||||
' . ($tag->active ? '<i class="fa fa-eye text-success"></i>' : '<i class="fa fa-eye-slash text-danger"></i>') . '
|
||||
</a>
|
||||
<a href="'.route('admin_downloadcenter_item_delete', ['obj' => 'tag', 'id'=> $tag->id]).'" class="btn btn-sm mt-1 nestable_list_delete"><i class="fa fa-trash text-danger"></i></a>
|
||||
</span>
|
||||
<div class="dd-handle">
|
||||
'.$tag->name.'
|
||||
</div>
|
||||
</li>';
|
||||
}
|
||||
return $out;
|
||||
}
|
||||
|
||||
|
||||
public static function makeNestableListCheckbox($category_id, $file_id){
|
||||
|
||||
$tags = DcTag::where('category_id', $category_id)->orderBy('pos')->get();
|
||||
$file_tags = DcFileTag::where('file_id', $file_id)->get();
|
||||
|
||||
$search = array();
|
||||
foreach ($file_tags as $file_tag) {
|
||||
$search[] = $file_tag->tag_id;
|
||||
}
|
||||
|
||||
$out = "";
|
||||
foreach ($tags as $tag){
|
||||
$out .= '<li class="dd-item" data-id="'.$tag->id.'">
|
||||
<div class="dd-handle dd-nodrag">
|
||||
<label class="custom-control custom-checkbox m-0" for="nestable_check_'.$tag->id.'">
|
||||
<input type="checkbox" class="custom-control-input" name="nestable_check[]" id="nestable_check_'.$tag->id.'" value="'.$tag->id.'" '.(array_search($tag->id, $search) !== FALSE ? 'checked="checked"' : '').'>
|
||||
<span class="custom-control-label"> '.$tag->name.' </span>
|
||||
</label>
|
||||
</div>
|
||||
</li>';
|
||||
}
|
||||
return $out;
|
||||
}
|
||||
|
||||
public static function makeFilterList($filter_list, $split = false, $chunk = false){
|
||||
|
||||
$out = "";
|
||||
$splitOn = 0;
|
||||
if($split){
|
||||
$count = count($filter_list);
|
||||
if($count > 0){
|
||||
$splitOn = intval(ceil($count / $split));
|
||||
$filter_chunk = array_chunk($filter_list, $splitOn, true);
|
||||
$filter_list = $filter_chunk[$chunk];
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
foreach($filter_list as $category_id => $value){
|
||||
$out .= '<label class="form-label" for="category_'.$category_id.'">'.$value['name'].'</label>';
|
||||
$out .= '<select class="selectpicker category-filter" name="categories['.$category_id.'][]" id="category_'.$category_id.'" data-style="btn-light" data-live-search="true" multiple>';
|
||||
foreach($value['items'] as $tag){
|
||||
$out .= '<option value="'.$tag->id.'">'.$tag->name.' ('.$tag->count.')</option>';
|
||||
|
||||
}
|
||||
$out .= '</select>';
|
||||
|
||||
}
|
||||
return $out;
|
||||
}
|
||||
|
||||
private function getAttributesOptions($ids = array(), $all = true){
|
||||
$ret = "";
|
||||
|
||||
return $ret;
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
1312
dev/app-bak/Services/DhlApiService.php
Normal file
1312
dev/app-bak/Services/DhlApiService.php
Normal file
File diff suppressed because it is too large
Load diff
89
dev/app-bak/Services/DhlDataHelper.php
Normal file
89
dev/app-bak/Services/DhlDataHelper.php
Normal file
|
|
@ -0,0 +1,89 @@
|
|||
<?php
|
||||
|
||||
namespace App\Services;
|
||||
|
||||
use App\Models\ShoppingOrder;
|
||||
use App\Http\Controllers\SettingController;
|
||||
|
||||
/**
|
||||
* DHL Data Helper
|
||||
*
|
||||
* Central class for preparing DHL API data structures
|
||||
* Prevents code duplication between DhlShipmentService and CreateShipmentJob
|
||||
*/
|
||||
class DhlDataHelper
|
||||
{
|
||||
/**
|
||||
* Prepare order data for DHL API v2
|
||||
*
|
||||
* Structure matches official DHL API v2 createOrders endpoint:
|
||||
* https://developer.dhl.com/api-reference/parcel-de-shipping-post-parcel-germany-v2
|
||||
*
|
||||
* @param ShoppingOrder $order
|
||||
* @param float $weight
|
||||
* @param array $options
|
||||
* @param array|null $dhlConfig Optional pre-loaded config (for queue jobs)
|
||||
* @return array
|
||||
*/
|
||||
public static function prepareOrderData(ShoppingOrder $order, float $weight, array $options = [], ?array $dhlConfig = null): array
|
||||
{
|
||||
\Log::info('prepareOrderData', $options);
|
||||
//die daten für das versandlabel werden immer aus dem Formular genommen, damit anpassungen möglich sind
|
||||
if (!isset($options['shipping_address'])) {
|
||||
throw new \Exception('shipping_address is required');
|
||||
}
|
||||
$shippingAddress = $options['shipping_address'];
|
||||
|
||||
// Get DHL configuration for shipper data
|
||||
if ($dhlConfig === null) {
|
||||
$settingController = new SettingController();
|
||||
$dhlConfig = $settingController->getDhlConfig();
|
||||
}
|
||||
return [
|
||||
'order_id' => $order->id,
|
||||
'weight_kg' => $weight,
|
||||
'product_code' => $options['product_code'] ?? 'V01PAK',
|
||||
'label_format' => $options['label_format'] ?? $dhlConfig['label_format'] ?? 'PDF',
|
||||
'print_format' => $options['print_format'] ?? $dhlConfig['print_format'] ?? null,
|
||||
'retoure_print_format' => $options['retoure_print_format'] ?? $dhlConfig['retoure_print_format'] ?? null,
|
||||
|
||||
// Shipper data (sender) - from admin settings
|
||||
'shipper' => [
|
||||
'name' => $dhlConfig['sender']['company'] ?? 'mivita care gmbh',
|
||||
'name2' => $dhlConfig['sender']['name'] ?? '',
|
||||
'street' => $dhlConfig['sender']['street'] ?? 'Leinfeld',
|
||||
'houseNumber' => $dhlConfig['sender']['house_number'] ?? '2',
|
||||
'postalCode' => $dhlConfig['sender']['postalCode'] ?? '87755',
|
||||
'city' => $dhlConfig['sender']['city'] ?? 'Kirchhaslach',
|
||||
'country' => $dhlConfig['sender']['country'] ?? 'DE',
|
||||
'email' => $dhlConfig['sender']['email'] ?? 'versand@mivita.care',
|
||||
'phone' => $dhlConfig['sender']['phone'] ?? '+49 123 456789',
|
||||
],
|
||||
|
||||
// Consignee data (recipient) - from order
|
||||
'consignee' => [
|
||||
'name' => $shippingAddress['firstname'] ?? '' . ' ' . $shippingAddress['lastname'] ?? '',
|
||||
'name2' => $shippingAddress['company'] ?? '',
|
||||
'street' => $shippingAddress['address'] ?? '',
|
||||
'houseNumber' => $shippingAddress['houseNumber'] ?? '',
|
||||
'postalCode' => $shippingAddress['zipcode'] ?? '',
|
||||
'city' => $shippingAddress['city'] ?? '',
|
||||
'country' => $shippingAddress['country']?->code ?? 'DE',
|
||||
'email' => $shippingAddress['email'] ?? '',
|
||||
'phone' => $shippingAddress['phone'] ?? '',
|
||||
],
|
||||
// Package dimensions from options or defaults
|
||||
'dimensions' => [
|
||||
'length' => $options['length'] ?? 30,
|
||||
'width' => $options['width'] ?? 25,
|
||||
'height' => $options['height'] ?? 10,
|
||||
],
|
||||
|
||||
// Additional services
|
||||
'services' => $options['services'] ?? [],
|
||||
|
||||
// Custom reference for tracking
|
||||
'reference' => 'Order-' . $order->id,
|
||||
];
|
||||
}
|
||||
}
|
||||
439
dev/app-bak/Services/DhlModalService.php
Normal file
439
dev/app-bak/Services/DhlModalService.php
Normal file
|
|
@ -0,0 +1,439 @@
|
|||
<?php
|
||||
|
||||
namespace App\Services;
|
||||
|
||||
use App\Models\ShoppingOrder;
|
||||
use App\Models\Country;
|
||||
use Illuminate\Support\Facades\Log;
|
||||
use Exception;
|
||||
|
||||
/**
|
||||
* DHL Modal Service
|
||||
*
|
||||
* Service class that handles all business logic for the DHL shipment creation modal.
|
||||
* Validates order data, processes addresses, and prepares data for the view.
|
||||
*/
|
||||
class DhlModalService
|
||||
{
|
||||
/**
|
||||
* @var array DHL configuration
|
||||
*/
|
||||
private $config;
|
||||
|
||||
/**
|
||||
* Constructor
|
||||
*/
|
||||
public function __construct()
|
||||
{
|
||||
$this->config = config('dhl');
|
||||
}
|
||||
|
||||
/**
|
||||
* Prepare modal data for DHL shipment creation
|
||||
*
|
||||
* @param mixed $id Order ID or 'new'
|
||||
* @param array $data Additional data from the request
|
||||
* @return array Prepared data for the view
|
||||
* @throws Exception
|
||||
*/
|
||||
public function prepareModalData($id, array $data): array
|
||||
{
|
||||
$result = [
|
||||
'order' => null,
|
||||
'orderWeight' => 1.0,
|
||||
'shippingAddress' => null,
|
||||
'availableCountries' => $this->getAvailableCountries(),
|
||||
'productCodes' => $this->getAvailableProductCodes(),
|
||||
'errors' => [],
|
||||
'warnings' => []
|
||||
];
|
||||
|
||||
// If no order ID or 'new', return empty data for order selection
|
||||
if (!$id || $id === 'new') {
|
||||
return $result;
|
||||
}
|
||||
|
||||
try {
|
||||
// Load and validate order
|
||||
$order = $this->loadOrder($id);
|
||||
if (!$order) {
|
||||
$result['errors'][] = "Bestellung #{$id} wurde nicht gefunden.";
|
||||
return $result;
|
||||
}
|
||||
|
||||
$result['order'] = $order;
|
||||
|
||||
// Calculate order weight
|
||||
$result['orderWeight'] = $this->calculateOrderWeight($order);
|
||||
|
||||
// Process and validate shipping address
|
||||
$result['shippingAddress'] = $this->processShippingAddress($order);
|
||||
|
||||
// Validate address completeness
|
||||
$addressValidation = $this->validateAddress($result['shippingAddress']);
|
||||
if (!$addressValidation['valid']) {
|
||||
$result['errors'] = array_merge($result['errors'], $addressValidation['errors']);
|
||||
}
|
||||
if (!empty($addressValidation['warnings'])) {
|
||||
$result['warnings'] = array_merge($result['warnings'], $addressValidation['warnings']);
|
||||
}
|
||||
|
||||
Log::info('[DHL Modal] Prepared modal data successfully', [
|
||||
'order_id' => $order->id,
|
||||
'weight' => $result['orderWeight'],
|
||||
'address_valid' => empty($result['errors'])
|
||||
]);
|
||||
} catch (Exception $e) {
|
||||
Log::error('[DHL Modal] Error preparing modal data', [
|
||||
'order_id' => $id,
|
||||
'error' => $e->getMessage()
|
||||
]);
|
||||
|
||||
$result['errors'][] = 'Fehler beim Laden der Bestelldaten: ' . $e->getMessage();
|
||||
}
|
||||
|
||||
return $result;
|
||||
}
|
||||
|
||||
/**
|
||||
* Load order with required relationships
|
||||
*
|
||||
* @param mixed $id
|
||||
* @return ShoppingOrder|null
|
||||
*/
|
||||
private function loadOrder($id): ?ShoppingOrder
|
||||
{
|
||||
return ShoppingOrder::with([
|
||||
'shopping_order_items',
|
||||
'shopping_user',
|
||||
])->find($id);
|
||||
}
|
||||
|
||||
/**
|
||||
* Calculate order weight in kg
|
||||
*
|
||||
* @param ShoppingOrder $order
|
||||
* @return float
|
||||
*/
|
||||
private function calculateOrderWeight(ShoppingOrder $order): float
|
||||
{
|
||||
return $order->weight / 100;
|
||||
/*
|
||||
// Default fallback weight
|
||||
$defaultWeight = 1.0;
|
||||
|
||||
if (!$order->shopping_order_items || $order->shopping_order_items->isEmpty()) {
|
||||
return $defaultWeight;
|
||||
}
|
||||
|
||||
// If order has a weight field (in grams), convert to kg
|
||||
if ($order->weight && $order->weight > 0) {
|
||||
return round($order->weight / 100, 1); // Convert grams to kg
|
||||
}
|
||||
|
||||
// Calculate from items if available
|
||||
$totalWeight = 0;
|
||||
foreach ($order->shopping_order_items as $item) {
|
||||
if ($item->weight && $item->weight > 0) {
|
||||
$totalWeight += ($item->weight * $item->quantity);
|
||||
}
|
||||
}
|
||||
|
||||
if ($totalWeight > 0) {
|
||||
return round($totalWeight / 100, 1); // Convert grams to kg
|
||||
}
|
||||
|
||||
// Estimate based on item count if no weight data
|
||||
$itemCount = $order->shopping_order_items->sum('quantity');
|
||||
$estimatedWeight = max($itemCount * 0.5, $defaultWeight); // Estimate 0.5kg per item
|
||||
|
||||
return round($estimatedWeight, 1);
|
||||
*/
|
||||
}
|
||||
|
||||
/**
|
||||
* Process and parse shipping address from order
|
||||
*
|
||||
* @param ShoppingOrder $order
|
||||
* @return array
|
||||
*/
|
||||
private function processShippingAddress(ShoppingOrder $order): array
|
||||
{
|
||||
$shoppingUser = $order->shopping_user;
|
||||
|
||||
if (!$shoppingUser) {
|
||||
return $this->getEmptyAddress();
|
||||
}
|
||||
|
||||
// Determine if shipping address is different from billing
|
||||
$useShipping = !($shoppingUser->same_as_billing ?? true);
|
||||
|
||||
// Extract address data
|
||||
$addressData = [
|
||||
'firstname' => $useShipping ? ($shoppingUser->shipping_firstname ?? '') : ($shoppingUser->billing_firstname ?? ''),
|
||||
'lastname' => $useShipping ? ($shoppingUser->shipping_lastname ?? '') : ($shoppingUser->billing_lastname ?? ''),
|
||||
'company' => $useShipping ? ($shoppingUser->shipping_company ?? '') : ($shoppingUser->billing_company ?? ''),
|
||||
'address' => $useShipping ? ($shoppingUser->shipping_address ?? '') : ($shoppingUser->billing_address ?? ''),
|
||||
'address_2' => $useShipping ? ($shoppingUser->shipping_address_2 ?? '') : ($shoppingUser->billing_address_2 ?? ''),
|
||||
'zipcode' => $useShipping ? ($shoppingUser->shipping_zipcode ?? '') : ($shoppingUser->billing_zipcode ?? ''),
|
||||
'city' => $useShipping ? ($shoppingUser->shipping_city ?? '') : ($shoppingUser->billing_city ?? ''),
|
||||
'country' => $useShipping ? ($shoppingUser->shipping_country ?? null) : ($shoppingUser->billing_country ?? null),
|
||||
'phone' => $useShipping ? ($shoppingUser->shipping_phone ?? '') : ($shoppingUser->billing_phone ?? ''),
|
||||
'email' => $shoppingUser->billing_email ?? '',
|
||||
'houseNumber' => '',
|
||||
];
|
||||
|
||||
// Parse and separate street name and number
|
||||
$this->parseStreetAddress($addressData);
|
||||
|
||||
return $addressData;
|
||||
}
|
||||
|
||||
/**
|
||||
* Parse street address and separate street name from house number
|
||||
*
|
||||
* @param array &$addressData
|
||||
*/
|
||||
private function parseStreetAddress(array &$addressData): void
|
||||
{
|
||||
$address = trim($addressData['address']);
|
||||
// If address_2 is empty and address contains both street and number
|
||||
if (!empty($address)) {
|
||||
// Try to separate street name and house number
|
||||
$patterns = [
|
||||
// Pattern 1: "Musterstraße 123" or "Musterstraße 123a"
|
||||
'/^(.+?)\s+(\d+[a-zA-Z]?)$/u',
|
||||
// Pattern 2: "Musterstraße 123-125" or "Musterstraße 123/125"
|
||||
'/^(.+?)\s+(\d+[-\/]\d+[a-zA-Z]?)$/u',
|
||||
// Pattern 3: "123 Musterstraße" (number first)
|
||||
'/^(\d+[a-zA-Z]?)\s+(.+)$/u'
|
||||
];
|
||||
|
||||
foreach ($patterns as $index => $pattern) {
|
||||
if (preg_match($pattern, $address, $matches)) {
|
||||
if ($index === 2) {
|
||||
// Number first pattern
|
||||
$addressData['address'] = trim($matches[2]);
|
||||
$addressData['houseNumber'] = trim($matches[1]);
|
||||
} else {
|
||||
// Street first patterns
|
||||
$addressData['address'] = trim($matches[1]);
|
||||
$addressData['houseNumber'] = trim($matches[2]);
|
||||
}
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// Clean up the address data
|
||||
$addressData['address'] = trim($addressData['address']);
|
||||
$addressData['houseNumber'] = trim($addressData['houseNumber']);
|
||||
}
|
||||
|
||||
/**
|
||||
* Validate address completeness and format
|
||||
*
|
||||
* @param array $address
|
||||
* @return array Validation result with 'valid', 'errors', and 'warnings' keys
|
||||
*/
|
||||
private function validateAddress(array $address): array
|
||||
{
|
||||
$errors = [];
|
||||
$warnings = [];
|
||||
|
||||
// Required fields
|
||||
$requiredFields = [
|
||||
'firstname' => 'Vorname',
|
||||
'lastname' => 'Nachname',
|
||||
'address' => 'Straße',
|
||||
'zipcode' => 'Postleitzahl',
|
||||
'city' => 'Stadt'
|
||||
];
|
||||
|
||||
foreach ($requiredFields as $field => $label) {
|
||||
if (empty(trim($address[$field]))) {
|
||||
$errors[] = "{$label} ist erforderlich.";
|
||||
}
|
||||
}
|
||||
|
||||
// Name validation
|
||||
if (empty(trim($address['firstname'])) && empty(trim($address['lastname'])) && empty(trim($address['company']))) {
|
||||
$errors[] = 'Entweder Name oder Firmenname muss angegeben werden.';
|
||||
}
|
||||
|
||||
// Street number validation
|
||||
if (!empty($address['address']) && empty($address['houseNumber'])) {
|
||||
$warnings[] = 'Hausnummer konnte nicht automatisch erkannt werden. Bitte prüfen Sie die Adressangaben.';
|
||||
}
|
||||
|
||||
// Postal code format validation for Germany
|
||||
if (!empty($address['zipcode']) && $address['country'] && $address['country']->code === 'DE') {
|
||||
if (!preg_match('/^\d{5}$/', $address['zipcode'])) {
|
||||
$warnings[] = 'Deutsche Postleitzahl sollte 5 Ziffern haben.';
|
||||
}
|
||||
}
|
||||
|
||||
// Country validation
|
||||
if (!$address['country']) {
|
||||
$errors[] = 'Land konnte nicht ermittelt werden.';
|
||||
}
|
||||
|
||||
return [
|
||||
'valid' => empty($errors),
|
||||
'errors' => $errors,
|
||||
'warnings' => $warnings
|
||||
];
|
||||
}
|
||||
|
||||
/**
|
||||
* Get empty address template
|
||||
*
|
||||
* @return array
|
||||
*/
|
||||
private function getEmptyAddress(): array
|
||||
{
|
||||
return [
|
||||
'firstname' => '',
|
||||
'lastname' => '',
|
||||
'company' => '',
|
||||
'address' => '',
|
||||
'address_2' => '',
|
||||
'zipcode' => '',
|
||||
'city' => '',
|
||||
'country' => null,
|
||||
'phone' => '',
|
||||
'email' => '',
|
||||
];
|
||||
}
|
||||
|
||||
/**
|
||||
* Get available countries for shipping
|
||||
*
|
||||
* @return \Illuminate\Database\Eloquent\Collection
|
||||
*/
|
||||
private function getAvailableCountries()
|
||||
{
|
||||
return Country::where('active', 1)->get();
|
||||
}
|
||||
|
||||
/**
|
||||
* Get available DHL product codes from settings
|
||||
*
|
||||
* @return array
|
||||
*/
|
||||
private function getAvailableProductCodes(): array
|
||||
{
|
||||
// Get DHL configuration with merged settings
|
||||
$settingController = new \App\Http\Controllers\SettingController();
|
||||
$dhlConfig = $settingController->getDhlConfig();
|
||||
|
||||
$productCodes = [];
|
||||
|
||||
// Add products based on configured account numbers
|
||||
$accountNumbers = $dhlConfig['account_numbers'] ?? [];
|
||||
|
||||
if (!empty($accountNumbers['V01PAK'])) {
|
||||
$productCodes['V01PAK'] = 'DHL Paket National';
|
||||
}
|
||||
|
||||
if (!empty($accountNumbers['V53PAK'])) {
|
||||
$productCodes['V53PAK'] = 'DHL Paket International';
|
||||
}
|
||||
|
||||
if (!empty($accountNumbers['V62WP'])) {
|
||||
$productCodes['V62WP'] = 'DHL Warenpost National';
|
||||
}
|
||||
|
||||
if (!empty($accountNumbers['V07PAK'])) {
|
||||
$productCodes['V07PAK'] = 'DHL Retoure Online';
|
||||
}
|
||||
|
||||
// Fallback to default if no account numbers configured
|
||||
if (empty($productCodes)) {
|
||||
$productCodes = [
|
||||
'V01PAK' => 'DHL Paket National',
|
||||
'V53PAK' => 'DHL Paket International',
|
||||
'V62WP' => 'DHL Warenpost National'
|
||||
];
|
||||
}
|
||||
|
||||
return $productCodes;
|
||||
}
|
||||
|
||||
/**
|
||||
* Validate shipment parameters before API call
|
||||
*
|
||||
* @param array $shipmentData
|
||||
* @return array Validation result
|
||||
*/
|
||||
public function validateShipmentData(array $shipmentData): array
|
||||
{
|
||||
$errors = [];
|
||||
$warnings = [];
|
||||
|
||||
// Weight validation
|
||||
$weight = floatval($shipmentData['weight'] ?? 0);
|
||||
if ($weight < 0.1) {
|
||||
$errors[] = 'Gewicht muss mindestens 0.1 kg betragen.';
|
||||
} elseif ($weight > 31.5) {
|
||||
$errors[] = 'Gewicht darf maximal 31.5 kg betragen.';
|
||||
}
|
||||
|
||||
// Product code validation
|
||||
$productCode = $shipmentData['product_code'] ?? '';
|
||||
$availableProducts = array_keys($this->getAvailableProductCodes());
|
||||
if (!in_array($productCode, $availableProducts)) {
|
||||
$errors[] = 'Ungültiger Produktcode ausgewählt.';
|
||||
}
|
||||
|
||||
// Address validation
|
||||
$requiredAddressFields = [
|
||||
'shipping_firstname' => 'Vorname',
|
||||
'shipping_lastname' => 'Nachname',
|
||||
'shipping_address' => 'Straße',
|
||||
'shipping_houseNumber' => 'Hausnummer',
|
||||
'shipping_zipcode' => 'Postleitzahl',
|
||||
'shipping_city' => 'Stadt',
|
||||
'shipping_country_id' => 'Land'
|
||||
];
|
||||
|
||||
foreach ($requiredAddressFields as $field => $label) {
|
||||
if (empty(trim($shipmentData[$field] ?? ''))) {
|
||||
$errors[] = "{$label} ist erforderlich.";
|
||||
}
|
||||
}
|
||||
|
||||
return [
|
||||
'valid' => empty($errors),
|
||||
'errors' => $errors,
|
||||
'warnings' => $warnings
|
||||
];
|
||||
}
|
||||
|
||||
/**
|
||||
* Prepare address data for DHL API
|
||||
*
|
||||
* @param array $formData
|
||||
* @return array
|
||||
*/
|
||||
public function prepareAddressForApi(array $formData): array
|
||||
{
|
||||
$country = null;
|
||||
if (!empty($formData['shipping_country_id'])) {
|
||||
$country = Country::find($formData['shipping_country_id']);
|
||||
}
|
||||
|
||||
return [
|
||||
'firstname' => trim($formData['shipping_firstname'] ?? ''),
|
||||
'lastname' => trim($formData['shipping_lastname'] ?? ''),
|
||||
'company' => trim($formData['shipping_company'] ?? ''),
|
||||
'address' => trim($formData['shipping_address'] ?? ''),
|
||||
'address_2' => trim($formData['shipping_address_2'] ?? ''),
|
||||
'houseNumber' => trim($formData['shipping_houseNumber'] ?? ''),
|
||||
'zipcode' => trim($formData['shipping_zipcode'] ?? ''),
|
||||
'city' => trim($formData['shipping_city'] ?? ''),
|
||||
'country_id' => $country?->id,
|
||||
'phone' => trim($formData['shipping_phone'] ?? '')
|
||||
];
|
||||
}
|
||||
}
|
||||
147
dev/app-bak/Services/DhlShipmentService.php
Normal file
147
dev/app-bak/Services/DhlShipmentService.php
Normal file
|
|
@ -0,0 +1,147 @@
|
|||
<?php
|
||||
|
||||
namespace App\Services;
|
||||
|
||||
use App\Models\ShoppingOrder;
|
||||
use App\Http\Controllers\SettingController;
|
||||
use App\Jobs\CreateShipmentJob;
|
||||
use App\Services\DhlDataHelper;
|
||||
use Illuminate\Support\Facades\Log;
|
||||
use Exception;
|
||||
|
||||
/**
|
||||
* DHL Shipment Service
|
||||
*
|
||||
* Handles both synchronous and asynchronous shipment creation
|
||||
* based on configuration settings
|
||||
*/
|
||||
class DhlShipmentService
|
||||
{
|
||||
/**
|
||||
* Create a DHL shipment (sync or async based on config)
|
||||
*
|
||||
* @param ShoppingOrder $order
|
||||
* @param float $weight
|
||||
* @param array $options
|
||||
* @return array
|
||||
*/
|
||||
public function createShipment(ShoppingOrder $order, float $weight = 1.0, array $options = []): array
|
||||
{
|
||||
// Get DHL configuration
|
||||
$settingController = new SettingController();
|
||||
$dhlConfig = $settingController->getDhlConfig();
|
||||
\Log::info('dhlConfig', $dhlConfig);
|
||||
// Check if queue should be used
|
||||
$useQueue = $dhlConfig['use_queue'] ?? false;
|
||||
|
||||
if ($useQueue) {
|
||||
return $this->createShipmentAsync($order, $weight, $options, $dhlConfig);
|
||||
} else {
|
||||
return $this->createShipmentSync($order, $weight, $options, $dhlConfig);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Create shipment asynchronously using queue
|
||||
*
|
||||
* @param ShoppingOrder $order
|
||||
* @param float $weight
|
||||
* @param array $options
|
||||
* @param array $dhlConfig
|
||||
* @return array
|
||||
*/
|
||||
private function createShipmentAsync(ShoppingOrder $order, float $weight, array $options, array $dhlConfig): array
|
||||
{
|
||||
try {
|
||||
// Dispatch job with pre-loaded config
|
||||
CreateShipmentJob::dispatch($order, $weight, $options, $dhlConfig);
|
||||
|
||||
Log::info('[DHL Service] Shipment creation dispatched to queue', [
|
||||
'order_id' => $order->id,
|
||||
'weight' => $weight
|
||||
]);
|
||||
|
||||
return [
|
||||
'success' => true,
|
||||
'message' => 'Sendung wird erstellt. Sie erhalten eine Benachrichtigung, sobald das Versandlabel verfügbar ist.',
|
||||
'queued' => true,
|
||||
'order_id' => $order->id
|
||||
];
|
||||
} catch (Exception $e) {
|
||||
Log::error('[DHL Service] Failed to dispatch shipment creation', [
|
||||
'error' => $e->getMessage(),
|
||||
'order_id' => $order->id,
|
||||
]);
|
||||
|
||||
return [
|
||||
'success' => false,
|
||||
'message' => 'Fehler beim Einreihen der Sendungserstellung: ' . $e->getMessage(),
|
||||
'queued' => false
|
||||
];
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Create shipment synchronously
|
||||
*
|
||||
* @param ShoppingOrder $order
|
||||
* @param float $weight
|
||||
* @param array $options
|
||||
* @param array $dhlConfig
|
||||
* @return array
|
||||
*/
|
||||
private function createShipmentSync(ShoppingOrder $order, float $weight, array $options, array $dhlConfig): array
|
||||
{
|
||||
try {
|
||||
Log::info('[DHL Service] Creating shipment synchronously', [
|
||||
'order_id' => $order->id,
|
||||
'weight' => $weight
|
||||
]);
|
||||
|
||||
// Create DHL client directly
|
||||
$dhlClient = new \Acme\Dhl\Support\DhlClient(
|
||||
$dhlConfig['base_url'],
|
||||
$dhlConfig['api_key'],
|
||||
$dhlConfig['username'],
|
||||
$dhlConfig['password']
|
||||
);
|
||||
|
||||
$shippingService = new \Acme\Dhl\Services\ShippingService($dhlClient);
|
||||
|
||||
// Prepare order data using helper
|
||||
$orderData = DhlDataHelper::prepareOrderData($order, $weight, $options, $dhlConfig);
|
||||
Log::info('orderData', $orderData);
|
||||
// Create the shipment directly
|
||||
$result = $shippingService->createLabel($orderData);
|
||||
|
||||
Log::info('[DHL Service] Shipment created successfully (sync)', [
|
||||
'order_id' => $order->id,
|
||||
'shipment_number' => $result['shipmentNumber'] ?? 'N/A',
|
||||
'label_path' => $result['labelPath'] ?? 'N/A',
|
||||
]);
|
||||
|
||||
return [
|
||||
'success' => true,
|
||||
'message' => 'Versandlabel erfolgreich erstellt!',
|
||||
'queued' => false,
|
||||
'order_id' => $order->id,
|
||||
'shipment_number' => $result['shipmentNumber'] ?? null,
|
||||
'tracking_number' => $result['trackingNumber'] ?? null,
|
||||
'label_path' => $result['labelPath'] ?? null,
|
||||
'label_url' => $result['labelUrl'] ?? null,
|
||||
];
|
||||
} catch (Exception $e) {
|
||||
Log::error('[DHL Service] Shipment creation failed (sync)', [
|
||||
'order_id' => $order->id,
|
||||
'error' => $e->getMessage()
|
||||
]);
|
||||
|
||||
return [
|
||||
'success' => false,
|
||||
'message' => 'Fehler beim Erstellen des Versandlabels: ' . $e->getMessage(),
|
||||
'queued' => false,
|
||||
'order_id' => $order->id
|
||||
];
|
||||
}
|
||||
}
|
||||
}
|
||||
296
dev/app-bak/Services/DomainService.php
Normal file
296
dev/app-bak/Services/DomainService.php
Normal file
|
|
@ -0,0 +1,296 @@
|
|||
<?php
|
||||
|
||||
namespace App\Services;
|
||||
|
||||
use App\Models\UserShop;
|
||||
use Illuminate\Support\Facades\Cache;
|
||||
use Illuminate\Support\Facades\Config;
|
||||
|
||||
/**
|
||||
* Domain Service - Centralized domain and subdomain management
|
||||
*
|
||||
* This service provides a centralized way to handle domain resolution,
|
||||
* subdomain validation, and domain-specific configuration management.
|
||||
*/
|
||||
class DomainService
|
||||
{
|
||||
private const CACHE_TTL = 3600; // 1 hour
|
||||
private const CACHE_TAG_USER_SHOPS = 'user_shops';
|
||||
private const CACHE_TAG_DOMAIN_PARSING = 'domain_parsing';
|
||||
private const FIXED_SUBDOMAINS = ['my', 'in', 'checkout'];
|
||||
|
||||
private array $domainConfig;
|
||||
|
||||
public function __construct(?array $domainConfig = null)
|
||||
{
|
||||
$this->domainConfig = $domainConfig ?? config('domains');
|
||||
}
|
||||
|
||||
/**
|
||||
* Determine the type of subdomain
|
||||
*/
|
||||
public function getSubdomainType(string $subdomain): string
|
||||
{
|
||||
// Frühe Validierung: Prüfe reservierte Subdomains aus Konfiguration
|
||||
$reservedSubdomains = $this->domainConfig['reserved_subdomains'] ?? self::FIXED_SUBDOMAINS;
|
||||
|
||||
if (in_array($subdomain, $reservedSubdomains)) {
|
||||
return match ($subdomain) {
|
||||
'my' => 'crm',
|
||||
'in' => 'portal',
|
||||
'checkout' => 'checkout',
|
||||
default => 'unknown' // Andere reservierte Subdomains sind ungültig
|
||||
};
|
||||
}
|
||||
|
||||
// Frühe Validierung: Prüfe auf ungültige Zeichen für UserShop-Slugs
|
||||
if (!preg_match('/^[a-z0-9-]+$/', $subdomain) || strlen($subdomain) < 3) {
|
||||
return 'unknown';
|
||||
}
|
||||
|
||||
// Check if it's a valid user shop
|
||||
if ($this->isValidUserShop($subdomain)) {
|
||||
return 'user-shop';
|
||||
}
|
||||
|
||||
return 'unknown';
|
||||
}
|
||||
|
||||
/**
|
||||
* Check if a subdomain represents a valid user shop
|
||||
*/
|
||||
public function isValidUserShop(string $slug): bool
|
||||
{
|
||||
$cacheKey = "user_shop_valid_{$slug}";
|
||||
|
||||
return Cache::remember($cacheKey, self::CACHE_TTL, function () use ($slug) {
|
||||
// Optimierte Query mit allen Validierungen in einem DB-Call
|
||||
$userShop = UserShop::where('slug', $slug)
|
||||
->where('active', true)
|
||||
->whereHas('user', function ($query) {
|
||||
$query->whereNotNull('payment_shop')
|
||||
->where('payment_shop', '>', now());
|
||||
})
|
||||
->exists();
|
||||
|
||||
return $userShop;
|
||||
});
|
||||
}
|
||||
|
||||
/**
|
||||
* Get user shop by slug with caching
|
||||
*/
|
||||
public function getUserShop(string $slug): ?UserShop
|
||||
{
|
||||
$cacheKey = "user_shop_{$slug}";
|
||||
|
||||
return Cache::remember($cacheKey, self::CACHE_TTL, function () use ($slug) {
|
||||
// Optimierte Query mit allen Validierungen in einem DB-Call
|
||||
return UserShop::where('slug', $slug)
|
||||
->where('active', true)
|
||||
->whereHas('user', function ($query) {
|
||||
$query->whereNotNull('payment_shop')
|
||||
->where('payment_shop', '>', now());
|
||||
})
|
||||
->with('user')
|
||||
->first();
|
||||
});
|
||||
}
|
||||
|
||||
/**
|
||||
* Parse domain from request and determine context
|
||||
*/
|
||||
public function parseDomain(string $host): array
|
||||
{
|
||||
// Normalisiere den Host (lowercase)
|
||||
$host = strtolower(trim($host));
|
||||
$parts = explode('.', $host);
|
||||
|
||||
// Handle different TLD scenarios
|
||||
if (count($parts) < 2) {
|
||||
\Log::channel('domain')->warning('Invalid host format', ['host' => $host]);
|
||||
return [
|
||||
'type' => 'invalid',
|
||||
'domain' => $host,
|
||||
'subdomain' => null,
|
||||
'tld' => null,
|
||||
'host' => $host
|
||||
];
|
||||
}
|
||||
|
||||
// Extract TLD and domain
|
||||
$tld = '.' . end($parts);
|
||||
$domain = $parts[count($parts) - 2];
|
||||
|
||||
// Check for subdomain
|
||||
$subdomain = null;
|
||||
if (count($parts) > 2) {
|
||||
$subdomain = $parts[0];
|
||||
if (config('app.debug')) {
|
||||
\Log::channel('domain')->debug('DomainService: Using extracted subdomain', ['subdomain' => $subdomain, 'host' => $host]);
|
||||
}
|
||||
}
|
||||
|
||||
// Determine domain type based on subdomain and host
|
||||
$type = $this->determineDomainType($host, $subdomain);
|
||||
|
||||
return [
|
||||
'type' => $type,
|
||||
'domain' => $domain,
|
||||
'subdomain' => $subdomain,
|
||||
'tld' => $tld,
|
||||
'host' => $host,
|
||||
'default_user_shop' => $this->domainConfig['domains']['shop']['default_user_shop'] ?? null
|
||||
];
|
||||
}
|
||||
|
||||
/**
|
||||
* Determine domain type based on full host and subdomain
|
||||
*/
|
||||
private function determineDomainType(string $host, ?string $subdomain): string
|
||||
{
|
||||
|
||||
|
||||
// Check against configured domains
|
||||
foreach ($this->domainConfig['domains'] as $type => $config) {
|
||||
if (isset($config['host'])) {
|
||||
// Handle wildcard user-shop pattern
|
||||
if ($type === 'user-shop') {
|
||||
$pattern = str_replace('{subdomain}', '([a-z0-9-]+)', $config['host']);
|
||||
if (preg_match("/^{$pattern}$/", $host)) {
|
||||
return 'user-shop';
|
||||
}
|
||||
} else {
|
||||
// Exact match for other domains
|
||||
if ($host === $config['host']) {
|
||||
return $type;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// Additional check for subdomain-based detection
|
||||
if ($subdomain) {
|
||||
$subdomainType = $this->getSubdomainType($subdomain);
|
||||
if ($subdomainType !== 'unknown') {
|
||||
return $subdomainType;
|
||||
}
|
||||
}
|
||||
|
||||
return 'unknown';
|
||||
}
|
||||
|
||||
/**
|
||||
* Build URL for specific domain type
|
||||
*/
|
||||
public function buildUrl(string $type, ?string $path = null, ?string $slug = null): string
|
||||
{
|
||||
$protocol = $this->domainConfig['protocol'] ?? 'https://';
|
||||
|
||||
$domainConfig = $this->domainConfig['domains'][$type] ?? null;
|
||||
|
||||
if (!$domainConfig) {
|
||||
throw new \InvalidArgumentException("Unknown domain type: {$type}");
|
||||
}
|
||||
|
||||
$host = $domainConfig['host'];
|
||||
|
||||
// Handle user-shop wildcard
|
||||
if ($type === 'user-shop') {
|
||||
if (!$slug) {
|
||||
throw new \InvalidArgumentException('Slug required for user-shop URLs');
|
||||
}
|
||||
$host = str_replace('{subdomain}', $slug, $host);
|
||||
}
|
||||
|
||||
$url = $protocol . $host;
|
||||
|
||||
if ($path) {
|
||||
$url .= '/' . ltrim($path, '/');
|
||||
}
|
||||
|
||||
return $url;
|
||||
}
|
||||
|
||||
/**
|
||||
* Get domain configuration
|
||||
*/
|
||||
public function getDomainConfiguration(): array
|
||||
{
|
||||
return $this->domainConfig;
|
||||
}
|
||||
|
||||
/**
|
||||
* Clear user shop cache
|
||||
*/
|
||||
public function clearUserShopCache(string $slug): void
|
||||
{
|
||||
Cache::forget("user_shop_valid_{$slug}");
|
||||
Cache::forget("user_shop_{$slug}");
|
||||
}
|
||||
|
||||
/**
|
||||
* Clear all user shop caches
|
||||
*/
|
||||
public function clearAllUserShopCaches(): void
|
||||
{
|
||||
// In Laravel mit Cache-Tags würde das eleganter funktionieren
|
||||
// Für jetzt eine einfache Lösung für häufig verwendete Shops
|
||||
$commonSlugs = ['aloevera']; // Füge häufig verwendete Slugs hinzu
|
||||
|
||||
foreach ($commonSlugs as $slug) {
|
||||
$this->clearUserShopCache($slug);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Get default user shop for main domain (fallback)
|
||||
*/
|
||||
public function getDefaultUserShop(): ?UserShop
|
||||
{
|
||||
$defaultSlug = $this->domainConfig['domains']['shop']['default_user_shop'] ?? 'aloevera';
|
||||
return $this->getUserShop($defaultSlug);
|
||||
}
|
||||
|
||||
/**
|
||||
* Validate domain configuration
|
||||
*/
|
||||
public function validateConfiguration(): array
|
||||
{
|
||||
$errors = [];
|
||||
|
||||
// Validate main domains
|
||||
$requiredDomains = ['main', 'shop', 'crm', 'portal', 'checkout', 'user-shop'];
|
||||
foreach ($requiredDomains as $domain) {
|
||||
if (empty($this->domainConfig['domains'][$domain]['host'])) {
|
||||
$errors[] = "Domain '{$domain}' not configured";
|
||||
}
|
||||
}
|
||||
|
||||
// Validate protocol
|
||||
if (empty($this->domainConfig['protocol'])) {
|
||||
$errors[] = 'Protocol not configured';
|
||||
}
|
||||
|
||||
// Validate reserved subdomains
|
||||
if (empty($this->domainConfig['reserved_subdomains'])) {
|
||||
$errors[] = 'Reserved subdomains not configured';
|
||||
}
|
||||
|
||||
// Validate shop default
|
||||
$defaultShop = $this->domainConfig['domains']['shop']['default_user_shop'] ?? null;
|
||||
if (!$defaultShop) {
|
||||
$errors[] = 'Default user shop not configured for shop domain';
|
||||
}
|
||||
|
||||
return $errors;
|
||||
}
|
||||
|
||||
/**
|
||||
* Check if domain configuration is valid
|
||||
*/
|
||||
public function isConfigurationValid(): bool
|
||||
{
|
||||
return empty($this->validateConfiguration());
|
||||
}
|
||||
}
|
||||
19
dev/app-bak/Services/Facade/Yard.php
Normal file
19
dev/app-bak/Services/Facade/Yard.php
Normal file
|
|
@ -0,0 +1,19 @@
|
|||
<?php
|
||||
|
||||
namespace App\Services\Facade;
|
||||
|
||||
use Illuminate\Support\Facades\Facade;
|
||||
|
||||
class Yard extends Facade {
|
||||
|
||||
/**
|
||||
* Get the registered name of the component.
|
||||
*
|
||||
* @return string
|
||||
*/
|
||||
protected static function getFacadeAccessor()
|
||||
{
|
||||
return \App\Services\Yard::class;
|
||||
}
|
||||
|
||||
}
|
||||
387
dev/app-bak/Services/HTMLHelper.php
Normal file
387
dev/app-bak/Services/HTMLHelper.php
Normal file
|
|
@ -0,0 +1,387 @@
|
|||
<?php
|
||||
namespace App\Services;
|
||||
|
||||
use App\Models\Attribute;
|
||||
use App\Models\Category;
|
||||
use App\Models\Country;
|
||||
use App\Models\Ingredient;
|
||||
use App\Models\Product;
|
||||
use App\Models\ShippingCountry;
|
||||
use App\Models\ShoppingUser;
|
||||
use App\Models\UserLevel;
|
||||
use App\User;
|
||||
|
||||
class HTMLHelper
|
||||
{
|
||||
|
||||
|
||||
public static $months = [
|
||||
1 => 'January',
|
||||
2 => 'February',
|
||||
3 => 'March',
|
||||
4 => 'April',
|
||||
5 => 'May',
|
||||
6 => 'June',
|
||||
7 => 'July',
|
||||
8 => 'August',
|
||||
9 => 'September',
|
||||
10 => 'October',
|
||||
11 => 'November',
|
||||
12 => 'December'
|
||||
];
|
||||
|
||||
|
||||
private static $roles = [
|
||||
0 => 'Berater',
|
||||
1 => 'VIP',
|
||||
2 => 'Admin',
|
||||
3 => 'SuperAdmin',
|
||||
4 => 'SySAdmin',
|
||||
];
|
||||
|
||||
|
||||
public static function getMonth($i){
|
||||
return trans('cal.months.'.self::$months[intval($i)]);
|
||||
}
|
||||
|
||||
public static function getTransMonths(){
|
||||
$ret = [];
|
||||
foreach(self::$months as $key=>$val){
|
||||
$ret[$key] = trans('cal.months.'.$val);
|
||||
}
|
||||
return $ret;
|
||||
}
|
||||
|
||||
public static function getYearRange($start = 2021)
|
||||
{
|
||||
$end = date("Y");
|
||||
return array_reverse(range($start, $end));
|
||||
}
|
||||
|
||||
public static function getRoleLabel($role_id = 0){
|
||||
return '<span class="badge badge-pill '.self::getLabel($role_id).'">'.self::$roles[$role_id].'</span>';
|
||||
}
|
||||
|
||||
public static function getLabel($id){
|
||||
switch ($id) {
|
||||
case 0:
|
||||
return 'badge-default';
|
||||
break;
|
||||
case 1:
|
||||
return 'badge-secondary';
|
||||
break;
|
||||
case 2:
|
||||
return 'badge-warning';
|
||||
break;
|
||||
case 3:
|
||||
return 'badge-primary';
|
||||
break;
|
||||
case 4:
|
||||
return 'badge-primary';
|
||||
break;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
public static function getRolesOptions(){
|
||||
$ret = "";
|
||||
foreach (self::$roles as $role_id => $value){
|
||||
$ret .= '<option value="'.$role_id.'">'.$value.'</option>\n';
|
||||
}
|
||||
return $ret;
|
||||
}
|
||||
|
||||
public static function getYearSelectOptions(){
|
||||
$start = date("Y", strtotime("-5 years", time()));
|
||||
$end = date("Y", strtotime("+1 years", time()));
|
||||
$values = range($start, $end);
|
||||
$now = date("Y", time());
|
||||
$ret = "";
|
||||
foreach ($values as $value){
|
||||
$attr = ($value == $now) ? 'selected="selected"' : '';
|
||||
$ret .= '<option value="'.$value.'" '.$attr.'>'.$value.'</option>\n';
|
||||
}
|
||||
return $ret;
|
||||
}
|
||||
|
||||
public static function getAboDeliveryOptions($default = 5){
|
||||
$values = \App\Models\UserAbo::$aboDeliveryDays;
|
||||
$ret = "";
|
||||
foreach ($values as $value){
|
||||
$attr = ($value == $default) ? 'selected="selected"' : '';
|
||||
$str = self::getAboStrLang($value);
|
||||
$ret .= '<option value="'.$value.'" '.$attr.'>'.$str.'</option>\n';
|
||||
}
|
||||
return $ret;
|
||||
}
|
||||
|
||||
public static function getAboStrLang($num){
|
||||
return $num.'. '.__('abo.of_month');
|
||||
}
|
||||
|
||||
|
||||
public static function getAttributesWithoutParents($id = false, $sameId = false, $all = true){
|
||||
$values = Attribute::where('parent_id', null)->get();
|
||||
$ret = "";
|
||||
if($all){
|
||||
$ret .= '<option value="">'.__('none').'</option>\n';
|
||||
}
|
||||
foreach ($values as $value){
|
||||
if($sameId == $value->id){
|
||||
continue;
|
||||
}
|
||||
$attr = ($value->id == $id) ? 'selected="selected"' : '';
|
||||
$ret .= '<option value="'.$value->id.'" '.$attr.'>'.$value->name.'</option>\n';
|
||||
}
|
||||
return $ret;
|
||||
}
|
||||
|
||||
public static function getCategoriesWithoutParents($id = false, $sameId = false, $all = true){
|
||||
$values = Category::where('parent_id', null)->get();
|
||||
$ret = "";
|
||||
if($all){
|
||||
$ret .= '<option value="">'.__('none').'</option>\n';
|
||||
}
|
||||
foreach ($values as $value){
|
||||
if($sameId == $value->id){
|
||||
continue;
|
||||
}
|
||||
$attr = ($value->id == $id) ? 'selected="selected"' : '';
|
||||
$ret .= '<option value="'.$value->id.'" '.$attr.'>'.$value->name.'</option>\n';
|
||||
}
|
||||
return $ret;
|
||||
}
|
||||
|
||||
public static function getProductsOptions($ids = array(), $all = true){
|
||||
if($ids == null){
|
||||
$ids = array();
|
||||
}
|
||||
$values = Product::all();
|
||||
$ret = "";
|
||||
if($all){
|
||||
$ret .= '<option value="">'.__('none').'</option>\n';
|
||||
}
|
||||
foreach ($values as $value){
|
||||
$attr = in_array($value->id, $ids) ? 'selected="selected"' : '';
|
||||
$ret .= '<option value="'.$value->id.'" '.$attr.'>'.$value->name.' ('.($value->active ? 'on' : 'off').')</option>\n';
|
||||
}
|
||||
return $ret;
|
||||
}
|
||||
|
||||
public static function getCategoriesOptions($ids = array(), $all = true){
|
||||
$values = Category::where('active', 1)->orderBy('pos', 'DESC')->get();
|
||||
$ret = "";
|
||||
if($all){
|
||||
$ret .= '<option value="">'.__('none').'</option>\n';
|
||||
}
|
||||
foreach ($values as $value){
|
||||
$attr = in_array($value->id, $ids) ? 'selected="selected"' : '';
|
||||
$ret .= '<option value="'.$value->id.'" '.$attr.'>'.$value->name.'</option>\n';
|
||||
}
|
||||
return $ret;
|
||||
}
|
||||
|
||||
public static function getProductIngredientsOptions($has_ids = array(), $all = true){
|
||||
$values = Ingredient::where('active', 1)->get();
|
||||
$ret = "";
|
||||
$attr = "";
|
||||
foreach ($values as $value){
|
||||
if(!in_array($value->id, $has_ids)){
|
||||
$ret .= '<option value="'.$value->id.'" '.$attr.'>'.$value->name.'</option>\n';
|
||||
}
|
||||
}
|
||||
return $ret;
|
||||
}
|
||||
|
||||
public static function getAttributesOptions($ids = array(), $all = true){
|
||||
$values = Attribute::where('active', 1)->get();
|
||||
$ret = "";
|
||||
if($all){
|
||||
$ret .= '<option value="">'.__('none').'</option>\n';
|
||||
}
|
||||
foreach ($values as $value){
|
||||
$attr = in_array($value->id, $ids) ? 'selected="selected"' : '';
|
||||
$ret .= '<option value="'.$value->id.'" '.$attr.'>'.$value->name.'</option>\n';
|
||||
}
|
||||
return $ret;
|
||||
}
|
||||
|
||||
public static function getUserLevelOptions($id = false, $all = true){
|
||||
$values = UserLevel::where('active', 1)->get();
|
||||
$ret = "";
|
||||
if($all){
|
||||
$ret .= '<option value="">'.__('none').'</option>\n';
|
||||
}
|
||||
foreach ($values as $value){
|
||||
$attr = ($value->id == $id) ? 'selected="selected"' : '';
|
||||
$ret .= '<option value="'.$value->id.'" '.$attr.'>'.$value->name.'</option>\n';
|
||||
}
|
||||
return $ret;
|
||||
}
|
||||
|
||||
|
||||
public static function getCompanyOptions($company){
|
||||
$options = array(1 => __('business'), 0 => __('private'), );
|
||||
$ret = "";
|
||||
foreach ($options as $id => $value){
|
||||
$attr = ($id == $company) ? 'selected="selected"' : '';
|
||||
$ret .= '<option value="'.$id.'" '.$attr.'>'.$value.'</option>\n';
|
||||
}
|
||||
return $ret;
|
||||
}
|
||||
|
||||
public static function getContriesWithMore($id, $all=true){#
|
||||
$values = Country::all();
|
||||
$counter = 1;
|
||||
$ret = "";
|
||||
if($all){
|
||||
$ret .= '<option value="">'.__('please select').'</option>\n';
|
||||
|
||||
}
|
||||
foreach ($values as $value){
|
||||
if( $counter == 7){
|
||||
$ret .= '<optgroup label="'.__('further countrie').'">';
|
||||
}
|
||||
$attr = ($value->id == $id) ? 'selected="selected"' : '';
|
||||
$ret .= '<option value="'.$value->id.'" '.$attr.'>'.$value->getLocated().'</option>\n';
|
||||
|
||||
$counter ++;
|
||||
}
|
||||
$ret .= '</optgroup>';
|
||||
return $ret;
|
||||
}
|
||||
|
||||
|
||||
|
||||
public static function getContriesCodes($id, $all=true){#
|
||||
$values = Country::all();
|
||||
$counter = 1;
|
||||
$ret = "";
|
||||
if($all){
|
||||
$ret .= '<option value="">'.__('please select').'</option>\n';
|
||||
|
||||
}
|
||||
foreach ($values as $value){
|
||||
|
||||
if(!$value->phone) continue;
|
||||
if( $counter == 7){
|
||||
$ret .= '<optgroup label="'.__('further countrie').'">';
|
||||
}
|
||||
$attr = ($value->id == $id) ? 'selected="selected"' : '';
|
||||
$ret .= '<option value="'.$value->id.'" '.$attr.'>'.$value->phone.'('.$value->getLocated().')</option>\n';
|
||||
|
||||
$counter ++;
|
||||
}
|
||||
$ret .= '</optgroup>';
|
||||
return $ret;
|
||||
}
|
||||
|
||||
public static function getCountriesWithoutUsedShippings($all=true){#
|
||||
$values = Country::all();
|
||||
$country_ids = ShippingCountry::all()->pluck('country_id')->toArray();
|
||||
$ret = "";
|
||||
if($all){
|
||||
$ret .= '<option value="">'.__('please select').'</option>\n';
|
||||
}
|
||||
foreach ($values as $value){
|
||||
if(!in_array($value->id, $country_ids)){
|
||||
$ret .= '<option value="'.$value->id.'">'.$value->getLocated().'</option>\n';
|
||||
}
|
||||
}
|
||||
return $ret;
|
||||
}
|
||||
|
||||
public static function getCountryNameFormShipping($id){
|
||||
$value = ShippingCountry::find($id);
|
||||
if($value){
|
||||
return $value->country->getLocated();
|
||||
}
|
||||
return "not defined";
|
||||
}
|
||||
|
||||
public static function getCountriesForShipping($id, $all=false){#
|
||||
$values = ShippingCountry::all();
|
||||
$ret = "";
|
||||
if($all){
|
||||
$ret .= '<option value="">'.__('please select').'</option>\n';
|
||||
}
|
||||
foreach ($values as $value){
|
||||
$attr = ($value->id == $id) ? 'selected="selected"' : '';
|
||||
$ret .= '<option value="'.$value->id.'" '.$attr.'>'.$value->country->getLocated().'</option>\n';
|
||||
|
||||
}
|
||||
return $ret;
|
||||
}
|
||||
|
||||
public static function getSalutation($id){
|
||||
$values = array('mr' => __('MR'), 'ms' => __('MS'), 'di' => __('DIV'));
|
||||
$ret = "";
|
||||
$ret .= '<option value="">'.__('please select').'</option>\n';
|
||||
foreach ($values as $key => $value){
|
||||
$attr = ($key == $id) ? 'selected="selected"' : '';
|
||||
$ret .= '<option value="'.$key.'" '.$attr.'>'.$value.'</option>\n';
|
||||
}
|
||||
return $ret;
|
||||
}
|
||||
|
||||
public static function getSalutationLang($id){
|
||||
$values = array('mr' => __('MR'), 'ms' => __('MS'), 'di' => __('DIV'));
|
||||
return (!empty($values[$id]) ? $values[$id] : '');
|
||||
}
|
||||
|
||||
public static function getTaxSaleOptions($id){
|
||||
$values = array('1' => __('account.taxable_sales_1'), '2' => __('account.taxable_sales_2'));
|
||||
$ret = "";
|
||||
$ret .= '<option value="">'.__('please select').'</option>\n';
|
||||
foreach ($values as $key => $value){
|
||||
$attr = ($key == $id) ? 'selected="selected"' : '';
|
||||
$ret .= '<option value="'.$key.'" '.$attr.'>'.$value.'</option>\n';
|
||||
}
|
||||
return $ret;
|
||||
}
|
||||
|
||||
public static function getMembersOptions($id, $all=false){
|
||||
$values = User::where('active', '=', true)->where('blocked', '=', false)->where('payment_account', '>=', now())->get();
|
||||
$ret = "";
|
||||
if($all){
|
||||
$ret .= '<option value="">'.__('please select').'</option>\n';
|
||||
}
|
||||
foreach ($values as $value){
|
||||
$attr = ($value->id == $id) ? 'selected="selected"' : '';
|
||||
$to="";
|
||||
if($value->account){
|
||||
$to = $value->account->first_name." ".$value->account->last_name." | ";
|
||||
}
|
||||
$ret .= '<option value="'.$value->id.'" '.$attr.'>'.$to.$value->email.' #'.$value->account->m_account.'</option>\n';
|
||||
|
||||
}
|
||||
return $ret;
|
||||
}
|
||||
|
||||
public static function getUserCustomerOptions($id, $all=false){
|
||||
$values = ShoppingUser::select(['id', 'billing_firstname', 'billing_lastname', 'billing_email', 'number'])
|
||||
->where('shopping_users.member_id', '=', \Auth::user()->id)->get();
|
||||
$ret = "";
|
||||
if($all){
|
||||
$ret .= '<option value="">'.__('please select').'</option>\n';
|
||||
}
|
||||
foreach ($values as $value){
|
||||
$attr = ($value->id == $id) ? 'selected="selected"' : '';
|
||||
$to = $value->billing_firstname." ".$value->billing_lastname." | ".$value->billing_email;
|
||||
$ret .= '<option value="'.$value->id.'" '.$attr.'>'.$to.' #'.$value->number.'</option>\n';
|
||||
|
||||
}
|
||||
return $ret;
|
||||
}
|
||||
|
||||
public static function getOptionRange($select, $from=1, $to=50){
|
||||
$values = range($from, $to);
|
||||
$ret = "";
|
||||
foreach ($values as $value){
|
||||
$attr = ($value == $select) ? 'selected="selected"' : '';
|
||||
$ret .= '<option value="'.$value.'" '.$attr.'>'.$value.'</option>\n';
|
||||
}
|
||||
return $ret;
|
||||
|
||||
}
|
||||
}
|
||||
511
dev/app-bak/Services/HomepartyCart.php
Normal file
511
dev/app-bak/Services/HomepartyCart.php
Normal file
|
|
@ -0,0 +1,511 @@
|
|||
<?php
|
||||
namespace App\Services;
|
||||
|
||||
|
||||
|
||||
|
||||
use App\Models\Product;
|
||||
use App\Models\Setting;
|
||||
use App\Models\Homeparty;
|
||||
|
||||
class HomepartyCart
|
||||
{
|
||||
/*private $shipping_price = 0;
|
||||
private $shipping_price_net = 0;
|
||||
private $shipping_tax_rate = 0;
|
||||
private $shipping_tax = 0;
|
||||
private $shipping_country_id = 0; //default de
|
||||
private $shipping_is_for;
|
||||
private $num_comp;
|
||||
private $ysession;
|
||||
private $yinstance;
|
||||
private $shopping_data = [];*/
|
||||
|
||||
|
||||
public static $points = 0;
|
||||
public static $price = 0;
|
||||
public static $price_net = 0;
|
||||
public static $ek_price = 0;
|
||||
public static $ek_price_net = 0;
|
||||
|
||||
public static $income_price = 0;
|
||||
public static $homeparty;
|
||||
|
||||
private static $shipping_total = 0;
|
||||
private static $shipping_net_total = 0;
|
||||
|
||||
private static $userCarts = [];
|
||||
|
||||
public static $user_host_id;
|
||||
|
||||
public static $is_bonus = false;
|
||||
public static $is_bonus_coupon = false;
|
||||
|
||||
|
||||
private static $bonus_coupon = 0;
|
||||
|
||||
private static $voucher_price = 0;
|
||||
public static $voucher_name = "";
|
||||
|
||||
|
||||
private static $bonus_diff = 0;
|
||||
private static $bonus_points_diff = 0;
|
||||
private static $bonus_coupon_fault = 0;
|
||||
private static $bonus_coupon_next_step = 0;
|
||||
private static $bonus_coupon_next_value = 0;
|
||||
private static $bonus_start = 230; //230
|
||||
private static $bonus_value = 30; //30
|
||||
|
||||
|
||||
private static $bonusTable = [
|
||||
295 => 15,
|
||||
350 => 20,
|
||||
460 => 30,
|
||||
565 => 35,
|
||||
670 => 40,
|
||||
780 => 50,
|
||||
];
|
||||
|
||||
public static function init(){
|
||||
self::$bonus_value = Setting::getContentBySlug('hp-bonus-value');
|
||||
self::$bonus_start = Setting::getContentBySlug('hp-bonus-start');
|
||||
if($hpBonusSteps = Setting::getContentBySlug('hp-bonus-steps')){
|
||||
self::$bonusTable = [];
|
||||
for ($i=1; $i <= $hpBonusSteps; $i++) {
|
||||
self::$bonusTable[Setting::getContentBySlug('hp-bonus-step-start-'.$i)] = Setting::getContentBySlug('hp-bonus-step-value-'.$i);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public static function calculateHomeparty(Homeparty $homeparty){
|
||||
self::init();
|
||||
self::$homeparty = $homeparty;
|
||||
foreach ($homeparty->homeparty_users as $homeparty_user){
|
||||
if($homeparty_user->is_host){
|
||||
self::$user_host_id = $homeparty_user->id;
|
||||
}
|
||||
self::$userCarts[$homeparty_user->id] = new HomepartyUserCart($homeparty_user);
|
||||
self::addCart(self::$userCarts[$homeparty_user->id]);
|
||||
|
||||
}
|
||||
self::caluclateBonus();
|
||||
self::calculateBonusHost();
|
||||
self::caluclateShipping();
|
||||
self::recalculate();
|
||||
|
||||
|
||||
}
|
||||
|
||||
public static function addCart(HomepartyUserCart $homepartyUserCart){
|
||||
self::$points += $homepartyUserCart->points;
|
||||
self::$price += $homepartyUserCart->price;
|
||||
self::$price_net += $homepartyUserCart->price_net;
|
||||
self::$ek_price += $homepartyUserCart->ek_price;
|
||||
self::$ek_price_net += $homepartyUserCart->ek_price_net;
|
||||
self::$income_price += $homepartyUserCart->income_price;
|
||||
}
|
||||
|
||||
public static function getUserCart($id){
|
||||
return isset(self::$userCarts[$id]) ? self::$userCarts[$id] : null;
|
||||
}
|
||||
|
||||
private static function recalculate(){
|
||||
self::$points =0;
|
||||
self::$price = 0;
|
||||
self::$price_net = 0;
|
||||
self::$ek_price = 0;
|
||||
self::$ek_price_net = 0;
|
||||
self::$income_price = 0;
|
||||
foreach(self::$userCarts as $user_cart){
|
||||
self::$points += $user_cart->points;
|
||||
self::$price += $user_cart->price;
|
||||
self::$price_net += $user_cart->price_net;
|
||||
self::$ek_price += $user_cart->ek_price;
|
||||
self::$ek_price_net += $user_cart->ek_price_net;
|
||||
self::$income_price += $user_cart->income_price;
|
||||
}
|
||||
}
|
||||
|
||||
private static function caluclateBonus(){
|
||||
|
||||
if(self::$price >= 200){
|
||||
self::$is_bonus = true;
|
||||
$proportional_voucher = Product::whereIdentifier('proportional_voucher')->first();
|
||||
self::$voucher_price = $proportional_voucher->price;
|
||||
self::$voucher_name = $proportional_voucher->getLang('name');
|
||||
|
||||
//add voucher to ek
|
||||
self::$ek_price += self::$voucher_price;
|
||||
self::$ek_price_net += $proportional_voucher->getPriceWith(true, false);
|
||||
|
||||
$bonus_tmp = self::$price - self::$bonus_value;
|
||||
|
||||
//look up for coupon in table
|
||||
foreach (self::$bonusTable as $val=>$coupon){
|
||||
if($bonus_tmp >= $val){
|
||||
self::$is_bonus_coupon = true;
|
||||
self::$bonus_coupon = $coupon;
|
||||
}else{
|
||||
if(self::$bonus_coupon_fault === 0){
|
||||
self::$bonus_coupon_fault = $val - $bonus_tmp;
|
||||
self::$bonus_coupon_next_step = $val;
|
||||
self::$bonus_coupon_next_value = $coupon;
|
||||
}
|
||||
}
|
||||
}
|
||||
$keys = array_keys(self::$bonusTable);
|
||||
$step = $keys[count($keys)-1];
|
||||
if($bonus_tmp > $step){
|
||||
self::$bonus_coupon_next_step = $step;
|
||||
self::$bonus_coupon_next_value =self::$bonusTable[$step];
|
||||
}
|
||||
|
||||
}else{
|
||||
self::$bonus_diff = 200 - self::$price;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
private static function calculateBonusHost(){
|
||||
if(self::$is_bonus){
|
||||
$bonus_total = self::$bonus_value + self::$bonus_coupon;
|
||||
$user_cart = self::getUserCart(self::$user_host_id);
|
||||
//cart lower the bonus
|
||||
|
||||
if($user_cart->price <= $bonus_total){
|
||||
self::$bonus_points_diff = $user_cart->points;
|
||||
$user_cart->points = 0;
|
||||
$user_cart->price = 0;
|
||||
$user_cart->price_net = 0;
|
||||
|
||||
//$price_bonus_total = $bonus_total - ($bonus_total - $user_cart->price);
|
||||
/* self::$price -= $price_bonus_total;
|
||||
self::$price_net -= ($price_bonus_total / config('app.main_tax'));
|
||||
self::$ek_price -= $price_bonus_total;
|
||||
self::$ek_price_net -= ($price_bonus_total / config('app.main_tax'));
|
||||
self::$income_price -= $user_cart->income_price;*/
|
||||
$user_cart->income_price = 0;
|
||||
|
||||
|
||||
|
||||
}else{
|
||||
$bonus_percent = (100/$user_cart->price*$bonus_total);
|
||||
self::$bonus_points_diff = round($user_cart->points/100*$bonus_percent);
|
||||
$user_cart->points -= self::$bonus_points_diff;
|
||||
//sub bonus on host
|
||||
$user_cart->price -= $bonus_total;
|
||||
$user_cart->price_net -= ($bonus_total / config('app.main_tax'));
|
||||
|
||||
|
||||
/*self::$price -= $bonus_total;
|
||||
self::$price_net -= ($bonus_total / config('app.main_tax'));
|
||||
self::$ek_price -= $bonus_total;
|
||||
self::$ek_price_net -= ($bonus_total / config('app.main_tax'));*/
|
||||
|
||||
}
|
||||
|
||||
if($user_cart->ek_price <= $bonus_total){
|
||||
$user_cart->ek_price = 0;
|
||||
$user_cart->ek_price_net = 0;
|
||||
$user_cart->income_price = $user_cart->price - $user_cart->ek_price;
|
||||
|
||||
}else{
|
||||
$user_cart->ek_price -= $bonus_total;
|
||||
$user_cart->ek_price_net -= ($bonus_total / config('app.main_tax'));
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
private static function caluclateShipping(){
|
||||
|
||||
//weight to the orders
|
||||
//first host
|
||||
$host_user_cart = self::getUserCart(self::$user_host_id);
|
||||
$host_user_cart->shipping_weight = $host_user_cart->weight;
|
||||
|
||||
foreach (self::$homeparty->homeparty_users as $homeparty_user){
|
||||
if(!$homeparty_user->is_host){
|
||||
$user_cart = self::$userCarts[$homeparty_user->id];
|
||||
if($homeparty_user->getDelivery() === 'direct'){
|
||||
$user_cart->shipping_weight += $user_cart->weight;
|
||||
}else{
|
||||
$host_user_cart->shipping_weight += $user_cart->weight;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
self::calculateShippingPrice();
|
||||
|
||||
}
|
||||
|
||||
private static function calculateShippingPrice(){
|
||||
|
||||
foreach (self::$homeparty->homeparty_users as $homeparty_user) {
|
||||
$shipping = $homeparty_user->getShipping();
|
||||
$user_cart = self::$userCarts[$homeparty_user->id];
|
||||
if(!$shipping){
|
||||
return;
|
||||
}
|
||||
if($user_cart->shipping_weight === 0){
|
||||
$shipping_price = $shipping->shipping_prices->first();
|
||||
$shipping_price->price = 0;
|
||||
$shipping_price->shipping_price_net = 0;
|
||||
}else{
|
||||
//sec by weight
|
||||
$shipping_price = self::shippingPriceByWeight($shipping->shipping_prices, $user_cart->shipping_weight);
|
||||
|
||||
//default
|
||||
if(!$shipping_price){
|
||||
$shipping_price = $shipping->shipping_prices->first();
|
||||
}
|
||||
}
|
||||
|
||||
if($shipping_price){
|
||||
$price = $shipping_price->price;
|
||||
$user_cart->shipping_price = $price;
|
||||
$user_cart->shipping_tax_rate = $shipping_price->tax_rate;
|
||||
$user_cart->shipping_price_net = round($price / ((100+$shipping_price->tax_rate) / 100), 2);
|
||||
$user_cart->shipping_tax = round($user_cart->shipping_price - $user_cart->shipping_price_net, 2);
|
||||
}
|
||||
|
||||
if($homeparty_user->is_host){
|
||||
//on the end, add prices for porto
|
||||
//$user_cart->price += $user_cart->shipping_price;
|
||||
//$user_cart->price_net += $user_cart->shipping_price_net;
|
||||
}else{
|
||||
//on the end, add prices for porto
|
||||
$user_cart->price += $user_cart->shipping_price;
|
||||
$user_cart->price_net += $user_cart->shipping_price_net;
|
||||
self::$price += $user_cart->shipping_price;
|
||||
self::$price_net += $user_cart->shipping_price_net;
|
||||
}
|
||||
|
||||
|
||||
$user_cart->ek_price += $user_cart->shipping_price;
|
||||
$user_cart->ek_price_net += $user_cart->shipping_price_net;
|
||||
|
||||
|
||||
self::$ek_price += $user_cart->shipping_price;
|
||||
self::$ek_price_net += $user_cart->shipping_price_net;
|
||||
|
||||
self::$shipping_total += $user_cart->shipping_price;
|
||||
self::$shipping_net_total += $user_cart->shipping_price_net;
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
private static function shippingPriceByWeight($prices, $weight){
|
||||
foreach ($prices as $price){
|
||||
if($price->weight_from > 0 && $price->weight_to > 0){
|
||||
if($weight >= $price->weight_from && $weight <= $price->weight_to){
|
||||
return $price;
|
||||
}
|
||||
}
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
|
||||
public static function store($identifier, $date){
|
||||
|
||||
$data = [
|
||||
'date' => $date,
|
||||
'identifier' => $identifier,
|
||||
'points' => self::$points,
|
||||
'price' => round(self::$price, 2),
|
||||
'price_net' => round(self::$price_net, 2),
|
||||
'ek_price' => round(self::$ek_price, 2),
|
||||
'ek_price_net' => round(self::$ek_price_net, 2),
|
||||
'income_price' => round(self::$income_price, 2),
|
||||
'user_host_id' => self::$user_host_id,
|
||||
'is_bonus' => self::$is_bonus,
|
||||
'is_bonus_coupon' => self::$is_bonus_coupon,
|
||||
'bonus_value' => self::$bonus_value,
|
||||
'bonus_coupon' => self::$bonus_coupon,
|
||||
'bonus_total' => self::$bonus_value + self::$bonus_coupon,
|
||||
'shipping_price' => self::$shipping_total,
|
||||
'shipping_price_net' => self::$shipping_net_total,
|
||||
'bonus_points_diff' => self::$bonus_points_diff,
|
||||
'voucher_price' => self::$voucher_price,
|
||||
'voucher_name' => self::$voucher_name,
|
||||
];
|
||||
if(self::$homeparty->getCardInfo('user_tax_free')){
|
||||
$data['price_net'] = round(self::$price, 2);
|
||||
$data['ek_price_net'] = round(self::$ek_price, 2);
|
||||
$data['shipping_price_net'] = self::$shipping_total;
|
||||
}
|
||||
$user_data = [];
|
||||
foreach (self::$homeparty->homeparty_users as $homeparty_user){
|
||||
|
||||
$user_cart = self::$userCarts[$homeparty_user->id];
|
||||
$user_data[$homeparty_user->id] = [
|
||||
'is_host' => $homeparty_user->is_host,
|
||||
'points' => $user_cart->points,
|
||||
'price' => round($user_cart->price, 2),
|
||||
'price_net' => round($user_cart->price_net, 2),
|
||||
'ek_price' => round($user_cart->ek_price, 2),
|
||||
'ek_price_net' => round($user_cart->ek_price_net, 2),
|
||||
'income_price' => round($user_cart->income_price, 2),
|
||||
'weight' => $user_cart->weight,
|
||||
'shipping_weight' => $user_cart->shipping_weight,
|
||||
'shipping_price' => round($user_cart->shipping_price, 2),
|
||||
'shipping_tax_rate' => round($user_cart->shipping_tax_rate, 2),
|
||||
'shipping_price_net' => round($user_cart->shipping_price_net, 2),
|
||||
'shipping_tax' => $user_cart->shipping_tax,
|
||||
];
|
||||
}
|
||||
$data['user_carts'] = $user_data;
|
||||
self::$homeparty->order = $data;
|
||||
self::$homeparty->save();
|
||||
|
||||
}
|
||||
|
||||
public static function getUserCartHost(){
|
||||
return self::getUserCart(self::$user_host_id);
|
||||
}
|
||||
|
||||
public static function getFormattedPoints()
|
||||
{
|
||||
return formatNumber(self::$points, 0);
|
||||
}
|
||||
|
||||
public static function getFormattedPointsTotal()
|
||||
{
|
||||
return formatNumber(self::$points - self::$bonus_points_diff, 0);
|
||||
}
|
||||
|
||||
public static function getFormattedPrice()
|
||||
{
|
||||
return formatNumber(self::$price);
|
||||
}
|
||||
|
||||
public static function getFormattedPriceNet()
|
||||
{
|
||||
return formatNumber(self::$price_net);
|
||||
}
|
||||
|
||||
public static function getFormattedEkPrice()
|
||||
{
|
||||
return formatNumber(self::$ek_price);
|
||||
}
|
||||
|
||||
public static function getFormattedEkPriceNet()
|
||||
{
|
||||
return formatNumber(self::$ek_price_net);
|
||||
}
|
||||
|
||||
public static function getFormattedIncomePrice()
|
||||
{
|
||||
return formatNumber(self::$income_price);
|
||||
}
|
||||
|
||||
public static function getFormattedPriceTax(){
|
||||
return formatNumber(self::$price - self::$price_net);
|
||||
}
|
||||
public static function getFormattedEkPriceTax(){
|
||||
return formatNumber(self::$ek_price - self::$ek_price_net);
|
||||
}
|
||||
public static function getFormattedBonusPrice()
|
||||
{
|
||||
return formatNumber(self::$voucher_price);
|
||||
}
|
||||
public static function getFormattedBonusStart(){
|
||||
return formatNumber(self::$bonus_start);
|
||||
}
|
||||
public static function getFormattedBonusValue(){
|
||||
return formatNumber(self::$bonus_value);
|
||||
}
|
||||
|
||||
public static function getFormattedBonusDiff(){
|
||||
return formatNumber(self::$bonus_diff);
|
||||
}
|
||||
|
||||
public static function getFormattedBonusCoupon(){
|
||||
return formatNumber(self::$bonus_coupon);
|
||||
}
|
||||
|
||||
public static function getFormattedBonusCouponFault(){
|
||||
return formatNumber(self::$bonus_coupon_fault);
|
||||
}
|
||||
|
||||
public static function getFormattedBonusCouponNextStep(){
|
||||
return formatNumber(self::$bonus_coupon_next_step);
|
||||
}
|
||||
public static function getFormattedBonusCouponNextValue(){
|
||||
return formatNumber(self::$bonus_coupon_next_value);
|
||||
}
|
||||
|
||||
public static function getFormattedBonusTotal(){
|
||||
if(self::$is_bonus){
|
||||
return formatNumber(self::$bonus_value + self::$bonus_coupon);
|
||||
}
|
||||
return formatNumber(0);
|
||||
}
|
||||
|
||||
public static function getFormattedBonusPointsDiff(){
|
||||
return formatNumber( self::$bonus_points_diff, 0 );
|
||||
|
||||
}
|
||||
|
||||
protected function numberFormat($value, $decimals, $decimalPoint, $thousandSeperator)
|
||||
{
|
||||
if(is_null($decimals)){
|
||||
$decimals = is_null(config('cart.format.decimals')) ? 2 : config('cart.format.decimals');
|
||||
}
|
||||
if(is_null($decimalPoint)){
|
||||
$decimalPoint = is_null(config('cart.format.decimal_point')) ? '.' : config('cart.format.decimal_point');
|
||||
}
|
||||
if(is_null($thousandSeperator)){
|
||||
$thousandSeperator = is_null(config('cart.format.thousand_seperator')) ? ',' : config('cart.format.thousand_seperator');
|
||||
}
|
||||
|
||||
return number_format($value, $decimals, $decimalPoint, $thousandSeperator);
|
||||
}
|
||||
|
||||
|
||||
public static function getCurrencyByKey($key)
|
||||
{
|
||||
$rNumber = 0;
|
||||
if(self::$homeparty && self::$homeparty->isPriceCurrency()){
|
||||
$user_country = self::$homeparty->getUserCountry();
|
||||
$faktor = isset($user_country->currency_faktor) ? $user_country->currency_faktor : 1;
|
||||
switch ($key) {
|
||||
case 'BonusValue':
|
||||
$rNumber = self::$bonus_value * $faktor;
|
||||
break;
|
||||
case 'BonusCoupon':
|
||||
$rNumber = self::$bonus_coupon * $faktor;
|
||||
break;
|
||||
case 'IncomePrice':
|
||||
$rNumber = self::$income_price * $faktor;
|
||||
break;
|
||||
case 'Price':
|
||||
$rNumber = self::$price * $faktor;
|
||||
break;
|
||||
case 'EkPrice':
|
||||
$rNumber = self::$ek_price * $faktor;
|
||||
break;
|
||||
case 'PriceNet':
|
||||
$rNumber = self::$price_net * $faktor;
|
||||
break;
|
||||
case 'EkPriceNet':
|
||||
$rNumber = self::$ek_price_net * $faktor;
|
||||
break;
|
||||
case 'PriceTax':
|
||||
$rNumber = (self::$price - self::$price_net) * $faktor;
|
||||
break;
|
||||
case 'EkPriceTax':
|
||||
$rNumber = (self::$ek_price - self::$ek_price_net)* $faktor;
|
||||
break;
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
return formatNumber($rNumber);
|
||||
}
|
||||
|
||||
}
|
||||
170
dev/app-bak/Services/HomepartyUserCart.php
Normal file
170
dev/app-bak/Services/HomepartyUserCart.php
Normal file
|
|
@ -0,0 +1,170 @@
|
|||
<?php
|
||||
namespace App\Services;
|
||||
|
||||
use App\Models\HomepartyUser;
|
||||
|
||||
|
||||
class HomepartyUserCart
|
||||
{
|
||||
/*private $shipping_price = 0;
|
||||
private $shipping_price_net = 0;
|
||||
private $shipping_tax_rate = 0;
|
||||
private $shipping_tax = 0;
|
||||
private $shipping_country_id = 0; //default de
|
||||
private $shipping_is_for;
|
||||
private $num_comp;
|
||||
private $ysession;
|
||||
private $yinstance;
|
||||
private $shopping_data = [];*/
|
||||
|
||||
|
||||
public $points;
|
||||
public $price;
|
||||
public $price_net;
|
||||
public $ek_price;
|
||||
public $ek_price_net;
|
||||
|
||||
public $real_price;
|
||||
|
||||
public $income_price;
|
||||
|
||||
public $weight;
|
||||
public $shipping_weight;
|
||||
|
||||
|
||||
public $shipping_price;
|
||||
public $shipping_tax_rate;
|
||||
public $shipping_price_net;
|
||||
public $shipping_tax;
|
||||
|
||||
|
||||
|
||||
private $homepartyUser;
|
||||
|
||||
public function __construct(HomepartyUser $homepartyUser)
|
||||
{
|
||||
$this->homepartyUser = $homepartyUser;
|
||||
//is all total
|
||||
$this->points = 0;
|
||||
$this->price = 0;
|
||||
$this->price_net = 0;
|
||||
$this->ek_price = 0;
|
||||
$this->ek_price_net = 0;
|
||||
|
||||
$this->real_price = 0;
|
||||
|
||||
$this->income_price = 0;
|
||||
$this->weight = 0;
|
||||
$this->shipping_weight = 0;
|
||||
$this->shipping_price = 0;
|
||||
$this->shipping_tax_rate = 0;
|
||||
$this->shipping_price_net = 0;
|
||||
$this->shipping_tax = 0;
|
||||
$this->calculateUserCart();
|
||||
}
|
||||
|
||||
public function calculateUserCart(){
|
||||
|
||||
foreach ($this->homepartyUser->homeparty_user_order_items as $order_item) {
|
||||
$this->points += $order_item->getTotalPoints();
|
||||
$this->price += $order_item->getTotalPrice();
|
||||
$this->real_price += $order_item->getTotalPrice();
|
||||
$this->price_net += $order_item->geTotalPriceNet();
|
||||
$this->ek_price += $order_item->geTotalEKPrice();
|
||||
$this->ek_price_net += $order_item->geTotalEKPriceNet();
|
||||
$this->income_price += $order_item->geTotalIncomePrice();
|
||||
$this->weight += ($order_item->product->weight * $order_item->qty);
|
||||
}
|
||||
}
|
||||
|
||||
public function isPrice(){
|
||||
return ($this->real_price) > 0 ? true : false;
|
||||
}
|
||||
public function getFormattedPoints()
|
||||
{
|
||||
return formatNumber($this->points, 0);
|
||||
}
|
||||
|
||||
public function getFormattedPrice()
|
||||
{
|
||||
return formatNumber($this->price);
|
||||
}
|
||||
|
||||
public function getFormattedPriceWithout()
|
||||
{
|
||||
return formatNumber($this->price - $this->shipping_price);
|
||||
}
|
||||
|
||||
public function getFormattedPriceNet()
|
||||
{
|
||||
return formatNumber($this->price_net);
|
||||
}
|
||||
|
||||
public function getFormattedEkPrice()
|
||||
{
|
||||
return formatNumber($this->ek_price);
|
||||
}
|
||||
|
||||
public function getFormattedEkPriceWithout()
|
||||
{
|
||||
return formatNumber($this->ek_price - $this->shipping_price);
|
||||
}
|
||||
|
||||
public function getFormattedIncomePrice()
|
||||
{
|
||||
return formatNumber($this->income_price);
|
||||
}
|
||||
|
||||
public function getFormattedShippingPrice()
|
||||
{
|
||||
return formatNumber($this->shipping_price);
|
||||
}
|
||||
|
||||
protected function numberFormat($value, $decimals, $decimalPoint, $thousandSeperator)
|
||||
{
|
||||
if(is_null($decimals)){
|
||||
$decimals = is_null(config('cart.format.decimals')) ? 2 : config('cart.format.decimals');
|
||||
}
|
||||
if(is_null($decimalPoint)){
|
||||
$decimalPoint = is_null(config('cart.format.decimal_point')) ? '.' : config('cart.format.decimal_point');
|
||||
}
|
||||
if(is_null($thousandSeperator)){
|
||||
$thousandSeperator = is_null(config('cart.format.thousand_seperator')) ? ',' : config('cart.format.thousand_seperator');
|
||||
}
|
||||
|
||||
return number_format($value, $decimals, $decimalPoint, $thousandSeperator);
|
||||
}
|
||||
|
||||
|
||||
public function getCurrencyByKey($key)
|
||||
{
|
||||
$rNumber = 0;
|
||||
if($this->homepartyUser->homeparty && $this->homepartyUser->homeparty->isPriceCurrency()){
|
||||
$user_country = $this->homepartyUser->homeparty->getUserCountry();
|
||||
$faktor = isset($user_country->currency_faktor) ? $user_country->currency_faktor : 1;
|
||||
switch ($key) {
|
||||
case 'ShippingPrice':
|
||||
$rNumber = $this->shipping_price * $faktor;
|
||||
break;
|
||||
case 'IncomePrice':
|
||||
$rNumber = $this->income_price * $faktor;
|
||||
break;
|
||||
case 'Price':
|
||||
$rNumber = $this->price * $faktor;
|
||||
break;
|
||||
case 'PriceWithout':
|
||||
$rNumber = ($this->price - $this->shipping_price) * $faktor;
|
||||
break;
|
||||
case 'EkPrice':
|
||||
$rNumber = $this->ek_price * $faktor;
|
||||
break;
|
||||
case 'EkPriceWithout':
|
||||
$rNumber = ($this->ek_price - $this->shipping_price) * $faktor;
|
||||
break;
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
return formatNumber($rNumber);
|
||||
}
|
||||
}
|
||||
15
dev/app-bak/Services/IPinfo/.editorconfig
Normal file
15
dev/app-bak/Services/IPinfo/.editorconfig
Normal file
|
|
@ -0,0 +1,15 @@
|
|||
; This file is for unifying the coding style for different editors and IDEs.
|
||||
; More information at http://editorconfig.org
|
||||
|
||||
root = true
|
||||
|
||||
[*]
|
||||
charset = utf-8
|
||||
indent_size = 4
|
||||
indent_style = space
|
||||
end_of_line = lf
|
||||
insert_final_newline = true
|
||||
trim_trailing_whitespace = true
|
||||
|
||||
[*.md]
|
||||
trim_trailing_whitespace = false
|
||||
42
dev/app-bak/Services/IPinfo/.github/workflows/phpunit.yaml
vendored
Normal file
42
dev/app-bak/Services/IPinfo/.github/workflows/phpunit.yaml
vendored
Normal file
|
|
@ -0,0 +1,42 @@
|
|||
name: Unit Tests
|
||||
|
||||
on:
|
||||
pull_request:
|
||||
|
||||
permissions:
|
||||
contents: read
|
||||
|
||||
jobs:
|
||||
run:
|
||||
|
||||
runs-on: ${{ matrix.operating-system }}
|
||||
strategy:
|
||||
matrix:
|
||||
operating-system: [ubuntu-latest]
|
||||
php-versions: ['8.0', '8.1', '8.2']
|
||||
phpunit-versions: ['9.5.20']
|
||||
|
||||
name: PHP ${{ matrix.php-versions }} Test on ${{ matrix.operating-system }}
|
||||
steps:
|
||||
- name: Checkout
|
||||
uses: actions/checkout@v2
|
||||
|
||||
- name: Setup PHP
|
||||
uses: shivammathur/setup-php@v2
|
||||
with:
|
||||
php-version: ${{ matrix.php-versions }}
|
||||
tools: phpunit:${{ matrix.phpunit-versions }}
|
||||
|
||||
- name: Check PHP Version
|
||||
run: php -v
|
||||
|
||||
- name: Validate composer.json and composer.lock
|
||||
run: composer validate --strict
|
||||
|
||||
- name: Composer install
|
||||
run: composer install --optimize-autoloader --prefer-dist --ignore-platform-reqs
|
||||
|
||||
- name: Run test suite
|
||||
env:
|
||||
IPINFO_TOKEN: ${{ secrets.IPINFO_TOKEN }}
|
||||
run: /usr/local/bin/phpunit --coverage-text
|
||||
1
dev/app-bak/Services/IPinfo/.styleci.yml
Normal file
1
dev/app-bak/Services/IPinfo/.styleci.yml
Normal file
|
|
@ -0,0 +1 @@
|
|||
preset: psr2
|
||||
55
dev/app-bak/Services/IPinfo/Details.php
Normal file
55
dev/app-bak/Services/IPinfo/Details.php
Normal file
|
|
@ -0,0 +1,55 @@
|
|||
<?php
|
||||
|
||||
namespace App\Services\IPinfo;
|
||||
|
||||
/**
|
||||
* Holds formatted data for a single IP address.
|
||||
*/
|
||||
class Details
|
||||
{
|
||||
public $country;
|
||||
public $country_name;
|
||||
public $country_flag;
|
||||
public $country_code;
|
||||
public $country_flag_url;
|
||||
public $country_currency;
|
||||
public $continent;
|
||||
public $latitude;
|
||||
public $longitude;
|
||||
public $loc;
|
||||
public $is_eu;
|
||||
public $ip;
|
||||
public $hostname;
|
||||
public $anycast;
|
||||
public $city;
|
||||
public $org;
|
||||
public $postal;
|
||||
public $region;
|
||||
public $timezone;
|
||||
public $asn;
|
||||
public $company;
|
||||
public $privacy;
|
||||
public $abuse;
|
||||
public $domains;
|
||||
public $bogon;
|
||||
public $all;
|
||||
public $error;
|
||||
|
||||
|
||||
public function __construct($raw_details)
|
||||
{
|
||||
foreach ($raw_details as $property => $value) {
|
||||
$this->$property = $value;
|
||||
}
|
||||
$this->all = $raw_details;
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns json string representation.
|
||||
*
|
||||
* @internal this class should implement Stringable explicitly when leaving support for PHP verision < 8.0
|
||||
*/
|
||||
public function __toString(): string {
|
||||
return json_encode($this);
|
||||
}
|
||||
}
|
||||
419
dev/app-bak/Services/IPinfo/IPinfo.php
Normal file
419
dev/app-bak/Services/IPinfo/IPinfo.php
Normal file
|
|
@ -0,0 +1,419 @@
|
|||
<?php
|
||||
|
||||
namespace App\Services\IPinfo;
|
||||
|
||||
use Exception;
|
||||
use GuzzleHttp\Pool;
|
||||
use GuzzleHttp\Client;
|
||||
use GuzzleHttp\Promise;
|
||||
use GuzzleHttp\Psr7\Request;
|
||||
use GuzzleHttp\Psr7\Response;
|
||||
use GuzzleHttp\Exception\GuzzleException;
|
||||
use App\Services\ipinfo\cache\DefaultCache;
|
||||
use Symfony\Component\HttpFoundation\IpUtils;
|
||||
|
||||
/**
|
||||
* Exposes the IPinfo library to client code.
|
||||
*/
|
||||
class IPinfo
|
||||
{
|
||||
const API_URL = 'https://ipinfo.io';
|
||||
const COUNTRY_FLAG_URL = 'https://cdn.ipinfo.io/static/images/countries-flags/';
|
||||
const STATUS_CODE_QUOTA_EXCEEDED = 429;
|
||||
const REQUEST_TIMEOUT_DEFAULT = 2; // seconds
|
||||
|
||||
const CACHE_MAXSIZE = 4096;
|
||||
const CACHE_TTL = 86400; // 24 hours as seconds
|
||||
const CACHE_KEY_VSN = '1'; // update when cache vals change for same key.
|
||||
|
||||
const COUNTRIES_FILE_DEFAULT = __DIR__ . '/json/countries.json';
|
||||
const COUNTRIES_FLAGS_FILE_DEFAULT = __DIR__ . '/json/flags.json';
|
||||
const EU_COUNTRIES_FILE_DEFAULT = __DIR__ . '/json/eu.json';
|
||||
const COUNTRIES_CURRENCIES_FILE_DEFAULT = __DIR__ . '/json/currency.json';
|
||||
const CONTINENT_FILE_DEFAULT = __DIR__ . '/json/continent.json';
|
||||
|
||||
const BATCH_MAX_SIZE = 1000;
|
||||
const BATCH_TIMEOUT = 5; // seconds
|
||||
|
||||
public $access_token;
|
||||
public $settings;
|
||||
public $cache;
|
||||
public $countries;
|
||||
public $eu_countries;
|
||||
public $countries_flags;
|
||||
public $countries_currencies;
|
||||
public $continents;
|
||||
protected $http_client;
|
||||
|
||||
public function __construct($access_token = null, $settings = [])
|
||||
{
|
||||
$this->access_token = $access_token;
|
||||
$this->settings = $settings;
|
||||
|
||||
/*
|
||||
Support a timeout first-class, then a `guzzle_opts` key that can
|
||||
override anything.
|
||||
*/
|
||||
$guzzle_opts = [
|
||||
'http_errors' => false,
|
||||
'headers' => $this->buildHeaders(),
|
||||
'timeout' => $settings['timeout'] ?? self::REQUEST_TIMEOUT_DEFAULT
|
||||
];
|
||||
if (isset($settings['guzzle_opts'])) {
|
||||
$guzzle_opts = array_merge($guzzle_opts, $settings['guzzle_opts']);
|
||||
}
|
||||
$this->http_client = new Client($guzzle_opts);
|
||||
|
||||
$countries_file = $settings['countries_file'] ?? self::COUNTRIES_FILE_DEFAULT;
|
||||
$countries_flags_file = $settings['countries_flags_file'] ?? self::COUNTRIES_FLAGS_FILE_DEFAULT;
|
||||
$countries_currencies_file = $settings['countries_currencies_file'] ?? self::COUNTRIES_CURRENCIES_FILE_DEFAULT;
|
||||
$eu_countries_file = $settings['eu_countries_file'] ?? self::EU_COUNTRIES_FILE_DEFAULT;
|
||||
$continents_file = $settings['continent_file'] ?? self::CONTINENT_FILE_DEFAULT;
|
||||
$this->countries = $this->readJSONFile($countries_file);
|
||||
$this->countries_flags = $this->readJSONFile($countries_flags_file);
|
||||
$this->countries_currencies = $this->readJSONFile($countries_currencies_file);
|
||||
$this->eu_countries = $this->readJSONFile($eu_countries_file);
|
||||
$this-> continents = $this->readJSONFile($continents_file);
|
||||
|
||||
/*if (!array_key_exists('cache_disabled', $this->settings) || $this->settings['cache_disabled'] == false) {
|
||||
if (array_key_exists('cache', $settings)) {
|
||||
$this->cache = $settings['cache'];
|
||||
} else {
|
||||
$maxsize = $settings['cache_maxsize'] ?? self::CACHE_MAXSIZE;
|
||||
$ttl = $settings['cache_ttl'] ?? self::CACHE_TTL;
|
||||
$this->cache = new DefaultCache($maxsize, $ttl);
|
||||
}
|
||||
} else {
|
||||
$this->cache = null;
|
||||
}*/
|
||||
}
|
||||
|
||||
/**
|
||||
* Get formatted details for an IP address.
|
||||
* @param string|null $ip_address IP address to look up.
|
||||
* @return Details Formatted IPinfo data.
|
||||
* @throws IPinfoException
|
||||
*/
|
||||
public function getDetails($ip_address = null)
|
||||
{
|
||||
$response_details = $this->getRequestDetails((string) $ip_address);
|
||||
return $this->formatDetailsObject($response_details);
|
||||
}
|
||||
|
||||
/**
|
||||
* Get formatted details for a list of IP addresses.
|
||||
* @param $urls the array of URLs.
|
||||
* @param $batchSize default value is set to max value for batch size, which is 1000.
|
||||
* @param batchTimeout in seconds. Default value is 5 seconds.
|
||||
* @param filter default value is false.
|
||||
* @return $results
|
||||
*/
|
||||
public function getBatchDetails(
|
||||
$urls,
|
||||
$batchSize = 0,
|
||||
$batchTimeout = self::BATCH_TIMEOUT,
|
||||
$filter = false
|
||||
) {
|
||||
$lookupUrls = [];
|
||||
$results = [];
|
||||
|
||||
// no items?
|
||||
if (count($urls) == 0) {
|
||||
return $results;
|
||||
}
|
||||
|
||||
// clip batch size.
|
||||
if (!is_numeric($batchSize) || $batchSize <= 0 || $batchSize > self::BATCH_MAX_SIZE) {
|
||||
$batchSize = self::BATCH_MAX_SIZE;
|
||||
}
|
||||
|
||||
// filter out URLs already cached.
|
||||
if ($this->cache != null) {
|
||||
foreach ($urls as $url) {
|
||||
$cachedRes = $this->cache->get($this->cacheKey($url));
|
||||
if ($cachedRes != null) {
|
||||
$results[$url] = $cachedRes;
|
||||
} else {
|
||||
$lookupUrls[] = $url;
|
||||
}
|
||||
}
|
||||
} else {
|
||||
$lookupUrls = $urls;
|
||||
}
|
||||
|
||||
// everything cached? exit early.
|
||||
if (count($lookupUrls) == 0) {
|
||||
return $results;
|
||||
}
|
||||
|
||||
// prepare each batch & fire it off asynchronously.
|
||||
$apiUrl = self::API_URL . "/batch";
|
||||
if ($filter) {
|
||||
$apiUrl .= '?filter=1';
|
||||
}
|
||||
$promises = [];
|
||||
$totalBatches = ceil(count($lookupUrls) / $batchSize);
|
||||
for ($i = 0; $i < $totalBatches; $i++) {
|
||||
$start = $i * $batchSize;
|
||||
$batch = array_slice($lookupUrls, $start, $batchSize);
|
||||
$promise = $this->http_client->postAsync($apiUrl, [
|
||||
'body' => json_encode($batch),
|
||||
'timeout' => $batchTimeout
|
||||
])->then(function ($resp) use (&$results) {
|
||||
$batchResult = json_decode($resp->getBody(), true);
|
||||
foreach ($batchResult as $k => $v) {
|
||||
$results[$k] = $v;
|
||||
}
|
||||
});
|
||||
$promises[] = $promise;
|
||||
}
|
||||
|
||||
// wait for all batches to finish.
|
||||
Promise\Utils::settle($promises)->wait();
|
||||
|
||||
// cache any new results.
|
||||
if ($this->cache != null) {
|
||||
foreach ($lookupUrls as $url) {
|
||||
if (array_key_exists($url, $results)) {
|
||||
$this->cache->set($this->cacheKey($url), $results[$url]);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return $results;
|
||||
}
|
||||
|
||||
public function formatDetailsObject($details = [])
|
||||
{
|
||||
$country = $details['country'] ?? null;
|
||||
$details['country_name'] = $this->countries[$country] ?? null;
|
||||
$details['is_eu'] = in_array($country, $this->eu_countries);
|
||||
$details['country_flag'] = $this->countries_flags[$country] ?? null;
|
||||
$details['country_flag_url'] = self::COUNTRY_FLAG_URL.$country.".svg";
|
||||
$details['country_currency'] = $this->countries_currencies[$country] ?? null;
|
||||
$details['continent'] = $this->continents[$country] ?? null;
|
||||
|
||||
if (array_key_exists('loc', $details)) {
|
||||
$coords = explode(',', $details['loc']);
|
||||
$details['latitude'] = $coords[0];
|
||||
$details['longitude'] = $coords[1];
|
||||
} else {
|
||||
$details['latitude'] = null;
|
||||
$details['longitude'] = null;
|
||||
}
|
||||
|
||||
return new Details($details);
|
||||
}
|
||||
|
||||
/**
|
||||
* Get details for a specific IP address.
|
||||
* @param string $ip_address IP address to query API for.
|
||||
* @return array IP response data.
|
||||
* @throws IPinfoException
|
||||
*/
|
||||
public function getRequestDetails(string $ip_address)
|
||||
{
|
||||
if ($this->isBogon($ip_address)) {
|
||||
return [
|
||||
"ip" => $ip_address,
|
||||
"bogon" => true,
|
||||
];
|
||||
}
|
||||
|
||||
if ($this->cache != null) {
|
||||
$cachedRes = $this->cache->get($this->cacheKey($ip_address));
|
||||
if ($cachedRes != null) {
|
||||
return $cachedRes;
|
||||
}
|
||||
}
|
||||
|
||||
$url = self::API_URL;
|
||||
if ($ip_address) {
|
||||
$url .= "/$ip_address";
|
||||
}
|
||||
|
||||
try {
|
||||
$response = $this->http_client->request('GET', $url);
|
||||
} catch (GuzzleException $e) {
|
||||
\Log::channel('ipinfo')->error('IPinfo::getRequestDetails GuzzleException.'. $e->getMessage());
|
||||
return [
|
||||
"ip" => $ip_address,
|
||||
"error" => $e->getMessage(),
|
||||
];
|
||||
//throw new IPinfoException($e->getMessage());
|
||||
} catch (Exception $e) {
|
||||
\Log::channel('ipinfo')->error('IPinfo::getRequestDetails Exception.'. $e->getMessage());
|
||||
return [
|
||||
"ip" => $ip_address,
|
||||
"error" => $e->getMessage(),
|
||||
];
|
||||
//throw new IPinfoException($e->getMessage());
|
||||
}
|
||||
|
||||
if ($response->getStatusCode() == self::STATUS_CODE_QUOTA_EXCEEDED) {
|
||||
//throw new IPinfoException('IPinfo request quota exceeded.');
|
||||
} elseif ($response->getStatusCode() >= 400) {
|
||||
\Log::channel('ipinfo')->error('IPinfo::getRequestDetails getStatusCode.'. json_encode([
|
||||
'status' => $response->getStatusCode(),
|
||||
'reason' => $response->getReasonPhrase(),
|
||||
]));
|
||||
|
||||
return [
|
||||
"ip" => $ip_address,
|
||||
'status' => $response->getStatusCode(),
|
||||
'reason' => $response->getReasonPhrase(),
|
||||
"error" => 'getStatusCode',
|
||||
];
|
||||
/*throw new IPinfoException('Exception: ' . json_encode([
|
||||
'status' => $response->getStatusCode(),
|
||||
'reason' => $response->getReasonPhrase(),
|
||||
]));*/
|
||||
}
|
||||
|
||||
$raw_details = json_decode($response->getBody(), true);
|
||||
|
||||
if ($this->cache != null) {
|
||||
$this->cache->set($this->cacheKey($ip_address), $raw_details);
|
||||
}
|
||||
|
||||
return $raw_details;
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets a URL to a map on https://ipinfo.io/map given a list of IPs (max
|
||||
* 500,000).
|
||||
* @param array $ips list of IP addresses to put on the map.
|
||||
* @return string URL to the map.
|
||||
*/
|
||||
public function getMapUrl($ips)
|
||||
{
|
||||
$url = sprintf("%s/map?cli=1", self::API_URL);
|
||||
|
||||
try {
|
||||
$response = $this->http_client->request(
|
||||
'POST',
|
||||
$url,
|
||||
[
|
||||
'json' => $ips
|
||||
]
|
||||
);
|
||||
} catch (GuzzleException $e) {
|
||||
throw new IPinfoException($e->getMessage());
|
||||
} catch (Exception $e) {
|
||||
throw new IPinfoException($e->getMessage());
|
||||
}
|
||||
|
||||
$res = json_decode($response->getBody(), true);
|
||||
return $res['reportUrl'];
|
||||
}
|
||||
|
||||
/**
|
||||
* Build headers for API request.
|
||||
* @return array Headers for API request.
|
||||
*/
|
||||
private function buildHeaders()
|
||||
{
|
||||
$headers = [
|
||||
'user-agent' => 'IPinfoClient/PHP/3.1.0',
|
||||
'accept' => 'application/json',
|
||||
'content-type' => 'application/json',
|
||||
];
|
||||
|
||||
if ($this->access_token) {
|
||||
$headers['authorization'] = "Bearer {$this->access_token}";
|
||||
}
|
||||
|
||||
return $headers;
|
||||
}
|
||||
|
||||
/**
|
||||
* Read JSON from a file and return as an array.
|
||||
* @param string $countries_file JSON file of country_code => country_name mappings
|
||||
* @return array country_code => country_name mappings
|
||||
*/
|
||||
private function readJSONFile($countries_file)
|
||||
{
|
||||
$file_contents = file_get_contents($countries_file);
|
||||
return json_decode($file_contents, true);
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns a versioned cache key given a user-input key.
|
||||
* @param string $k key to transform into a versioned cache key.
|
||||
* @return string the versioned cache key.
|
||||
*/
|
||||
private function cacheKey($k)
|
||||
{
|
||||
return sprintf('%s:%s', $k, self::CACHE_KEY_VSN);
|
||||
}
|
||||
|
||||
/**
|
||||
* Check if an IP address is a bogon.
|
||||
*
|
||||
* @param string $ip The IP address to check
|
||||
* @return bool True if the IP address is a bogon, false otherwise
|
||||
*/
|
||||
public function isBogon($ip)
|
||||
{
|
||||
// Check if the IP address is in the range
|
||||
return IpUtils::checkIp($ip, $this->bogonNetworks);
|
||||
}
|
||||
|
||||
// List of bogon CIDRs.
|
||||
protected $bogonNetworks = [
|
||||
"0.0.0.0/8",
|
||||
"10.0.0.0/8",
|
||||
"100.64.0.0/10",
|
||||
"127.0.0.0/8",
|
||||
"169.254.0.0/16",
|
||||
"172.16.0.0/12",
|
||||
"192.0.0.0/24",
|
||||
"192.0.2.0/24",
|
||||
"192.168.0.0/16",
|
||||
"198.18.0.0/15",
|
||||
"198.51.100.0/24",
|
||||
"203.0.113.0/24",
|
||||
"224.0.0.0/4",
|
||||
"240.0.0.0/4",
|
||||
"255.255.255.255/32",
|
||||
"::/128",
|
||||
"::1/128",
|
||||
"::ffff:0:0/96",
|
||||
"::/96",
|
||||
"100::/64",
|
||||
"2001:10::/28",
|
||||
"2001:db8::/32",
|
||||
"fc00::/7",
|
||||
"fe80::/10",
|
||||
"fec0::/10",
|
||||
"ff00::/8",
|
||||
"2002::/24",
|
||||
"2002:a00::/24",
|
||||
"2002:7f00::/24",
|
||||
"2002:a9fe::/32",
|
||||
"2002:ac10::/28",
|
||||
"2002:c000::/40",
|
||||
"2002:c000:200::/40",
|
||||
"2002:c0a8::/32",
|
||||
"2002:c612::/31",
|
||||
"2002:c633:6400::/40",
|
||||
"2002:cb00:7100::/40",
|
||||
"2002:e000::/20",
|
||||
"2002:f000::/20",
|
||||
"2002:ffff:ffff::/48",
|
||||
"2001::/40",
|
||||
"2001:0:a00::/40",
|
||||
"2001:0:7f00::/40",
|
||||
"2001:0:a9fe::/48",
|
||||
"2001:0:ac10::/44",
|
||||
"2001:0:c000::/56",
|
||||
"2001:0:c000:200::/56",
|
||||
"2001:0:c0a8::/48",
|
||||
"2001:0:c612::/47",
|
||||
"2001:0:c633:6400::/56",
|
||||
"2001:0:cb00:7100::/56",
|
||||
"2001:0:e000::/36",
|
||||
"2001:0:f000::/36",
|
||||
"2001:0:ffff:ffff::/64"
|
||||
];
|
||||
}
|
||||
8
dev/app-bak/Services/IPinfo/IPinfoException.php
Normal file
8
dev/app-bak/Services/IPinfo/IPinfoException.php
Normal file
|
|
@ -0,0 +1,8 @@
|
|||
<?php
|
||||
|
||||
namespace App\Services\IPinfo;
|
||||
use Exception;
|
||||
|
||||
class IPinfoException extends Exception
|
||||
{
|
||||
}
|
||||
59
dev/app-bak/Services/IPinfo/_info/CHANGELOG.md
Normal file
59
dev/app-bak/Services/IPinfo/_info/CHANGELOG.md
Normal file
|
|
@ -0,0 +1,59 @@
|
|||
# CHANGELOG
|
||||
|
||||
### 3.1.1 (August 3rd 2023)
|
||||
|
||||
- Patched deprecations.
|
||||
|
||||
### 3.1.0 (July 28th 2023)
|
||||
|
||||
- Default cache changed. Replaced `sabre/cache` with `symfony/cache`.
|
||||
|
||||
### 3.0.1 (June 19th 2023)
|
||||
|
||||
- Added the link of country flag image.
|
||||
|
||||
### 3.0.0 (December 27th 2022)
|
||||
|
||||
- Require PHP >= 8.0.
|
||||
- Add local bogon checking.
|
||||
|
||||
### 2.3.1 (June 27 2022)
|
||||
|
||||
- Added Stringable implementation for PHP 8.0 with backward compatibility.
|
||||
|
||||
### 2.3.0 (September 21 2021)
|
||||
|
||||
- Added batch ops integration.
|
||||
- Added the ability to disable cache usage entirely.
|
||||
|
||||
### 2.2.0 (April 22nd 2021)
|
||||
|
||||
- Added Maps integration.
|
||||
- Added versioned cache keys.
|
||||
This allows more reliable changes to cached data in the future without
|
||||
causing confusing incompatibilities. This should be transparent to the user.
|
||||
This is primarily useful for users with persistent cache implementations.
|
||||
|
||||
### 2.1.1 (January 12 2021)
|
||||
|
||||
- Bug fix issue reported in Laravel SDK
|
||||
(https://github.com/ipinfo/laravel/issues/14) which also applies in PHP SDK,
|
||||
with https://github.com/ipinfo/php/pull/27.
|
||||
|
||||
### 2.1.0 (December 2 2020)
|
||||
|
||||
- Deprecate PHP 7.2 support.
|
||||
- Add support for PHP 8.0.
|
||||
|
||||
### 2.0.0 (November 2020)
|
||||
|
||||
- A `guzzle_opts` option is supported in the settings, which allows full Guzzle
|
||||
option overrides.
|
||||
- A `timeout` option is supported in the settings, which is the request timeout
|
||||
value, and defaults to 2 seconds.
|
||||
**BREAKING**: this was previously unconfigurable and was 0 seconds,
|
||||
i.e. infinite timeout.
|
||||
- The `buildHeaders` method on the main `IPinfo` client is now private.
|
||||
**BREAKING**: this will no longer be available for use from the client.
|
||||
- Only non-EOL PHP 7 versions are supported. In particular, PHP 7.2 and above
|
||||
are all supported and tested in the CI.
|
||||
257
dev/app-bak/Services/IPinfo/_info/README.md
Normal file
257
dev/app-bak/Services/IPinfo/_info/README.md
Normal file
|
|
@ -0,0 +1,257 @@
|
|||
# [<img src="https://ipinfo.io/static/ipinfo-small.svg" alt="IPinfo" width="24"/>](https://ipinfo.io/) IPinfo PHP Client Library
|
||||
|
||||
This is the official PHP client library for the [IPinfo.io](https://ipinfo.io) IP address API, allowing you to look up your own IP address, or get any of the following details for an IP:
|
||||
- [IP to Geolocation data](https://ipinfo.io/ip-geolocation-api) (city, region, country, postal code, latitude, and longitude)
|
||||
- [ASN information](https://ipinfo.io/asn-api) (ISP or network operator, associated domain name, and type, such as business, hosting, or company)
|
||||
- [Company details](https://ipinfo.io/ip-company-api) (the name and domain of the business that uses the IP address)
|
||||
- [Carrier information](https://ipinfo.io/ip-carrier-api) (the name of the mobile carrier and MNC and MCC for that carrier if the IP is used exclusively for mobile traffic)
|
||||
|
||||
Check all the data we have for your IP address [here](https://ipinfo.io/what-is-my-ip).
|
||||
|
||||
### Getting Started
|
||||
|
||||
You'll need an IPinfo API access token, which you can get by signing up for a free account at [https://ipinfo.io/signup](https://ipinfo.io/signup?ref=lib-PHP).
|
||||
|
||||
The free plan is limited to 50,000 requests per month, and doesn't include some of the data fields such as IP type and company data. To enable all the data fields and additional request volumes see [https://ipinfo.io/pricing](https://ipinfo.io/pricing?ref=lib-PHP).
|
||||
|
||||
#### Installation
|
||||
|
||||
The package works with PHP 8 and is available using [Composer](https://getcomposer.org).
|
||||
|
||||
```shell
|
||||
composer require ipinfo/ipinfo
|
||||
```
|
||||
|
||||
#### Quick Start
|
||||
|
||||
```php
|
||||
<?php
|
||||
|
||||
require_once __DIR__ . '/vendor/autoload.php';
|
||||
|
||||
use ipinfo\ipinfo\IPinfo;
|
||||
|
||||
$access_token = '123456789abc';
|
||||
$client = new IPinfo($access_token);
|
||||
$ip_address = '216.239.36.21';
|
||||
$details = $client->getDetails($ip_address);
|
||||
|
||||
$details->city; // Emeryville
|
||||
$details->loc; // 37.8342,-122.2900
|
||||
```
|
||||
|
||||
### Usage
|
||||
|
||||
The `IPinfo->getDetails()` method accepts an IP address as an optional, positional argument. If no IP address is specified, the API will return data for the IP address from which it receives the request.
|
||||
|
||||
```php
|
||||
$client = new IPinfo();
|
||||
$ip_address = '216.239.36.21';
|
||||
$details = $client->getDetails($ip_address);
|
||||
$details->city; // Emeryville
|
||||
$details->loc; // 37.8342,-122.2900
|
||||
```
|
||||
|
||||
### Authentication
|
||||
|
||||
The IPinfo library can be authenticated with your IPinfo API token, which is passed in as a positional argument. It also works without an authentication token, but in a more limited capacity.
|
||||
|
||||
```php
|
||||
$access_token = '123456789abc';
|
||||
$client = new IPinfo($access_token);
|
||||
```
|
||||
|
||||
### Details Data
|
||||
|
||||
`IPinfo->getDetails()` will return a `Details` object that contains all fields listed [IPinfo developer docs](https://ipinfo.io/developers/responses#full-response) with a few minor additions. Properties can be accessed directly.
|
||||
|
||||
```php
|
||||
$details->hostname; // cpe-104-175-221-247.socal.res.rr.com
|
||||
```
|
||||
|
||||
#### Country Name
|
||||
|
||||
`Details->country_name` will return the country name, as supplied by the `countries.json` file. See below for instructions on changing that file for use with non-English languages. `Details->country` will still return the country code.
|
||||
|
||||
```php
|
||||
$details->country; // US
|
||||
$details->country_name; // United States
|
||||
```
|
||||
|
||||
#### EU Country
|
||||
|
||||
`Details->is_eu` will return true if the country is a member of the EU, as supplied by the `eu.json` file.
|
||||
|
||||
```php
|
||||
$details->is_eu; // False
|
||||
```
|
||||
|
||||
#### Country Flag
|
||||
|
||||
`Details->country_flag` will return the emoji and Unicode representations of
|
||||
the country's flag, as supplied by the `flags.json` file.
|
||||
|
||||
```php
|
||||
$details->country_flag['emoji']; // 🇺🇸
|
||||
$details->country_flag['unicode']; // U+1F1FA U+1F1F8
|
||||
```
|
||||
|
||||
#### Country Flag URL
|
||||
|
||||
`Details->country_flag_url` will return a public link to the country's flag image as an SVG which can be used anywhere.
|
||||
|
||||
```php
|
||||
$details->country_flag_url; // https://cdn.ipinfo.io/static/images/countries-flags/US.svg
|
||||
```
|
||||
|
||||
#### Country Currency
|
||||
|
||||
`Details->country_currency` will return the code and symbol of the
|
||||
country's currency, as supplied by the `currency.json` file.
|
||||
|
||||
```php
|
||||
$details->country_currency['code']; // USD
|
||||
$details->country_currency['symbol']; // $
|
||||
```
|
||||
|
||||
#### Continent
|
||||
|
||||
`Details->continent` will return the code and name of the
|
||||
continent, as supplied by the `continent.json` file.
|
||||
|
||||
```php
|
||||
$details->continent['code']; // NA
|
||||
$details->continent['name']; // North America
|
||||
```
|
||||
|
||||
#### Longitude and Latitude
|
||||
|
||||
`Details->latitude` and `Details->longitude` will return latitude and longitude, respectively, as strings. `Details->loc` will still return a composite string of both values.
|
||||
|
||||
```php
|
||||
$details->loc; // 34.0293,-118.3570
|
||||
$details->latitude; // 34.0293
|
||||
$details->longitude; // -118.3570
|
||||
```
|
||||
|
||||
#### Accessing all properties
|
||||
|
||||
`Details->all` will return all details data as a dictionary.
|
||||
|
||||
```php
|
||||
$details->all;
|
||||
/*
|
||||
{
|
||||
'asn': { 'asn': 'AS20001',
|
||||
'domain': 'twcable.com',
|
||||
'name': 'Time Warner Cable Internet LLC',
|
||||
'route': '104.172.0.0/14',
|
||||
'type': 'isp'},
|
||||
'city': 'Los Angeles',
|
||||
'company': { 'domain': 'twcable.com',
|
||||
'name': 'Time Warner Cable Internet LLC',
|
||||
'type': 'isp'},
|
||||
'country': 'US',
|
||||
'country_name': 'United States',
|
||||
'hostname': 'cpe-104-175-221-247.socal.res.rr.com',
|
||||
'ip': '104.175.221.247',
|
||||
'loc': '34.0293,-118.3570',
|
||||
'latitude': '34.0293',
|
||||
'longitude': '-118.3570',
|
||||
'phone': '323',
|
||||
'postal': '90016',
|
||||
'region': 'California'
|
||||
}
|
||||
*/
|
||||
```
|
||||
|
||||
### Caching
|
||||
|
||||
In-memory caching of `Details` data is provided by default via the [symfony/cache](https://github.com/symfony/cache/) library. LRU (least recently used) cache-invalidation functionality has been added to the default TTL (time to live). This means that values will be cached for the specified duration; if the cache's max size is reached, cache values will be invalidated as necessary, starting with the oldest cached value.
|
||||
|
||||
#### Modifying cache options
|
||||
|
||||
Default cache TTL and maximum size can be changed by setting values in the `$settings` argument array.
|
||||
|
||||
* Default maximum cache size: 4096 (multiples of 2 are recommended to increase efficiency)
|
||||
* Default TTL: 24 hours (in seconds)
|
||||
|
||||
```php
|
||||
$access_token = '123456789abc';
|
||||
$settings = ['cache_maxsize' => 30, 'cache_ttl' => 128];
|
||||
$client = new IPinfo($access_token, $settings);
|
||||
```
|
||||
|
||||
#### Using a different cache
|
||||
|
||||
It's possible to use a custom cache by creating a child class of the [CacheInterface](https://github.com/ipinfo/php/blob/master/src/cache/Interface.php) class and passing this into the handler object with the `cache` keyword argument. FYI this is known as [the Strategy Pattern](https://sourcemaking.com/design_patterns/strategy).
|
||||
|
||||
```php
|
||||
$access_token = '123456789abc';
|
||||
$settings = ['cache' => $my_fancy_custom_cache];
|
||||
$client = new IPinfo($access_token, $settings);
|
||||
```
|
||||
|
||||
#### Disabling the cache
|
||||
|
||||
You may disable the cache by passing in a `cache_disabled` key in the settings:
|
||||
|
||||
```php
|
||||
$access_token = '123456789abc';
|
||||
$settings = ['cache_disabled' => true];
|
||||
$client = new IPinfo($access_token, $settings);
|
||||
```
|
||||
|
||||
### Overriding HTTP Client options
|
||||
|
||||
The IPinfo client constructor accepts a `timeout` key which is the request
|
||||
timeout in seconds.
|
||||
|
||||
For full flexibility, a `guzzle_opts` key is accepted which accepts an
|
||||
associative array which is described in [Guzzle Request Options](https://docs.guzzlephp.org/en/stable/request-options.html).
|
||||
Options set here will override any custom settings set by the IPinfo client
|
||||
internally in case of conflict, including headers.
|
||||
|
||||
### Batch Operations
|
||||
|
||||
Looking up a single IP at a time can be slow. It could be done concurrently from the client side, but IPinfo supports a batch endpoint to allow you to group together IPs and let us handle retrieving details for them in bulk for you.
|
||||
|
||||
```php
|
||||
$access_token = '123456789abc';
|
||||
$client = new IPinfo($access_token);
|
||||
$ips = ['1.1.1.1', '8.8.8.8', '1.2.3.4/country'];
|
||||
$results = $client->getBatchDetails($ips);
|
||||
echo $results['1.2.3.4/country']; // AU
|
||||
var_dump($results['1.1.1.1']);
|
||||
var_dump($results['8.8.8.8']);
|
||||
```
|
||||
|
||||
The input size is not limited, as the interface will chunk operations for you behind the scenes.
|
||||
|
||||
Please see [the official documentation](https://ipinfo.io/developers/batch) for more information and limitations.
|
||||
|
||||
### Internationalization
|
||||
|
||||
When looking up an IP address, the response object includes a `Details->country_name` attribute which includes the country name based on American English. It is possible to return the country name in other languages by setting the `countries_file` keyword argument when creating the `IPinfo` object.
|
||||
|
||||
The file must be a `.json` file with the following structure:
|
||||
|
||||
```JSON
|
||||
{
|
||||
"BD": "Bangladesh",
|
||||
"BE": "Belgium",
|
||||
"BF": "Burkina Faso",
|
||||
"BG": "Bulgaria"
|
||||
...
|
||||
}
|
||||
```
|
||||
|
||||
### Other Libraries
|
||||
|
||||
There are official IPinfo client libraries available for many languages including PHP, Python, Go, Java, Ruby, and many popular frameworks such as Django, Rails, and Laravel. There are also many third-party libraries and integrations available for our API.
|
||||
|
||||
### About IPinfo
|
||||
|
||||
Founded in 2013, IPinfo prides itself on being the most reliable, accurate, and in-depth source of IP address data available anywhere. We process terabytes of data to produce our custom IP geolocation, company, carrier, privacy, hosted domains and IP type data sets. Our API handles over 40 billion requests a month for 100,000 businesses and developers.
|
||||
|
||||
[](https://ipinfo.io/)
|
||||
64
dev/app-bak/Services/IPinfo/_info/composer.json
Normal file
64
dev/app-bak/Services/IPinfo/_info/composer.json
Normal file
|
|
@ -0,0 +1,64 @@
|
|||
{
|
||||
"name": "ipinfo/ipinfo",
|
||||
"type": "library",
|
||||
"description": "The official PHP library for IPinfo, the most reliable, accurate, and in-depth source of IP address data available anywhere. We process terabytes of data to produce our custom IP geolocation, company, carrier and IP type data sets. Visit our developer docs at https://ipinfo.io/developers.",
|
||||
"keywords": [
|
||||
"ipinfo"
|
||||
],
|
||||
"homepage": "https://github.com/ipinfo/php",
|
||||
"license": "Apache-2.0",
|
||||
"authors": [
|
||||
{
|
||||
"name": "James Timmins",
|
||||
"email": "jameshtimmins@gmail.com",
|
||||
"homepage": "https://github.com/jhtimmins",
|
||||
"role": "Developer"
|
||||
},
|
||||
{
|
||||
"name": "Uman Shahzad",
|
||||
"email": "uman@mslm.io",
|
||||
"homepage": "https://github.com/UmanShahzad",
|
||||
"role": "Developer"
|
||||
},
|
||||
{
|
||||
"name": "Umar Farooq",
|
||||
"email": "umar@ipinfo.io",
|
||||
"homepage": "https://github.com/rm-Umar",
|
||||
"role": "Developer"
|
||||
}
|
||||
],
|
||||
"require": {
|
||||
"php": ">=8.0",
|
||||
"ext-json": "*",
|
||||
"guzzlehttp/guzzle": "^6.3||^7.0",
|
||||
"symfony/cache": "^6.3",
|
||||
"symfony/http-foundation": "^6.2"
|
||||
},
|
||||
"require-dev": {
|
||||
"phpunit/phpunit": "^10.0.0",
|
||||
"squizlabs/php_codesniffer": "^3.5.8"
|
||||
},
|
||||
"autoload": {
|
||||
"psr-4": {
|
||||
"ipinfo\\ipinfo\\": "src"
|
||||
}
|
||||
},
|
||||
"autoload-dev": {
|
||||
"psr-4": {
|
||||
"ipinfo\\ipinfo\\": "tests"
|
||||
}
|
||||
},
|
||||
"scripts": {
|
||||
"test": "phpunit",
|
||||
"check-style": "phpcs -p --standard=PSR2 --runtime-set ignore_errors_on_exit 1 --runtime-set ignore_warnings_on_exit 1 src tests",
|
||||
"fix-style": "phpcbf -p --standard=PSR2 --runtime-set ignore_errors_on_exit 1 --runtime-set ignore_warnings_on_exit 1 src tests"
|
||||
},
|
||||
"extra": {
|
||||
"branch-alias": {
|
||||
"dev-master": "3.1.1-dev"
|
||||
}
|
||||
},
|
||||
"config": {
|
||||
"sort-packages": true
|
||||
}
|
||||
}
|
||||
31
dev/app-bak/Services/IPinfo/cache/CacheInterface.php
vendored
Normal file
31
dev/app-bak/Services/IPinfo/cache/CacheInterface.php
vendored
Normal file
|
|
@ -0,0 +1,31 @@
|
|||
<?php
|
||||
|
||||
namespace App\Services\IPinfo\cache;
|
||||
|
||||
/**
|
||||
* Interface for caches used to store IP data between requests.
|
||||
*/
|
||||
interface CacheInterface
|
||||
{
|
||||
|
||||
/**
|
||||
* Tests if the specified IP address is cached.
|
||||
* @param string $ip_address IP address to lookup.
|
||||
* @return boolean Is the IP address data in the cache.
|
||||
*/
|
||||
public function has(string $ip_address);
|
||||
|
||||
/**
|
||||
* Set the IP address key to the specified value.
|
||||
* @param string $ip_address IP address to cache data for.
|
||||
* @param mixed $value Data for specified IP address.
|
||||
*/
|
||||
public function set(string $ip_address, $value);
|
||||
|
||||
/**
|
||||
* Get data for the specified IP address.
|
||||
* @param string $ip_address IP address to lookup in cache.
|
||||
* @return mixed IP address data.
|
||||
*/
|
||||
public function get(string $ip_address);
|
||||
}
|
||||
82
dev/app-bak/Services/IPinfo/cache/DefaultCache.php
vendored
Normal file
82
dev/app-bak/Services/IPinfo/cache/DefaultCache.php
vendored
Normal file
|
|
@ -0,0 +1,82 @@
|
|||
<?php
|
||||
|
||||
namespace App\Services\IPinfo\cache;
|
||||
|
||||
use Symfony\Component\Cache\Adapter\ArrayAdapter;
|
||||
use Symfony\Contracts\Cache\ItemInterface;
|
||||
|
||||
/**
|
||||
* Default implementation of the CacheInterface. Provides in-memory caching.
|
||||
*/
|
||||
class DefaultCache implements CacheInterface
|
||||
{
|
||||
|
||||
public $maxsize;
|
||||
public $ttl;
|
||||
|
||||
private $cache;
|
||||
private $element_queue;
|
||||
|
||||
public function __construct(int $maxsize, int $ttl)
|
||||
{
|
||||
$this->cache = new ArrayAdapter();
|
||||
$this->element_queue = array();
|
||||
$this->maxsize = $maxsize;
|
||||
$this->ttl = $ttl;
|
||||
}
|
||||
|
||||
/**
|
||||
* Tests if the specified IP address is cached.
|
||||
* @param string $ip_address IP address to lookup.
|
||||
* @return boolean Is the IP address data in the cache.
|
||||
*/
|
||||
public function has(string $name): bool
|
||||
{
|
||||
return $this->cache->hasItem($name);
|
||||
}
|
||||
|
||||
/**
|
||||
* Set the IP address key to the specified value.
|
||||
* @param string $ip_address IP address to cache data for.
|
||||
* @param mixed $value Data for specified IP address.
|
||||
*/
|
||||
public function set(string $name, $value)
|
||||
{
|
||||
if (!$this->cache->hasItem($name)) {
|
||||
$this->element_queue[] = $name;
|
||||
}
|
||||
|
||||
$this->cache->get($name, function (ItemInterface $item) use ($value) {
|
||||
$item->set($value)->expiresAfter($this->ttl);
|
||||
return $item->get();
|
||||
});
|
||||
|
||||
$this->manageSize();
|
||||
}
|
||||
|
||||
/**
|
||||
* Get data for the specified IP address.
|
||||
* @param string $ip_address IP address to lookup in cache.
|
||||
* @return mixed IP address data.
|
||||
*/
|
||||
public function get(string $name)
|
||||
{
|
||||
return $this->cache->getItem($name)->get();
|
||||
}
|
||||
|
||||
/**
|
||||
* If cache maxsize has been reached, remove oldest elements until limit is reached.
|
||||
*/
|
||||
private function manageSize()
|
||||
{
|
||||
$overflow = count($this->element_queue) - $this->maxsize;
|
||||
if ($overflow > 0) {
|
||||
foreach (array_slice($this->element_queue, 0, $overflow) as $name) {
|
||||
if ($this->has($name)) {
|
||||
$this->cache->delete($name);
|
||||
}
|
||||
}
|
||||
$this->element_queue = array_slice($this->element_queue, $overflow);
|
||||
}
|
||||
}
|
||||
}
|
||||
252
dev/app-bak/Services/IPinfo/json/continent.json
Normal file
252
dev/app-bak/Services/IPinfo/json/continent.json
Normal file
|
|
@ -0,0 +1,252 @@
|
|||
{
|
||||
"BD": {"code": "AS", "name": "Asia"},
|
||||
"BE": {"code": "EU", "name": "Europe"},
|
||||
"BF": {"code": "AF", "name": "Africa"},
|
||||
"BG": {"code": "EU", "name": "Europe"},
|
||||
"BA": {"code": "EU", "name": "Europe"},
|
||||
"BB": {"code": "NA", "name": "North America"},
|
||||
"WF": {"code": "OC", "name": "Oceania"},
|
||||
"BL": {"code": "NA", "name": "North America"},
|
||||
"BM": {"code": "NA", "name": "North America"},
|
||||
"BN": {"code": "AS", "name": "Asia"},
|
||||
"BO": {"code": "SA", "name": "South America"},
|
||||
"BH": {"code": "AS", "name": "Asia"},
|
||||
"BI": {"code": "AF", "name": "Africa"},
|
||||
"BJ": {"code": "AF", "name": "Africa"},
|
||||
"BT": {"code": "AS", "name": "Asia"},
|
||||
"JM": {"code": "NA", "name": "North America"},
|
||||
"BV": {"code": "AN", "name": "Antarctica"},
|
||||
"BW": {"code": "AF", "name": "Africa"},
|
||||
"WS": {"code": "OC", "name": "Oceania"},
|
||||
"BQ": {"code": "NA", "name": "North America"},
|
||||
"BR": {"code": "SA", "name": "South America"},
|
||||
"BS": {"code": "NA", "name": "North America"},
|
||||
"JE": {"code": "EU", "name": "Europe"},
|
||||
"BY": {"code": "EU", "name": "Europe"},
|
||||
"BZ": {"code": "NA", "name": "North America"},
|
||||
"RU": {"code": "EU", "name": "Europe"},
|
||||
"RW": {"code": "AF", "name": "Africa"},
|
||||
"RS": {"code": "EU", "name": "Europe"},
|
||||
"TL": {"code": "OC", "name": "Oceania"},
|
||||
"RE": {"code": "AF", "name": "Africa"},
|
||||
"TM": {"code": "AS", "name": "Asia"},
|
||||
"TJ": {"code": "AS", "name": "Asia"},
|
||||
"RO": {"code": "EU", "name": "Europe"},
|
||||
"TK": {"code": "OC", "name": "Oceania"},
|
||||
"GW": {"code": "AF", "name": "Africa"},
|
||||
"GU": {"code": "OC", "name": "Oceania"},
|
||||
"GT": {"code": "NA", "name": "North America"},
|
||||
"GS": {"code": "AN", "name": "Antarctica"},
|
||||
"GR": {"code": "EU", "name": "Europe"},
|
||||
"GQ": {"code": "AF", "name": "Africa"},
|
||||
"GP": {"code": "NA", "name": "North America"},
|
||||
"JP": {"code": "AS", "name": "Asia"},
|
||||
"GY": {"code": "SA", "name": "South America"},
|
||||
"GG": {"code": "EU", "name": "Europe"},
|
||||
"GF": {"code": "SA", "name": "South America"},
|
||||
"GE": {"code": "AS", "name": "Asia"},
|
||||
"GD": {"code": "NA", "name": "North America"},
|
||||
"GB": {"code": "EU", "name": "Europe"},
|
||||
"GA": {"code": "AF", "name": "Africa"},
|
||||
"SV": {"code": "NA", "name": "North America"},
|
||||
"GN": {"code": "AF", "name": "Africa"},
|
||||
"GM": {"code": "AF", "name": "Africa"},
|
||||
"GL": {"code": "NA", "name": "North America"},
|
||||
"GI": {"code": "EU", "name": "Europe"},
|
||||
"GH": {"code": "AF", "name": "Africa"},
|
||||
"OM": {"code": "AS", "name": "Asia"},
|
||||
"TN": {"code": "AF", "name": "Africa"},
|
||||
"JO": {"code": "AS", "name": "Asia"},
|
||||
"HR": {"code": "EU", "name": "Europe"},
|
||||
"HT": {"code": "NA", "name": "North America"},
|
||||
"HU": {"code": "EU", "name": "Europe"},
|
||||
"HK": {"code": "AS", "name": "Asia"},
|
||||
"HN": {"code": "NA", "name": "North America"},
|
||||
"HM": {"code": "AN", "name": "Antarctica"},
|
||||
"VE": {"code": "SA", "name": "South America"},
|
||||
"PR": {"code": "NA", "name": "North America"},
|
||||
"PS": {"code": "AS", "name": "Asia"},
|
||||
"PW": {"code": "OC", "name": "Oceania"},
|
||||
"PT": {"code": "EU", "name": "Europe"},
|
||||
"SJ": {"code": "EU", "name": "Europe"},
|
||||
"PY": {"code": "SA", "name": "South America"},
|
||||
"IQ": {"code": "AS", "name": "Asia"},
|
||||
"PA": {"code": "NA", "name": "North America"},
|
||||
"PF": {"code": "OC", "name": "Oceania"},
|
||||
"PG": {"code": "OC", "name": "Oceania"},
|
||||
"PE": {"code": "SA", "name": "South America"},
|
||||
"PK": {"code": "AS", "name": "Asia"},
|
||||
"PH": {"code": "AS", "name": "Asia"},
|
||||
"PN": {"code": "OC", "name": "Oceania"},
|
||||
"PL": {"code": "EU", "name": "Europe"},
|
||||
"PM": {"code": "NA", "name": "North America"},
|
||||
"ZM": {"code": "AF", "name": "Africa"},
|
||||
"EH": {"code": "AF", "name": "Africa"},
|
||||
"EE": {"code": "EU", "name": "Europe"},
|
||||
"EG": {"code": "AF", "name": "Africa"},
|
||||
"ZA": {"code": "AF", "name": "Africa"},
|
||||
"EC": {"code": "SA", "name": "South America"},
|
||||
"IT": {"code": "EU", "name": "Europe"},
|
||||
"VN": {"code": "AS", "name": "Asia"},
|
||||
"SB": {"code": "OC", "name": "Oceania"},
|
||||
"ET": {"code": "AF", "name": "Africa"},
|
||||
"SO": {"code": "AF", "name": "Africa"},
|
||||
"ZW": {"code": "AF", "name": "Africa"},
|
||||
"SA": {"code": "AS", "name": "Asia"},
|
||||
"ES": {"code": "EU", "name": "Europe"},
|
||||
"ER": {"code": "AF", "name": "Africa"},
|
||||
"ME": {"code": "EU", "name": "Europe"},
|
||||
"MD": {"code": "EU", "name": "Europe"},
|
||||
"MG": {"code": "AF", "name": "Africa"},
|
||||
"MF": {"code": "NA", "name": "North America"},
|
||||
"MA": {"code": "AF", "name": "Africa"},
|
||||
"MC": {"code": "EU", "name": "Europe"},
|
||||
"UZ": {"code": "AS", "name": "Asia"},
|
||||
"MM": {"code": "AS", "name": "Asia"},
|
||||
"ML": {"code": "AF", "name": "Africa"},
|
||||
"MO": {"code": "AS", "name": "Asia"},
|
||||
"MN": {"code": "AS", "name": "Asia"},
|
||||
"MH": {"code": "OC", "name": "Oceania"},
|
||||
"MK": {"code": "EU", "name": "Europe"},
|
||||
"MU": {"code": "AF", "name": "Africa"},
|
||||
"MT": {"code": "EU", "name": "Europe"},
|
||||
"MW": {"code": "AF", "name": "Africa"},
|
||||
"MV": {"code": "AS", "name": "Asia"},
|
||||
"MQ": {"code": "NA", "name": "North America"},
|
||||
"MP": {"code": "OC", "name": "Oceania"},
|
||||
"MS": {"code": "NA", "name": "North America"},
|
||||
"MR": {"code": "AF", "name": "Africa"},
|
||||
"IM": {"code": "EU", "name": "Europe"},
|
||||
"UG": {"code": "AF", "name": "Africa"},
|
||||
"TZ": {"code": "AF", "name": "Africa"},
|
||||
"MY": {"code": "AS", "name": "Asia"},
|
||||
"MX": {"code": "NA", "name": "North America"},
|
||||
"IL": {"code": "AS", "name": "Asia"},
|
||||
"FR": {"code": "EU", "name": "Europe"},
|
||||
"IO": {"code": "AS", "name": "Asia"},
|
||||
"SH": {"code": "AF", "name": "Africa"},
|
||||
"FI": {"code": "EU", "name": "Europe"},
|
||||
"FJ": {"code": "OC", "name": "Oceania"},
|
||||
"FK": {"code": "SA", "name": "South America"},
|
||||
"FM": {"code": "OC", "name": "Oceania"},
|
||||
"FO": {"code": "EU", "name": "Europe"},
|
||||
"NI": {"code": "NA", "name": "North America"},
|
||||
"NL": {"code": "EU", "name": "Europe"},
|
||||
"NO": {"code": "EU", "name": "Europe"},
|
||||
"NA": {"code": "AF", "name": "Africa"},
|
||||
"VU": {"code": "OC", "name": "Oceania"},
|
||||
"NC": {"code": "OC", "name": "Oceania"},
|
||||
"NE": {"code": "AF", "name": "Africa"},
|
||||
"NF": {"code": "OC", "name": "Oceania"},
|
||||
"NG": {"code": "AF", "name": "Africa"},
|
||||
"NZ": {"code": "OC", "name": "Oceania"},
|
||||
"NP": {"code": "AS", "name": "Asia"},
|
||||
"NR": {"code": "OC", "name": "Oceania"},
|
||||
"NU": {"code": "OC", "name": "Oceania"},
|
||||
"CK": {"code": "OC", "name": "Oceania"},
|
||||
"XK": {"code": "EU", "name": "Europe"},
|
||||
"CI": {"code": "AF", "name": "Africa"},
|
||||
"CH": {"code": "EU", "name": "Europe"},
|
||||
"CO": {"code": "SA", "name": "South America"},
|
||||
"CN": {"code": "AS", "name": "Asia"},
|
||||
"CM": {"code": "AF", "name": "Africa"},
|
||||
"CL": {"code": "SA", "name": "South America"},
|
||||
"CC": {"code": "AS", "name": "Asia"},
|
||||
"CA": {"code": "NA", "name": "North America"},
|
||||
"CG": {"code": "AF", "name": "Africa"},
|
||||
"CF": {"code": "AF", "name": "Africa"},
|
||||
"CD": {"code": "AF", "name": "Africa"},
|
||||
"CZ": {"code": "EU", "name": "Europe"},
|
||||
"CY": {"code": "EU", "name": "Europe"},
|
||||
"CX": {"code": "AS", "name": "Asia"},
|
||||
"CR": {"code": "NA", "name": "North America"},
|
||||
"CW": {"code": "NA", "name": "North America"},
|
||||
"CV": {"code": "AF", "name": "Africa"},
|
||||
"CU": {"code": "NA", "name": "North America"},
|
||||
"SZ": {"code": "AF", "name": "Africa"},
|
||||
"SY": {"code": "AS", "name": "Asia"},
|
||||
"SX": {"code": "NA", "name": "North America"},
|
||||
"KG": {"code": "AS", "name": "Asia"},
|
||||
"KE": {"code": "AF", "name": "Africa"},
|
||||
"SS": {"code": "AF", "name": "Africa"},
|
||||
"SR": {"code": "SA", "name": "South America"},
|
||||
"KI": {"code": "OC", "name": "Oceania"},
|
||||
"KH": {"code": "AS", "name": "Asia"},
|
||||
"KN": {"code": "NA", "name": "North America"},
|
||||
"KM": {"code": "AF", "name": "Africa"},
|
||||
"ST": {"code": "AF", "name": "Africa"},
|
||||
"SK": {"code": "EU", "name": "Europe"},
|
||||
"KR": {"code": "AS", "name": "Asia"},
|
||||
"SI": {"code": "EU", "name": "Europe"},
|
||||
"KP": {"code": "AS", "name": "Asia"},
|
||||
"KW": {"code": "AS", "name": "Asia"},
|
||||
"SN": {"code": "AF", "name": "Africa"},
|
||||
"SM": {"code": "EU", "name": "Europe"},
|
||||
"SL": {"code": "AF", "name": "Africa"},
|
||||
"SC": {"code": "AF", "name": "Africa"},
|
||||
"KZ": {"code": "AS", "name": "Asia"},
|
||||
"KY": {"code": "NA", "name": "North America"},
|
||||
"SG": {"code": "AS", "name": "Asia"},
|
||||
"SE": {"code": "EU", "name": "Europe"},
|
||||
"SD": {"code": "AF", "name": "Africa"},
|
||||
"DO": {"code": "NA", "name": "North America"},
|
||||
"DM": {"code": "NA", "name": "North America"},
|
||||
"DJ": {"code": "AF", "name": "Africa"},
|
||||
"DK": {"code": "EU", "name": "Europe"},
|
||||
"VG": {"code": "NA", "name": "North America"},
|
||||
"DE": {"code": "EU", "name": "Europe"},
|
||||
"YE": {"code": "AS", "name": "Asia"},
|
||||
"DZ": {"code": "AF", "name": "Africa"},
|
||||
"US": {"code": "NA", "name": "North America"},
|
||||
"UY": {"code": "SA", "name": "South America"},
|
||||
"YT": {"code": "AF", "name": "Africa"},
|
||||
"UM": {"code": "OC", "name": "Oceania"},
|
||||
"LB": {"code": "AS", "name": "Asia"},
|
||||
"LC": {"code": "NA", "name": "North America"},
|
||||
"LA": {"code": "AS", "name": "Asia"},
|
||||
"TV": {"code": "OC", "name": "Oceania"},
|
||||
"TW": {"code": "AS", "name": "Asia"},
|
||||
"TT": {"code": "NA", "name": "North America"},
|
||||
"TR": {"code": "AS", "name": "Asia"},
|
||||
"LK": {"code": "AS", "name": "Asia"},
|
||||
"LI": {"code": "EU", "name": "Europe"},
|
||||
"LV": {"code": "EU", "name": "Europe"},
|
||||
"TO": {"code": "OC", "name": "Oceania"},
|
||||
"LT": {"code": "EU", "name": "Europe"},
|
||||
"LU": {"code": "EU", "name": "Europe"},
|
||||
"LR": {"code": "AF", "name": "Africa"},
|
||||
"LS": {"code": "AF", "name": "Africa"},
|
||||
"TH": {"code": "AS", "name": "Asia"},
|
||||
"TF": {"code": "AN", "name": "Antarctica"},
|
||||
"TG": {"code": "AF", "name": "Africa"},
|
||||
"TD": {"code": "AF", "name": "Africa"},
|
||||
"TC": {"code": "NA", "name": "North America"},
|
||||
"LY": {"code": "AF", "name": "Africa"},
|
||||
"VA": {"code": "EU", "name": "Europe"},
|
||||
"VC": {"code": "NA", "name": "North America"},
|
||||
"AE": {"code": "AS", "name": "Asia"},
|
||||
"AD": {"code": "EU", "name": "Europe"},
|
||||
"AG": {"code": "NA", "name": "North America"},
|
||||
"AF": {"code": "AS", "name": "Asia"},
|
||||
"AI": {"code": "NA", "name": "North America"},
|
||||
"VI": {"code": "NA", "name": "North America"},
|
||||
"IS": {"code": "EU", "name": "Europe"},
|
||||
"IR": {"code": "AS", "name": "Asia"},
|
||||
"AM": {"code": "AS", "name": "Asia"},
|
||||
"AL": {"code": "EU", "name": "Europe"},
|
||||
"AO": {"code": "AF", "name": "Africa"},
|
||||
"AQ": {"code": "AN", "name": "Antarctica"},
|
||||
"AS": {"code": "OC", "name": "Oceania"},
|
||||
"AR": {"code": "SA", "name": "South America"},
|
||||
"AU": {"code": "OC", "name": "Oceania"},
|
||||
"AT": {"code": "EU", "name": "Europe"},
|
||||
"AW": {"code": "NA", "name": "North America"},
|
||||
"IN": {"code": "AS", "name": "Asia"},
|
||||
"AX": {"code": "EU", "name": "Europe"},
|
||||
"AZ": {"code": "AS", "name": "Asia"},
|
||||
"IE": {"code": "EU", "name": "Europe"},
|
||||
"ID": {"code": "AS", "name": "Asia"},
|
||||
"UA": {"code": "EU", "name": "Europe"},
|
||||
"QA": {"code": "AS", "name": "Asia"},
|
||||
"MZ": {"code": "AF", "name": "Africa"}
|
||||
}
|
||||
1
dev/app-bak/Services/IPinfo/json/countries.json
Normal file
1
dev/app-bak/Services/IPinfo/json/countries.json
Normal file
|
|
@ -0,0 +1 @@
|
|||
{"BD": "Bangladesh", "BE": "Belgium", "BF": "Burkina Faso", "BG": "Bulgaria", "BA": "Bosnia and Herzegovina", "BB": "Barbados", "WF": "Wallis and Futuna", "BL": "Saint Barthelemy", "BM": "Bermuda", "BN": "Brunei", "BO": "Bolivia", "BH": "Bahrain", "BI": "Burundi", "BJ": "Benin", "BT": "Bhutan", "JM": "Jamaica", "BV": "Bouvet Island", "BW": "Botswana", "WS": "Samoa", "BQ": "Bonaire, Saint Eustatius and Saba ", "BR": "Brazil", "BS": "Bahamas", "JE": "Jersey", "BY": "Belarus", "BZ": "Belize", "RU": "Russia", "RW": "Rwanda", "RS": "Serbia", "TL": "East Timor", "RE": "Reunion", "TM": "Turkmenistan", "TJ": "Tajikistan", "RO": "Romania", "TK": "Tokelau", "GW": "Guinea-Bissau", "GU": "Guam", "GT": "Guatemala", "GS": "South Georgia and the South Sandwich Islands", "GR": "Greece", "GQ": "Equatorial Guinea", "GP": "Guadeloupe", "JP": "Japan", "GY": "Guyana", "GG": "Guernsey", "GF": "French Guiana", "GE": "Georgia", "GD": "Grenada", "GB": "United Kingdom", "GA": "Gabon", "SV": "El Salvador", "GN": "Guinea", "GM": "Gambia", "GL": "Greenland", "GI": "Gibraltar", "GH": "Ghana", "OM": "Oman", "TN": "Tunisia", "JO": "Jordan", "HR": "Croatia", "HT": "Haiti", "HU": "Hungary", "HK": "Hong Kong", "HN": "Honduras", "HM": "Heard Island and McDonald Islands", "VE": "Venezuela", "PR": "Puerto Rico", "PS": "Palestinian Territory", "PW": "Palau", "PT": "Portugal", "SJ": "Svalbard and Jan Mayen", "PY": "Paraguay", "IQ": "Iraq", "PA": "Panama", "PF": "French Polynesia", "PG": "Papua New Guinea", "PE": "Peru", "PK": "Pakistan", "PH": "Philippines", "PN": "Pitcairn", "PL": "Poland", "PM": "Saint Pierre and Miquelon", "ZM": "Zambia", "EH": "Western Sahara", "EE": "Estonia", "EG": "Egypt", "ZA": "South Africa", "EC": "Ecuador", "IT": "Italy", "VN": "Vietnam", "SB": "Solomon Islands", "ET": "Ethiopia", "SO": "Somalia", "ZW": "Zimbabwe", "SA": "Saudi Arabia", "ES": "Spain", "ER": "Eritrea", "ME": "Montenegro", "MD": "Moldova", "MG": "Madagascar", "MF": "Saint Martin", "MA": "Morocco", "MC": "Monaco", "UZ": "Uzbekistan", "MM": "Myanmar", "ML": "Mali", "MO": "Macao", "MN": "Mongolia", "MH": "Marshall Islands", "MK": "Macedonia", "MU": "Mauritius", "MT": "Malta", "MW": "Malawi", "MV": "Maldives", "MQ": "Martinique", "MP": "Northern Mariana Islands", "MS": "Montserrat", "MR": "Mauritania", "IM": "Isle of Man", "UG": "Uganda", "TZ": "Tanzania", "MY": "Malaysia", "MX": "Mexico", "IL": "Israel", "FR": "France", "IO": "British Indian Ocean Territory", "SH": "Saint Helena", "FI": "Finland", "FJ": "Fiji", "FK": "Falkland Islands", "FM": "Micronesia", "FO": "Faroe Islands", "NI": "Nicaragua", "NL": "Netherlands", "NO": "Norway", "NA": "Namibia", "VU": "Vanuatu", "NC": "New Caledonia", "NE": "Niger", "NF": "Norfolk Island", "NG": "Nigeria", "NZ": "New Zealand", "NP": "Nepal", "NR": "Nauru", "NU": "Niue", "CK": "Cook Islands", "XK": "Kosovo", "CI": "Ivory Coast", "CH": "Switzerland", "CO": "Colombia", "CN": "China", "CM": "Cameroon", "CL": "Chile", "CC": "Cocos Islands", "CA": "Canada", "CG": "Republic of the Congo", "CF": "Central African Republic", "CD": "Democratic Republic of the Congo", "CZ": "Czech Republic", "CY": "Cyprus", "CX": "Christmas Island", "CR": "Costa Rica", "CW": "Curacao", "CV": "Cape Verde", "CU": "Cuba", "SZ": "Swaziland", "SY": "Syria", "SX": "Sint Maarten", "KG": "Kyrgyzstan", "KE": "Kenya", "SS": "South Sudan", "SR": "Suriname", "KI": "Kiribati", "KH": "Cambodia", "KN": "Saint Kitts and Nevis", "KM": "Comoros", "ST": "Sao Tome and Principe", "SK": "Slovakia", "KR": "South Korea", "SI": "Slovenia", "KP": "North Korea", "KW": "Kuwait", "SN": "Senegal", "SM": "San Marino", "SL": "Sierra Leone", "SC": "Seychelles", "KZ": "Kazakhstan", "KY": "Cayman Islands", "SG": "Singapore", "SE": "Sweden", "SD": "Sudan", "DO": "Dominican Republic", "DM": "Dominica", "DJ": "Djibouti", "DK": "Denmark", "VG": "British Virgin Islands", "DE": "Germany", "YE": "Yemen", "DZ": "Algeria", "US": "United States", "UY": "Uruguay", "YT": "Mayotte", "UM": "United States Minor Outlying Islands", "LB": "Lebanon", "LC": "Saint Lucia", "LA": "Laos", "TV": "Tuvalu", "TW": "Taiwan", "TT": "Trinidad and Tobago", "TR": "Turkey", "LK": "Sri Lanka", "LI": "Liechtenstein", "LV": "Latvia", "TO": "Tonga", "LT": "Lithuania", "LU": "Luxembourg", "LR": "Liberia", "LS": "Lesotho", "TH": "Thailand", "TF": "French Southern Territories", "TG": "Togo", "TD": "Chad", "TC": "Turks and Caicos Islands", "LY": "Libya", "VA": "Vatican", "VC": "Saint Vincent and the Grenadines", "AE": "United Arab Emirates", "AD": "Andorra", "AG": "Antigua and Barbuda", "AF": "Afghanistan", "AI": "Anguilla", "VI": "U.S. Virgin Islands", "IS": "Iceland", "IR": "Iran", "AM": "Armenia", "AL": "Albania", "AO": "Angola", "AQ": "Antarctica", "AS": "American Samoa", "AR": "Argentina", "AU": "Australia", "AT": "Austria", "AW": "Aruba", "IN": "India", "AX": "Aland Islands", "AZ": "Azerbaijan", "IE": "Ireland", "ID": "Indonesia", "UA": "Ukraine", "QA": "Qatar", "MZ": "Mozambique"}
|
||||
253
dev/app-bak/Services/IPinfo/json/currency.json
Normal file
253
dev/app-bak/Services/IPinfo/json/currency.json
Normal file
|
|
@ -0,0 +1,253 @@
|
|||
{
|
||||
"AD" : { "code": "EUR" ,"symbol": "€"},
|
||||
"AE" : { "code": "AED" ,"symbol": "د.إ"},
|
||||
"AF" : { "code": "AFN" ,"symbol": "؋"},
|
||||
"AG" : { "code": "XCD" ,"symbol": "$"},
|
||||
"AI" : { "code": "XCD" ,"symbol": "$"},
|
||||
"AL" : { "code": "ALL" ,"symbol": "L"},
|
||||
"AM" : { "code": "AMD" ,"symbol": "֏"},
|
||||
"AO" : { "code": "AOA" ,"symbol": "Kz"},
|
||||
"AQ" : { "code": "" ,"symbol": "$"},
|
||||
"AR" : { "code": "ARS" ,"symbol": "$"},
|
||||
"AS" : { "code": "USD" ,"symbol": "$"},
|
||||
"AT" : { "code": "EUR" ,"symbol": "€"},
|
||||
"AU" : { "code": "AUD" ,"symbol": "$"},
|
||||
"AW" : { "code": "AWG" ,"symbol": "ƒ"},
|
||||
"AX" : { "code": "EUR" ,"symbol": "€"},
|
||||
"AZ" : { "code": "AZN" ,"symbol": "₼"},
|
||||
"BA" : { "code": "BAM" ,"symbol": "KM"},
|
||||
"BB" : { "code": "BBD" ,"symbol": "$"},
|
||||
"BD" : { "code": "BDT" ,"symbol": "৳"},
|
||||
"BE" : { "code": "EUR" ,"symbol": "€"},
|
||||
"BF" : { "code": "XOF" ,"symbol": "CFA"},
|
||||
"BG" : { "code": "BGN" ,"symbol": "лв"},
|
||||
"BH" : { "code": "BHD" ,"symbol": ".د.ب"},
|
||||
"BI" : { "code": "BIF" ,"symbol": "FBu"},
|
||||
"BJ" : { "code": "XOF" ,"symbol": "CFA"},
|
||||
"BL" : { "code": "EUR" ,"symbol": "€"},
|
||||
"BM" : { "code": "BMD" ,"symbol": "$"},
|
||||
"BN" : { "code": "BND" ,"symbol": "$"},
|
||||
"BO" : { "code": "BOB" ,"symbol": "$b"},
|
||||
"BQ" : { "code": "USD" ,"symbol": "$"},
|
||||
"BR" : { "code": "BRL" ,"symbol": "R$"},
|
||||
"BS" : { "code": "BSD" ,"symbol": "$"},
|
||||
"BT" : { "code": "BTN" ,"symbol": "Nu."},
|
||||
"BV" : { "code": "NOK" ,"symbol": "kr"},
|
||||
"BW" : { "code": "BWP" ,"symbol": "P"},
|
||||
"BY" : { "code": "BYR" ,"symbol": "Br"},
|
||||
"BZ" : { "code": "BZD" ,"symbol": "BZ$"},
|
||||
"CA" : { "code": "CAD" ,"symbol": "$"},
|
||||
"CC" : { "code": "AUD" ,"symbol": "$"},
|
||||
"CD" : { "code": "CDF" ,"symbol": "FC"},
|
||||
"CF" : { "code": "XAF" ,"symbol": "FCFA"},
|
||||
"CG" : { "code": "XAF" ,"symbol": "FCFA"},
|
||||
"CH" : { "code": "CHF" ,"symbol": "CHF"},
|
||||
"CI" : { "code": "XOF" ,"symbol": "CFA"},
|
||||
"CK" : { "code": "NZD" ,"symbol": "$"},
|
||||
"CL" : { "code": "CLP" ,"symbol": "$"},
|
||||
"CM" : { "code": "XAF" ,"symbol": "FCFA"},
|
||||
"CN" : { "code": "CNY" ,"symbol": "¥"},
|
||||
"CO" : { "code": "COP" ,"symbol": "$"},
|
||||
"CR" : { "code": "CRC" ,"symbol": "₡"},
|
||||
"CU" : { "code": "CUP" ,"symbol": "₱"},
|
||||
"CV" : { "code": "CVE" ,"symbol": "$"},
|
||||
"CW" : { "code": "ANG" ,"symbol": "ƒ"},
|
||||
"CX" : { "code": "AUD" ,"symbol": "$"},
|
||||
"CY" : { "code": "EUR" ,"symbol": "€"},
|
||||
"CZ" : { "code": "CZK" ,"symbol": "Kč"},
|
||||
"DE" : { "code": "EUR" ,"symbol": "€"},
|
||||
"DJ" : { "code": "DJF" ,"symbol": "Fdj"},
|
||||
"DK" : { "code": "DKK" ,"symbol": "kr"},
|
||||
"DM" : { "code": "XCD" ,"symbol": "$"},
|
||||
"DO" : { "code": "DOP" ,"symbol": "RD$"},
|
||||
"DZ" : { "code": "DZD" ,"symbol": "دج"},
|
||||
"EC" : { "code": "USD" ,"symbol": "$"},
|
||||
"EE" : { "code": "EUR" ,"symbol": "€"},
|
||||
"EG" : { "code": "EGP" ,"symbol": "£"},
|
||||
"EH" : { "code": "MAD" ,"symbol": "MAD"},
|
||||
"ER" : { "code": "ERN" ,"symbol": "Nfk"},
|
||||
"ES" : { "code": "EUR" ,"symbol": "€"},
|
||||
"ET" : { "code": "ETB" ,"symbol": "Br"},
|
||||
"FI" : { "code": "EUR" ,"symbol": "€"},
|
||||
"FJ" : { "code": "FJD" ,"symbol": "$"},
|
||||
"FK" : { "code": "FKP" ,"symbol": "£"},
|
||||
"FM" : { "code": "USD" ,"symbol": "$"},
|
||||
"FO" : { "code": "DKK" ,"symbol": "kr"},
|
||||
"FR" : { "code": "EUR" ,"symbol": "€"},
|
||||
"GA" : { "code": "XAF" ,"symbol": "FCFA"},
|
||||
"GB" : { "code": "GBP" ,"symbol": "£"},
|
||||
"GD" : { "code": "XCD" ,"symbol": "$"},
|
||||
"GE" : { "code": "GEL" ,"symbol": "ლ"},
|
||||
"GF" : { "code": "EUR" ,"symbol": "€"},
|
||||
"GG" : { "code": "GBP" ,"symbol": "£"},
|
||||
"GH" : { "code": "GHS" ,"symbol": "GH₵"},
|
||||
"GI" : { "code": "GIP" ,"symbol": "£"},
|
||||
"GL" : { "code": "DKK" ,"symbol": "kr"},
|
||||
"GM" : { "code": "GMD" ,"symbol": "D"},
|
||||
"GN" : { "code": "GNF" ,"symbol": "FG"},
|
||||
"GP" : { "code": "EUR" ,"symbol": "€"},
|
||||
"GQ" : { "code": "XAF" ,"symbol": "FCFA"},
|
||||
"GR" : { "code": "EUR" ,"symbol": "€"},
|
||||
"GS" : { "code": "GBP" ,"symbol": "£"},
|
||||
"GT" : { "code": "GTQ" ,"symbol": "Q"},
|
||||
"GU" : { "code": "USD" ,"symbol": "$"},
|
||||
"GW" : { "code": "XOF" ,"symbol": "CFA"},
|
||||
"GY" : { "code": "GYD" ,"symbol": "$"},
|
||||
"HK" : { "code": "HKD" ,"symbol": "$"},
|
||||
"HM" : { "code": "AUD" ,"symbol": "$"},
|
||||
"HN" : { "code": "HNL" ,"symbol": "L"},
|
||||
"HR" : { "code": "HRK" ,"symbol": "kn"},
|
||||
"HT" : { "code": "HTG" ,"symbol": "G"},
|
||||
"HU" : { "code": "HUF" ,"symbol": "Ft"},
|
||||
"ID" : { "code": "IDR" ,"symbol": "Rp"},
|
||||
"IE" : { "code": "EUR" ,"symbol": "€"},
|
||||
"IL" : { "code": "ILS" ,"symbol": "₪"},
|
||||
"IM" : { "code": "GBP" ,"symbol": "£"},
|
||||
"IN" : { "code": "INR" ,"symbol": "₹"},
|
||||
"IO" : { "code": "USD" ,"symbol": "$"},
|
||||
"IQ" : { "code": "IQD" ,"symbol": "ع.د"},
|
||||
"IR" : { "code": "IRR" ,"symbol": "﷼"},
|
||||
"IS" : { "code": "ISK" ,"symbol": "kr"},
|
||||
"IT" : { "code": "EUR" ,"symbol": "€"},
|
||||
"JE" : { "code": "GBP" ,"symbol": "£"},
|
||||
"JM" : { "code": "JMD" ,"symbol": "J$"},
|
||||
"JO" : { "code": "JOD" ,"symbol": "JD"},
|
||||
"JP" : { "code": "JPY" ,"symbol": "¥"},
|
||||
"KE" : { "code": "KES" ,"symbol": "KSh"},
|
||||
"KG" : { "code": "KGS" ,"symbol": "лв"},
|
||||
"KH" : { "code": "KHR" ,"symbol": "៛"},
|
||||
"KI" : { "code": "AUD" ,"symbol": "$"},
|
||||
"KM" : { "code": "KMF" ,"symbol": "CF"},
|
||||
"KN" : { "code": "XCD" ,"symbol": "$"},
|
||||
"KP" : { "code": "KPW" ,"symbol": "₩"},
|
||||
"KR" : { "code": "KRW" ,"symbol": "₩"},
|
||||
"KW" : { "code": "KWD" ,"symbol": "KD"},
|
||||
"KY" : { "code": "KYD" ,"symbol": "$"},
|
||||
"KZ" : { "code": "KZT" ,"symbol": "₸"},
|
||||
"LA" : { "code": "LAK" ,"symbol": "₭"},
|
||||
"LB" : { "code": "LBP" ,"symbol": "£"},
|
||||
"LC" : { "code": "XCD" ,"symbol": "$"},
|
||||
"LI" : { "code": "CHF" ,"symbol": "CHF"},
|
||||
"LK" : { "code": "LKR" ,"symbol": "₨"},
|
||||
"LR" : { "code": "LRD" ,"symbol": "$"},
|
||||
"LS" : { "code": "LSL" ,"symbol": "M"},
|
||||
"LT" : { "code": "LTL" ,"symbol": "Lt"},
|
||||
"LU" : { "code": "EUR" ,"symbol": "€"},
|
||||
"LV" : { "code": "EUR" ,"symbol": "€"},
|
||||
"LY" : { "code": "LYD" ,"symbol": "LD"},
|
||||
"MA" : { "code": "MAD" ,"symbol": "MAD"},
|
||||
"MC" : { "code": "EUR" ,"symbol": "€"},
|
||||
"MD" : { "code": "MDL" ,"symbol": "lei"},
|
||||
"ME" : { "code": "EUR" ,"symbol": "€"},
|
||||
"MF" : { "code": "EUR" ,"symbol": "€"},
|
||||
"MG" : { "code": "MGA" ,"symbol": "Ar"},
|
||||
"MH" : { "code": "USD" ,"symbol": "$"},
|
||||
"MK" : { "code": "MKD" ,"symbol": "ден"},
|
||||
"ML" : { "code": "XOF" ,"symbol": "CFA"},
|
||||
"MM" : { "code": "MMK" ,"symbol": "K"},
|
||||
"MN" : { "code": "MNT" ,"symbol": "₮"},
|
||||
"MO" : { "code": "MOP" ,"symbol": "MOP$"},
|
||||
"MP" : { "code": "USD" ,"symbol": "$"},
|
||||
"MQ" : { "code": "EUR" ,"symbol": "€"},
|
||||
"MR" : { "code": "MRO" ,"symbol": "UM"},
|
||||
"MS" : { "code": "XCD" ,"symbol": "$"},
|
||||
"MT" : { "code": "EUR" ,"symbol": "€"},
|
||||
"MU" : { "code": "MUR" ,"symbol": "₨"},
|
||||
"MV" : { "code": "MVR" ,"symbol": "Rf"},
|
||||
"MW" : { "code": "MWK" ,"symbol": "MK"},
|
||||
"MX" : { "code": "MXN" ,"symbol": "$"},
|
||||
"MY" : { "code": "MYR" ,"symbol": "RM"},
|
||||
"MZ" : { "code": "MZN" ,"symbol": "MT"},
|
||||
"NA" : { "code": "NAD" ,"symbol": "$"},
|
||||
"NC" : { "code": "XPF" ,"symbol": "₣"},
|
||||
"NE" : { "code": "XOF" ,"symbol": "CFA"},
|
||||
"NF" : { "code": "AUD" ,"symbol": "$"},
|
||||
"NG" : { "code": "NGN" ,"symbol": "₦"},
|
||||
"NI" : { "code": "NIO" ,"symbol": "C$"},
|
||||
"NL" : { "code": "EUR" ,"symbol": "€"},
|
||||
"NO" : { "code": "NOK" ,"symbol": "kr"},
|
||||
"NP" : { "code": "NPR" ,"symbol": "₨"},
|
||||
"NR" : { "code": "AUD" ,"symbol": "$"},
|
||||
"NU" : { "code": "NZD" ,"symbol": "$"},
|
||||
"NZ" : { "code": "NZD" ,"symbol": "$"},
|
||||
"OM" : { "code": "OMR" ,"symbol": "﷼"},
|
||||
"PA" : { "code": "PAB" ,"symbol": "B/."},
|
||||
"PE" : { "code": "PEN" ,"symbol": "S/."},
|
||||
"PF" : { "code": "XPF" ,"symbol": "₣"},
|
||||
"PG" : { "code": "PGK" ,"symbol": "K"},
|
||||
"PH" : { "code": "PHP" ,"symbol": "₱"},
|
||||
"PK" : { "code": "PKR" ,"symbol": "₨"},
|
||||
"PL" : { "code": "PLN" ,"symbol": "zł"},
|
||||
"PM" : { "code": "EUR" ,"symbol": "€"},
|
||||
"PN" : { "code": "NZD" ,"symbol": "$"},
|
||||
"PR" : { "code": "USD" ,"symbol": "$"},
|
||||
"PS" : { "code": "ILS" ,"symbol": "₪"},
|
||||
"PT" : { "code": "EUR" ,"symbol": "€"},
|
||||
"PW" : { "code": "USD" ,"symbol": "$"},
|
||||
"PY" : { "code": "PYG" ,"symbol": "Gs"},
|
||||
"QA" : { "code": "QAR" ,"symbol": "﷼"},
|
||||
"RE" : { "code": "EUR" ,"symbol": "€"},
|
||||
"RO" : { "code": "RON" ,"symbol": "lei"},
|
||||
"RS" : { "code": "RSD" ,"symbol": "Дин."},
|
||||
"RU" : { "code": "RUB" ,"symbol": "₽"},
|
||||
"RW" : { "code": "RWF" ,"symbol": "R₣"},
|
||||
"SA" : { "code": "SAR" ,"symbol": "﷼"},
|
||||
"SB" : { "code": "SBD" ,"symbol": "$"},
|
||||
"SC" : { "code": "SCR" ,"symbol": "₨"},
|
||||
"SD" : { "code": "SDG" ,"symbol": "ج.س."},
|
||||
"SE" : { "code": "SEK" ,"symbol": "kr"},
|
||||
"SG" : { "code": "SGD" ,"symbol": "S$"},
|
||||
"SH" : { "code": "SHP" ,"symbol": "£"},
|
||||
"SI" : { "code": "EUR" ,"symbol": "€"},
|
||||
"SJ" : { "code": "NOK" ,"symbol": "kr"},
|
||||
"SK" : { "code": "EUR" ,"symbol": "€"},
|
||||
"SL" : { "code": "SLL" ,"symbol": "Le"},
|
||||
"SM" : { "code": "EUR" ,"symbol": "€"},
|
||||
"SN" : { "code": "XOF" ,"symbol": "CFA"},
|
||||
"SO" : { "code": "SOS" ,"symbol": "S"},
|
||||
"SR" : { "code": "SRD" ,"symbol": "$"},
|
||||
"SS" : { "code": "SSP" ,"symbol": "£"},
|
||||
"ST" : { "code": "STD" ,"symbol": "Db"},
|
||||
"SV" : { "code": "USD" ,"symbol": "$"},
|
||||
"SX" : { "code": "ANG" ,"symbol": "ƒ"},
|
||||
"SY" : { "code": "SYP" ,"symbol": "£"},
|
||||
"SZ" : { "code": "SZL" ,"symbol": "E"},
|
||||
"TC" : { "code": "USD" ,"symbol": "$"},
|
||||
"TD" : { "code": "XAF" ,"symbol": "FCFA"},
|
||||
"TF" : { "code": "EUR" ,"symbol": "€"},
|
||||
"TG" : { "code": "XOF" ,"symbol": "CFA"},
|
||||
"TH" : { "code": "THB" ,"symbol": "฿"},
|
||||
"TJ" : { "code": "TJS" ,"symbol": "SM"},
|
||||
"TK" : { "code": "NZD" ,"symbol": "$"},
|
||||
"TL" : { "code": "USD" ,"symbol": "$"},
|
||||
"TM" : { "code": "TMT" ,"symbol": "T"},
|
||||
"TN" : { "code": "TND" ,"symbol": "د.ت"},
|
||||
"TO" : { "code": "TOP" ,"symbol": "T$"},
|
||||
"TR" : { "code": "TRY" ,"symbol": "₺"},
|
||||
"TT" : { "code": "TTD" ,"symbol": "TT$"},
|
||||
"TV" : { "code": "AUD" ,"symbol": "$"},
|
||||
"TW" : { "code": "TWD" ,"symbol": "NT$"},
|
||||
"TZ" : { "code": "TZS" ,"symbol": "TSh"},
|
||||
"UA" : { "code": "UAH" ,"symbol": "₴"},
|
||||
"UG" : { "code": "UGX" ,"symbol": "USh"},
|
||||
"UM" : { "code": "USD" ,"symbol": "$"},
|
||||
"US" : { "code": "USD" ,"symbol": "$"},
|
||||
"UY" : { "code": "UYU" ,"symbol": "$U"},
|
||||
"UZ" : { "code": "UZS" ,"symbol": "лв"},
|
||||
"VA" : { "code": "EUR" ,"symbol": "€"},
|
||||
"VC" : { "code": "XCD" ,"symbol": "$"},
|
||||
"VE" : { "code": "VEF" ,"symbol": "Bs"},
|
||||
"VG" : { "code": "USD" ,"symbol": "$"},
|
||||
"VI" : { "code": "USD" ,"symbol": "$"},
|
||||
"VN" : { "code": "VND" ,"symbol": "₫"},
|
||||
"VU" : { "code": "VUV" ,"symbol": "VT"},
|
||||
"WF" : { "code": "XPF" ,"symbol": "₣"},
|
||||
"WS" : { "code": "WST" ,"symbol": "WS$"},
|
||||
"XK" : { "code": "EUR" ,"symbol": "€"},
|
||||
"YE" : { "code": "YER" ,"symbol": "﷼"},
|
||||
"YT" : { "code": "EUR" ,"symbol": "€"},
|
||||
"ZA" : { "code": "ZAR" ,"symbol": "R"},
|
||||
"ZM" : { "code": "ZMK" ,"symbol": "ZK"},
|
||||
"ZW" : { "code": "ZWL" ,"symbol": "$"}
|
||||
}
|
||||
|
||||
1
dev/app-bak/Services/IPinfo/json/eu.json
Normal file
1
dev/app-bak/Services/IPinfo/json/eu.json
Normal file
|
|
@ -0,0 +1 @@
|
|||
["IE","AT","LT","LU","LV","DE","DK","SE","SI","SK","CZ","CY","NL","FI","FR","MT","ES","IT","EE","PL","PT","HU","HR","GR","RO","BG","BE"]
|
||||
252
dev/app-bak/Services/IPinfo/json/flags.json
Normal file
252
dev/app-bak/Services/IPinfo/json/flags.json
Normal file
|
|
@ -0,0 +1,252 @@
|
|||
{
|
||||
"AD": {"emoji": "🇦🇩","unicode": "U+1F1E6 U+1F1E9"},
|
||||
"AE": {"emoji": "🇦🇪","unicode": "U+1F1E6 U+1F1EA"},
|
||||
"AF": {"emoji": "🇦🇫","unicode": "U+1F1E6 U+1F1EB"},
|
||||
"AG": {"emoji": "🇦🇬","unicode": "U+1F1E6 U+1F1EC"},
|
||||
"AI": {"emoji": "🇦🇮","unicode": "U+1F1E6 U+1F1EE"},
|
||||
"AL": {"emoji": "🇦🇱","unicode": "U+1F1E6 U+1F1F1"},
|
||||
"AM": {"emoji": "🇦🇲","unicode": "U+1F1E6 U+1F1F2"},
|
||||
"AO": {"emoji": "🇦🇴","unicode": "U+1F1E6 U+1F1F4"},
|
||||
"AQ": {"emoji": "🇦🇶","unicode": "U+1F1E6 U+1F1F6"},
|
||||
"AR": {"emoji": "🇦🇷","unicode": "U+1F1E6 U+1F1F7"},
|
||||
"AS": {"emoji": "🇦🇸","unicode": "U+1F1E6 U+1F1F8"},
|
||||
"AT": {"emoji": "🇦🇹","unicode": "U+1F1E6 U+1F1F9"},
|
||||
"AU": {"emoji": "🇦🇺","unicode": "U+1F1E6 U+1F1FA"},
|
||||
"AW": {"emoji": "🇦🇼","unicode": "U+1F1E6 U+1F1FC"},
|
||||
"AX": {"emoji": "🇦🇽","unicode": "U+1F1E6 U+1F1FD"},
|
||||
"AZ": {"emoji": "🇦🇿","unicode": "U+1F1E6 U+1F1FF"},
|
||||
"BA": {"emoji": "🇧🇦","unicode": "U+1F1E7 U+1F1E6"},
|
||||
"BB": {"emoji": "🇧🇧","unicode": "U+1F1E7 U+1F1E7"},
|
||||
"BD": {"emoji": "🇧🇩","unicode": "U+1F1E7 U+1F1E9"},
|
||||
"BE": {"emoji": "🇧🇪","unicode": "U+1F1E7 U+1F1EA"},
|
||||
"BF": {"emoji": "🇧🇫","unicode": "U+1F1E7 U+1F1EB"},
|
||||
"BG": {"emoji": "🇧🇬","unicode": "U+1F1E7 U+1F1EC"},
|
||||
"BH": {"emoji": "🇧🇭","unicode": "U+1F1E7 U+1F1ED"},
|
||||
"BI": {"emoji": "🇧🇮","unicode": "U+1F1E7 U+1F1EE"},
|
||||
"BJ": {"emoji": "🇧🇯","unicode": "U+1F1E7 U+1F1EF"},
|
||||
"BL": {"emoji": "🇧🇱","unicode": "U+1F1E7 U+1F1F1"},
|
||||
"BM": {"emoji": "🇧🇲","unicode": "U+1F1E7 U+1F1F2"},
|
||||
"BN": {"emoji": "🇧🇳","unicode": "U+1F1E7 U+1F1F3"},
|
||||
"BO": {"emoji": "🇧🇴","unicode": "U+1F1E7 U+1F1F4"},
|
||||
"BQ": {"emoji": "🇧🇶","unicode": "U+1F1E7 U+1F1F6"},
|
||||
"BR": {"emoji": "🇧🇷","unicode": "U+1F1E7 U+1F1F7"},
|
||||
"BS": {"emoji": "🇧🇸","unicode": "U+1F1E7 U+1F1F8"},
|
||||
"BT": {"emoji": "🇧🇹","unicode": "U+1F1E7 U+1F1F9"},
|
||||
"BV": {"emoji": "🇧🇻","unicode": "U+1F1E7 U+1F1FB"},
|
||||
"BW": {"emoji": "🇧🇼","unicode": "U+1F1E7 U+1F1FC"},
|
||||
"BY": {"emoji": "🇧🇾","unicode": "U+1F1E7 U+1F1FE"},
|
||||
"BZ": {"emoji": "🇧🇿","unicode": "U+1F1E7 U+1F1FF"},
|
||||
"CA": {"emoji": "🇨🇦","unicode": "U+1F1E8 U+1F1E6"},
|
||||
"CC": {"emoji": "🇨🇨","unicode": "U+1F1E8 U+1F1E8"},
|
||||
"CD": {"emoji": "🇨🇩","unicode": "U+1F1E8 U+1F1E9"},
|
||||
"CF": {"emoji": "🇨🇫","unicode": "U+1F1E8 U+1F1EB"},
|
||||
"CG": {"emoji": "🇨🇬","unicode": "U+1F1E8 U+1F1EC"},
|
||||
"CH": {"emoji": "🇨🇭","unicode": "U+1F1E8 U+1F1ED"},
|
||||
"CI": {"emoji": "🇨🇮","unicode": "U+1F1E8 U+1F1EE"},
|
||||
"CK": {"emoji": "🇨🇰","unicode": "U+1F1E8 U+1F1F0"},
|
||||
"CL": {"emoji": "🇨🇱","unicode": "U+1F1E8 U+1F1F1"},
|
||||
"CM": {"emoji": "🇨🇲","unicode": "U+1F1E8 U+1F1F2"},
|
||||
"CN": {"emoji": "🇨🇳","unicode": "U+1F1E8 U+1F1F3"},
|
||||
"CO": {"emoji": "🇨🇴","unicode": "U+1F1E8 U+1F1F4"},
|
||||
"CR": {"emoji": "🇨🇷","unicode": "U+1F1E8 U+1F1F7"},
|
||||
"CU": {"emoji": "🇨🇺","unicode": "U+1F1E8 U+1F1FA"},
|
||||
"CV": {"emoji": "🇨🇻","unicode": "U+1F1E8 U+1F1FB"},
|
||||
"CW": {"emoji": "🇨🇼","unicode": "U+1F1E8 U+1F1FC"},
|
||||
"CX": {"emoji": "🇨🇽","unicode": "U+1F1E8 U+1F1FD"},
|
||||
"CY": {"emoji": "🇨🇾","unicode": "U+1F1E8 U+1F1FE"},
|
||||
"CZ": {"emoji": "🇨🇿","unicode": "U+1F1E8 U+1F1FF"},
|
||||
"DE": {"emoji": "🇩🇪","unicode": "U+1F1E9 U+1F1EA"},
|
||||
"DJ": {"emoji": "🇩🇯","unicode": "U+1F1E9 U+1F1EF"},
|
||||
"DK": {"emoji": "🇩🇰","unicode": "U+1F1E9 U+1F1F0"},
|
||||
"DM": {"emoji": "🇩🇲","unicode": "U+1F1E9 U+1F1F2"},
|
||||
"DO": {"emoji": "🇩🇴","unicode": "U+1F1E9 U+1F1F4"},
|
||||
"DZ": {"emoji": "🇩🇿","unicode": "U+1F1E9 U+1F1FF"},
|
||||
"EC": {"emoji": "🇪🇨","unicode": "U+1F1EA U+1F1E8"},
|
||||
"EE": {"emoji": "🇪🇪","unicode": "U+1F1EA U+1F1EA"},
|
||||
"EG": {"emoji": "🇪🇬","unicode": "U+1F1EA U+1F1EC"},
|
||||
"EH": {"emoji": "🇪🇭","unicode": "U+1F1EA U+1F1ED"},
|
||||
"ER": {"emoji": "🇪🇷","unicode": "U+1F1EA U+1F1F7"},
|
||||
"ES": {"emoji": "🇪🇸","unicode": "U+1F1EA U+1F1F8"},
|
||||
"ET": {"emoji": "🇪🇹","unicode": "U+1F1EA U+1F1F9"},
|
||||
"FI": {"emoji": "🇫🇮","unicode": "U+1F1EB U+1F1EE"},
|
||||
"FJ": {"emoji": "🇫🇯","unicode": "U+1F1EB U+1F1EF"},
|
||||
"FK": {"emoji": "🇫🇰","unicode": "U+1F1EB U+1F1F0"},
|
||||
"FM": {"emoji": "🇫🇲","unicode": "U+1F1EB U+1F1F2"},
|
||||
"FO": {"emoji": "🇫🇴","unicode": "U+1F1EB U+1F1F4"},
|
||||
"FR": {"emoji": "🇫🇷","unicode": "U+1F1EB U+1F1F7"},
|
||||
"GA": {"emoji": "🇬🇦","unicode": "U+1F1EC U+1F1E6"},
|
||||
"GB": {"emoji": "🇬🇧","unicode": "U+1F1EC U+1F1E7"},
|
||||
"GD": {"emoji": "🇬🇩","unicode": "U+1F1EC U+1F1E9"},
|
||||
"GE": {"emoji": "🇬🇪","unicode": "U+1F1EC U+1F1EA"},
|
||||
"GF": {"emoji": "🇬🇫","unicode": "U+1F1EC U+1F1EB"},
|
||||
"GG": {"emoji": "🇬🇬","unicode": "U+1F1EC U+1F1EC"},
|
||||
"GH": {"emoji": "🇬🇭","unicode": "U+1F1EC U+1F1ED"},
|
||||
"GI": {"emoji": "🇬🇮","unicode": "U+1F1EC U+1F1EE"},
|
||||
"GL": {"emoji": "🇬🇱","unicode": "U+1F1EC U+1F1F1"},
|
||||
"GM": {"emoji": "🇬🇲","unicode": "U+1F1EC U+1F1F2"},
|
||||
"GN": {"emoji": "🇬🇳","unicode": "U+1F1EC U+1F1F3"},
|
||||
"GP": {"emoji": "🇬🇵","unicode": "U+1F1EC U+1F1F5"},
|
||||
"GQ": {"emoji": "🇬🇶","unicode": "U+1F1EC U+1F1F6"},
|
||||
"GR": {"emoji": "🇬🇷","unicode": "U+1F1EC U+1F1F7"},
|
||||
"GS": {"emoji": "🇬🇸","unicode": "U+1F1EC U+1F1F8"},
|
||||
"GT": {"emoji": "🇬🇹","unicode": "U+1F1EC U+1F1F9"},
|
||||
"GU": {"emoji": "🇬🇺","unicode": "U+1F1EC U+1F1FA"},
|
||||
"GW": {"emoji": "🇬🇼","unicode": "U+1F1EC U+1F1FC"},
|
||||
"GY": {"emoji": "🇬🇾","unicode": "U+1F1EC U+1F1FE"},
|
||||
"HK": {"emoji": "🇭🇰","unicode": "U+1F1ED U+1F1F0"},
|
||||
"HM": {"emoji": "🇭🇲","unicode": "U+1F1ED U+1F1F2"},
|
||||
"HN": {"emoji": "🇭🇳","unicode": "U+1F1ED U+1F1F3"},
|
||||
"HR": {"emoji": "🇭🇷","unicode": "U+1F1ED U+1F1F7"},
|
||||
"HT": {"emoji": "🇭🇹","unicode": "U+1F1ED U+1F1F9"},
|
||||
"HU": {"emoji": "🇭🇺","unicode": "U+1F1ED U+1F1FA"},
|
||||
"ID": {"emoji": "🇮🇩","unicode": "U+1F1EE U+1F1E9"},
|
||||
"IE": {"emoji": "🇮🇪","unicode": "U+1F1EE U+1F1EA"},
|
||||
"IL": {"emoji": "🇮🇱","unicode": "U+1F1EE U+1F1F1"},
|
||||
"IM": {"emoji": "🇮🇲","unicode": "U+1F1EE U+1F1F2"},
|
||||
"IN": {"emoji": "🇮🇳","unicode": "U+1F1EE U+1F1F3"},
|
||||
"IO": {"emoji": "🇮🇴","unicode": "U+1F1EE U+1F1F4"},
|
||||
"IQ": {"emoji": "🇮🇶","unicode": "U+1F1EE U+1F1F6"},
|
||||
"IR": {"emoji": "🇮🇷","unicode": "U+1F1EE U+1F1F7"},
|
||||
"IS": {"emoji": "🇮🇸","unicode": "U+1F1EE U+1F1F8"},
|
||||
"IT": {"emoji": "🇮🇹","unicode": "U+1F1EE U+1F1F9"},
|
||||
"JE": {"emoji": "🇯🇪","unicode": "U+1F1EF U+1F1EA"},
|
||||
"JM": {"emoji": "🇯🇲","unicode": "U+1F1EF U+1F1F2"},
|
||||
"JO": {"emoji": "🇯🇴","unicode": "U+1F1EF U+1F1F4"},
|
||||
"JP": {"emoji": "🇯🇵","unicode": "U+1F1EF U+1F1F5"},
|
||||
"KE": {"emoji": "🇰🇪","unicode": "U+1F1F0 U+1F1EA"},
|
||||
"KG": {"emoji": "🇰🇬","unicode": "U+1F1F0 U+1F1EC"},
|
||||
"KH": {"emoji": "🇰🇭","unicode": "U+1F1F0 U+1F1ED"},
|
||||
"KI": {"emoji": "🇰🇮","unicode": "U+1F1F0 U+1F1EE"},
|
||||
"KM": {"emoji": "🇰🇲","unicode": "U+1F1F0 U+1F1F2"},
|
||||
"KN": {"emoji": "🇰🇳","unicode": "U+1F1F0 U+1F1F3"},
|
||||
"KP": {"emoji": "🇰🇵","unicode": "U+1F1F0 U+1F1F5"},
|
||||
"KR": {"emoji": "🇰🇷","unicode": "U+1F1F0 U+1F1F7"},
|
||||
"KW": {"emoji": "🇰🇼","unicode": "U+1F1F0 U+1F1FC"},
|
||||
"KY": {"emoji": "🇰🇾","unicode": "U+1F1F0 U+1F1FE"},
|
||||
"KZ": {"emoji": "🇰🇿","unicode": "U+1F1F0 U+1F1FF"},
|
||||
"LA": {"emoji": "🇱🇦","unicode": "U+1F1F1 U+1F1E6"},
|
||||
"LB": {"emoji": "🇱🇧","unicode": "U+1F1F1 U+1F1E7"},
|
||||
"LC": {"emoji": "🇱🇨","unicode": "U+1F1F1 U+1F1E8"},
|
||||
"LI": {"emoji": "🇱🇮","unicode": "U+1F1F1 U+1F1EE"},
|
||||
"LK": {"emoji": "🇱🇰","unicode": "U+1F1F1 U+1F1F0"},
|
||||
"LR": {"emoji": "🇱🇷","unicode": "U+1F1F1 U+1F1F7"},
|
||||
"LS": {"emoji": "🇱🇸","unicode": "U+1F1F1 U+1F1F8"},
|
||||
"LT": {"emoji": "🇱🇹","unicode": "U+1F1F1 U+1F1F9"},
|
||||
"LU": {"emoji": "🇱🇺","unicode": "U+1F1F1 U+1F1FA"},
|
||||
"LV": {"emoji": "🇱🇻","unicode": "U+1F1F1 U+1F1FB"},
|
||||
"LY": {"emoji": "🇱🇾","unicode": "U+1F1F1 U+1F1FE"},
|
||||
"MA": {"emoji": "🇲🇦","unicode": "U+1F1F2 U+1F1E6"},
|
||||
"MC": {"emoji": "🇲🇨","unicode": "U+1F1F2 U+1F1E8"},
|
||||
"MD": {"emoji": "🇲🇩","unicode": "U+1F1F2 U+1F1E9"},
|
||||
"ME": {"emoji": "🇲🇪","unicode": "U+1F1F2 U+1F1EA"},
|
||||
"MF": {"emoji": "🇲🇫","unicode": "U+1F1F2 U+1F1EB"},
|
||||
"MG": {"emoji": "🇲🇬","unicode": "U+1F1F2 U+1F1EC"},
|
||||
"MH": {"emoji": "🇲🇭","unicode": "U+1F1F2 U+1F1ED"},
|
||||
"MK": {"emoji": "🇲🇰","unicode": "U+1F1F2 U+1F1F0"},
|
||||
"ML": {"emoji": "🇲🇱","unicode": "U+1F1F2 U+1F1F1"},
|
||||
"MM": {"emoji": "🇲🇲","unicode": "U+1F1F2 U+1F1F2"},
|
||||
"MN": {"emoji": "🇲🇳","unicode": "U+1F1F2 U+1F1F3"},
|
||||
"MO": {"emoji": "🇲🇴","unicode": "U+1F1F2 U+1F1F4"},
|
||||
"MP": {"emoji": "🇲🇵","unicode": "U+1F1F2 U+1F1F5"},
|
||||
"MQ": {"emoji": "🇲🇶","unicode": "U+1F1F2 U+1F1F6"},
|
||||
"MR": {"emoji": "🇲🇷","unicode": "U+1F1F2 U+1F1F7"},
|
||||
"MS": {"emoji": "🇲🇸","unicode": "U+1F1F2 U+1F1F8"},
|
||||
"MT": {"emoji": "🇲🇹","unicode": "U+1F1F2 U+1F1F9"},
|
||||
"MU": {"emoji": "🇲🇺","unicode": "U+1F1F2 U+1F1FA"},
|
||||
"MV": {"emoji": "🇲🇻","unicode": "U+1F1F2 U+1F1FB"},
|
||||
"MW": {"emoji": "🇲🇼","unicode": "U+1F1F2 U+1F1FC"},
|
||||
"MX": {"emoji": "🇲🇽","unicode": "U+1F1F2 U+1F1FD"},
|
||||
"MY": {"emoji": "🇲🇾","unicode": "U+1F1F2 U+1F1FE"},
|
||||
"MZ": {"emoji": "🇲🇿","unicode": "U+1F1F2 U+1F1FF"},
|
||||
"NA": {"emoji": "🇳🇦","unicode": "U+1F1F3 U+1F1E6"},
|
||||
"NC": {"emoji": "🇳🇨","unicode": "U+1F1F3 U+1F1E8"},
|
||||
"NE": {"emoji": "🇳🇪","unicode": "U+1F1F3 U+1F1EA"},
|
||||
"NF": {"emoji": "🇳🇫","unicode": "U+1F1F3 U+1F1EB"},
|
||||
"NG": {"emoji": "🇳🇬","unicode": "U+1F1F3 U+1F1EC"},
|
||||
"NI": {"emoji": "🇳🇮","unicode": "U+1F1F3 U+1F1EE"},
|
||||
"NL": {"emoji": "🇳🇱","unicode": "U+1F1F3 U+1F1F1"},
|
||||
"NO": {"emoji": "🇳🇴","unicode": "U+1F1F3 U+1F1F4"},
|
||||
"NP": {"emoji": "🇳🇵","unicode": "U+1F1F3 U+1F1F5"},
|
||||
"NR": {"emoji": "🇳🇷","unicode": "U+1F1F3 U+1F1F7"},
|
||||
"NU": {"emoji": "🇳🇺","unicode": "U+1F1F3 U+1F1FA"},
|
||||
"NZ": {"emoji": "🇳🇿","unicode": "U+1F1F3 U+1F1FF"},
|
||||
"OM": {"emoji": "🇴🇲","unicode": "U+1F1F4 U+1F1F2"},
|
||||
"PA": {"emoji": "🇵🇦","unicode": "U+1F1F5 U+1F1E6"},
|
||||
"PE": {"emoji": "🇵🇪","unicode": "U+1F1F5 U+1F1EA"},
|
||||
"PF": {"emoji": "🇵🇫","unicode": "U+1F1F5 U+1F1EB"},
|
||||
"PG": {"emoji": "🇵🇬","unicode": "U+1F1F5 U+1F1EC"},
|
||||
"PH": {"emoji": "🇵🇭","unicode": "U+1F1F5 U+1F1ED"},
|
||||
"PK": {"emoji": "🇵🇰","unicode": "U+1F1F5 U+1F1F0"},
|
||||
"PL": {"emoji": "🇵🇱","unicode": "U+1F1F5 U+1F1F1"},
|
||||
"PM": {"emoji": "🇵🇲","unicode": "U+1F1F5 U+1F1F2"},
|
||||
"PN": {"emoji": "🇵🇳","unicode": "U+1F1F5 U+1F1F3"},
|
||||
"PR": {"emoji": "🇵🇷","unicode": "U+1F1F5 U+1F1F7"},
|
||||
"PS": {"emoji": "🇵🇸","unicode": "U+1F1F5 U+1F1F8"},
|
||||
"PT": {"emoji": "🇵🇹","unicode": "U+1F1F5 U+1F1F9"},
|
||||
"PW": {"emoji": "🇵🇼","unicode": "U+1F1F5 U+1F1FC"},
|
||||
"PY": {"emoji": "🇵🇾","unicode": "U+1F1F5 U+1F1FE"},
|
||||
"QA": {"emoji": "🇶🇦","unicode": "U+1F1F6 U+1F1E6"},
|
||||
"RE": {"emoji": "🇷🇪","unicode": "U+1F1F7 U+1F1EA"},
|
||||
"RO": {"emoji": "🇷🇴","unicode": "U+1F1F7 U+1F1F4"},
|
||||
"RS": {"emoji": "🇷🇸","unicode": "U+1F1F7 U+1F1F8"},
|
||||
"RU": {"emoji": "🇷🇺","unicode": "U+1F1F7 U+1F1FA"},
|
||||
"RW": {"emoji": "🇷🇼","unicode": "U+1F1F7 U+1F1FC"},
|
||||
"SA": {"emoji": "🇸🇦","unicode": "U+1F1F8 U+1F1E6"},
|
||||
"SB": {"emoji": "🇸🇧","unicode": "U+1F1F8 U+1F1E7"},
|
||||
"SC": {"emoji": "🇸🇨","unicode": "U+1F1F8 U+1F1E8"},
|
||||
"SD": {"emoji": "🇸🇩","unicode": "U+1F1F8 U+1F1E9"},
|
||||
"SE": {"emoji": "🇸🇪","unicode": "U+1F1F8 U+1F1EA"},
|
||||
"SG": {"emoji": "🇸🇬","unicode": "U+1F1F8 U+1F1EC"},
|
||||
"SH": {"emoji": "🇸🇭","unicode": "U+1F1F8 U+1F1ED"},
|
||||
"SI": {"emoji": "🇸🇮","unicode": "U+1F1F8 U+1F1EE"},
|
||||
"SJ": {"emoji": "🇸🇯","unicode": "U+1F1F8 U+1F1EF"},
|
||||
"SK": {"emoji": "🇸🇰","unicode": "U+1F1F8 U+1F1F0"},
|
||||
"SL": {"emoji": "🇸🇱","unicode": "U+1F1F8 U+1F1F1"},
|
||||
"SM": {"emoji": "🇸🇲","unicode": "U+1F1F8 U+1F1F2"},
|
||||
"SN": {"emoji": "🇸🇳","unicode": "U+1F1F8 U+1F1F3"},
|
||||
"SO": {"emoji": "🇸🇴","unicode": "U+1F1F8 U+1F1F4"},
|
||||
"SR": {"emoji": "🇸🇷","unicode": "U+1F1F8 U+1F1F7"},
|
||||
"SS": {"emoji": "🇸🇸","unicode": "U+1F1F8 U+1F1F8"},
|
||||
"ST": {"emoji": "🇸🇹","unicode": "U+1F1F8 U+1F1F9"},
|
||||
"SV": {"emoji": "🇸🇻","unicode": "U+1F1F8 U+1F1FB"},
|
||||
"SX": {"emoji": "🇸🇽","unicode": "U+1F1F8 U+1F1FD"},
|
||||
"SY": {"emoji": "🇸🇾","unicode": "U+1F1F8 U+1F1FE"},
|
||||
"SZ": {"emoji": "🇸🇿","unicode": "U+1F1F8 U+1F1FF"},
|
||||
"TC": {"emoji": "🇹🇨","unicode": "U+1F1F9 U+1F1E8"},
|
||||
"TD": {"emoji": "🇹🇩","unicode": "U+1F1F9 U+1F1E9"},
|
||||
"TF": {"emoji": "🇹🇫","unicode": "U+1F1F9 U+1F1EB"},
|
||||
"TG": {"emoji": "🇹🇬","unicode": "U+1F1F9 U+1F1EC"},
|
||||
"TH": {"emoji": "🇹🇭","unicode": "U+1F1F9 U+1F1ED"},
|
||||
"TJ": {"emoji": "🇹🇯","unicode": "U+1F1F9 U+1F1EF"},
|
||||
"TK": {"emoji": "🇹🇰","unicode": "U+1F1F9 U+1F1F0"},
|
||||
"TL": {"emoji": "🇹🇱","unicode": "U+1F1F9 U+1F1F1"},
|
||||
"TM": {"emoji": "🇹🇲","unicode": "U+1F1F9 U+1F1F2"},
|
||||
"TN": {"emoji": "🇹🇳","unicode": "U+1F1F9 U+1F1F3"},
|
||||
"TO": {"emoji": "🇹🇴","unicode": "U+1F1F9 U+1F1F4"},
|
||||
"TR": {"emoji": "🇹🇷","unicode": "U+1F1F9 U+1F1F7"},
|
||||
"TT": {"emoji": "🇹🇹","unicode": "U+1F1F9 U+1F1F9"},
|
||||
"TV": {"emoji": "🇹🇻","unicode": "U+1F1F9 U+1F1FB"},
|
||||
"TW": {"emoji": "🇹🇼","unicode": "U+1F1F9 U+1F1FC"},
|
||||
"TZ": {"emoji": "🇹🇿","unicode": "U+1F1F9 U+1F1FF"},
|
||||
"UA": {"emoji": "🇺🇦","unicode": "U+1F1FA U+1F1E6"},
|
||||
"UG": {"emoji": "🇺🇬","unicode": "U+1F1FA U+1F1EC"},
|
||||
"UM": {"emoji": "🇺🇲","unicode": "U+1F1FA U+1F1F2"},
|
||||
"US": {"emoji": "🇺🇸","unicode": "U+1F1FA U+1F1F8"},
|
||||
"UY": {"emoji": "🇺🇾","unicode": "U+1F1FA U+1F1FE"},
|
||||
"UZ": {"emoji": "🇺🇿","unicode": "U+1F1FA U+1F1FF"},
|
||||
"VA": {"emoji": "🇻🇦","unicode": "U+1F1FB U+1F1E6"},
|
||||
"VC": {"emoji": "🇻🇨","unicode": "U+1F1FB U+1F1E8"},
|
||||
"VE": {"emoji": "🇻🇪","unicode": "U+1F1FB U+1F1EA"},
|
||||
"VG": {"emoji": "🇻🇬","unicode": "U+1F1FB U+1F1EC"},
|
||||
"VI": {"emoji": "🇻🇮","unicode": "U+1F1FB U+1F1EE"},
|
||||
"VN": {"emoji": "🇻🇳","unicode": "U+1F1FB U+1F1F3"},
|
||||
"VU": {"emoji": "🇻🇺","unicode": "U+1F1FB U+1F1FA"},
|
||||
"WF": {"emoji": "🇼🇫","unicode": "U+1F1FC U+1F1EB"},
|
||||
"WS": {"emoji": "🇼🇸","unicode": "U+1F1FC U+1F1F8"},
|
||||
"XK": {"emoji": "🇽🇰","unicode": "U+1F1FD U+1F1F0"},
|
||||
"YE": {"emoji": "🇾🇪","unicode": "U+1F1FE U+1F1EA"},
|
||||
"YT": {"emoji": "🇾🇹","unicode": "U+1F1FE U+1F1F9"},
|
||||
"ZA": {"emoji": "🇿🇦","unicode": "U+1F1FF U+1F1E6"},
|
||||
"ZM": {"emoji": "🇿🇲","unicode": "U+1F1FF U+1F1F2"},
|
||||
"ZW": {"emoji": "🇿🇼","unicode": "U+1F1FF U+1F1FC"}
|
||||
}
|
||||
67
dev/app-bak/Services/Invoice.php
Normal file
67
dev/app-bak/Services/Invoice.php
Normal file
|
|
@ -0,0 +1,67 @@
|
|||
<?php
|
||||
namespace App\Services;
|
||||
|
||||
use App\Mail\MailInvoice;
|
||||
use App\Models\Setting;
|
||||
use App\Models\ShoppingOrder;
|
||||
use Illuminate\Support\Facades\Mail;
|
||||
|
||||
class Invoice
|
||||
{
|
||||
|
||||
public static function getInvoiceNumber(){
|
||||
return (int) Setting::getContentBySlug('invoice-number');
|
||||
}
|
||||
|
||||
public static function makeNextInvoiceNumber(){
|
||||
$invoice_number = self::getInvoiceNumber();
|
||||
$invoice_number = $invoice_number+1;
|
||||
Setting::setContentBySlug('invoice-number', $invoice_number, 'int');
|
||||
return $invoice_number;
|
||||
}
|
||||
|
||||
public static function createInvoiceNumber($invoice_number, $invoice_date){
|
||||
$prefix = \Carbon::parse($invoice_date)->format('Y');
|
||||
$invoice_number = str_pad($invoice_number, 5, '0', STR_PAD_LEFT);
|
||||
return $prefix.$invoice_number;
|
||||
}
|
||||
|
||||
public static function getInvoiceStorageDir($invoice_date){
|
||||
return "invoice/".\Carbon::parse($invoice_date)->format('Y/m/');
|
||||
}
|
||||
|
||||
public static function getDeliveryStorageDir($invoice_date){
|
||||
return "delivery/".\Carbon::parse($invoice_date)->format('Y/m/');
|
||||
}
|
||||
|
||||
public static function makeInvoiceFilename($invoice_number){
|
||||
return $invoice_number."-MIVITA-Rechnung.pdf";
|
||||
}
|
||||
|
||||
public static function makeDeliveryFilename($invoice_number){
|
||||
return $invoice_number."-MIVITA-Lieferschein.pdf";
|
||||
}
|
||||
|
||||
public static function isInvoice(ShoppingOrder $shopping_order){
|
||||
return $shopping_order->isInvoice();
|
||||
}
|
||||
|
||||
public static function sendInvoiceMail($shopping_order, $user_invoice){
|
||||
$bcc = [];
|
||||
$billing_email = $shopping_order->shopping_user->billing_email;
|
||||
if(!$billing_email){
|
||||
if($shopping_order->mode === 'test'){
|
||||
$billing_email = config('app.checkout_test_mail');
|
||||
}else{
|
||||
$billing_email = config('app.checkout_mail');
|
||||
}
|
||||
}
|
||||
if($shopping_order->mode === 'test'){
|
||||
$bcc[] = config('app.checkout_test_mail');
|
||||
}else{
|
||||
$bcc[] = config('app.checkout_mail');
|
||||
}
|
||||
|
||||
Mail::to($billing_email)->bcc($bcc)->locale($shopping_order->getLocale())->send(new MailInvoice($shopping_order, $user_invoice));
|
||||
}
|
||||
}
|
||||
232
dev/app-bak/Services/LevelReportService.php
Normal file
232
dev/app-bak/Services/LevelReportService.php
Normal file
|
|
@ -0,0 +1,232 @@
|
|||
<?php
|
||||
|
||||
namespace App\Services;
|
||||
|
||||
use App\Models\UserBusiness;
|
||||
use App\Models\UserLevel;
|
||||
use App\User;
|
||||
use Illuminate\Support\Collection;
|
||||
|
||||
class LevelReportService
|
||||
{
|
||||
public function getLevelPromotions(array $filters = []): Collection
|
||||
{
|
||||
$month = $filters['month'] ?? null;
|
||||
$year = $filters['year'] ?? null;
|
||||
$userId = $filters['user_id'] ?? null;
|
||||
$onlyNotUpdated = $filters['only_not_updated'] ?? false;
|
||||
|
||||
// Lade UserLevels für Referenz
|
||||
$userLevels = UserLevel::where('active', 1)->orderBy('pos')->get()->keyBy('id');
|
||||
|
||||
// Query UserBusiness Einträge mit Level-Aufstiegen
|
||||
$query = UserBusiness::whereNotNull('next_qual_user_level')
|
||||
->whereRaw("JSON_LENGTH(next_qual_user_level) > 0")
|
||||
->orderBy('year', 'desc')
|
||||
->orderBy('month', 'desc')
|
||||
->orderBy('user_id');
|
||||
|
||||
// Filter anwenden
|
||||
if ($month) {
|
||||
$query->where('month', $month);
|
||||
}
|
||||
if ($year) {
|
||||
$query->where('year', $year);
|
||||
}
|
||||
if ($userId) {
|
||||
$query->where('user_id', $userId);
|
||||
}
|
||||
|
||||
$userBusinesses = $query->get();
|
||||
|
||||
return $this->processLevelPromotions($userBusinesses, $userLevels, $onlyNotUpdated);
|
||||
}
|
||||
|
||||
public function processLevelPromotions($userBusinesses, $userLevels, $onlyNotUpdated = false): Collection
|
||||
{
|
||||
$promotions = [];
|
||||
|
||||
// Lade User-Daten für alle Level-Vergleiche
|
||||
$userIds = $userBusinesses->pluck('user_id')->unique();
|
||||
$users = User::whereIn('id', $userIds)->get(['id', 'm_level']);
|
||||
$currentUserLevels = $users->keyBy('id');
|
||||
|
||||
foreach ($userBusinesses as $userBusiness) {
|
||||
$nextQualUserLevel = $userBusiness->next_qual_user_level;
|
||||
|
||||
if (is_array($nextQualUserLevel) && !empty($nextQualUserLevel)) {
|
||||
// next_qual_user_level kann sowohl ein einzelnes Level-Objekt als auch ein Array von Level-Objekten sein
|
||||
$levelArray = isset($nextQualUserLevel['id']) ? [$nextQualUserLevel] : $nextQualUserLevel;
|
||||
|
||||
foreach ($levelArray as $newLevelData) {
|
||||
// Überprüfe ob es ein vollständiges Level-Objekt ist
|
||||
if (is_array($newLevelData) && isset($newLevelData['id'])) {
|
||||
$currentLevel = $userLevels->get($userBusiness->m_level_id);
|
||||
$newLevelId = $newLevelData['id'];
|
||||
|
||||
// Lade aktuellen User Level
|
||||
$currentUser = $currentUserLevels->get($userBusiness->user_id);
|
||||
$currentUserLevelName = 'Unbekannt';
|
||||
|
||||
if ($currentUser && $currentUser->m_level) {
|
||||
$currentUserLevel = $userLevels->get($currentUser->m_level);
|
||||
$currentUserLevelName = $currentUserLevel ? $currentUserLevel->name : 'Level ID: ' . $currentUser->m_level;
|
||||
}
|
||||
|
||||
// Filter: Nur User die noch nicht auf das neue Level umgestellt wurden
|
||||
if ($onlyNotUpdated) {
|
||||
if (!$currentUser || $currentUser->m_level == $newLevelId) {
|
||||
continue; // Skip - User ist bereits auf das neue Level umgestellt
|
||||
}
|
||||
}
|
||||
|
||||
$promotions[] = [
|
||||
'user_id' => $userBusiness->user_id,
|
||||
'email' => $userBusiness->email,
|
||||
'first_name' => $userBusiness->first_name,
|
||||
'last_name' => $userBusiness->last_name,
|
||||
'month' => $userBusiness->month,
|
||||
'year' => $userBusiness->year,
|
||||
'date' => sprintf('%04d-%02d', $userBusiness->year, $userBusiness->month),
|
||||
'from_level_id' => $userBusiness->m_level_id,
|
||||
'from_level_name' => $currentLevel ? $currentLevel->name : 'Unbekannt',
|
||||
'to_level_id' => $newLevelId,
|
||||
'to_level_name' => $newLevelData['name'] ?? 'Unbekannt',
|
||||
'to_level_margin' => $newLevelData['margin'] ?? 0,
|
||||
'to_level_margin_shop' => $newLevelData['margin_shop'] ?? 0,
|
||||
'to_level_qual_kp' => $newLevelData['qual_kp'] ?? 0,
|
||||
'to_level_qual_pp' => $newLevelData['qual_pp'] ?? 0,
|
||||
'to_level_growth_bonus' => $newLevelData['growth_bonus'] ?? 0,
|
||||
'to_level_pos' => $newLevelData['pos'] ?? 0,
|
||||
'current_user_level_id' => $currentUser ? $currentUser->m_level : null,
|
||||
'current_user_level_name' => $currentUserLevelName,
|
||||
'level_updated' => $onlyNotUpdated ? 'Nein' : ($currentUser && $currentUser->m_level == $newLevelId ? 'Ja' : 'Nein'),
|
||||
'total_pp' => $userBusiness->total_pp ?? 0,
|
||||
'total_qual_pp' => $userBusiness->total_qual_pp ?? 0,
|
||||
'payline_points_qual_kp' => $userBusiness->payline_points_qual_kp ?? 0,
|
||||
'sales_volume_points_sum' => $userBusiness->sales_volume_points_KP_sum ?? 0,
|
||||
'active_account' => $userBusiness->active_account ? 'Ja' : 'Nein',
|
||||
];
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// Sortiere nach Datum (neueste zuerst) und dann nach User ID
|
||||
usort($promotions, function ($a, $b) {
|
||||
if ($a['year'] !== $b['year']) {
|
||||
return $b['year'] - $a['year'];
|
||||
}
|
||||
if ($a['month'] !== $b['month']) {
|
||||
return $b['month'] - $a['month'];
|
||||
}
|
||||
return $a['user_id'] - $b['user_id'];
|
||||
});
|
||||
|
||||
return collect($promotions);
|
||||
}
|
||||
|
||||
public function getStatistics(Collection $promotions): array
|
||||
{
|
||||
$stats = [
|
||||
'total_count' => $promotions->count(),
|
||||
'level_stats' => [],
|
||||
'period_stats' => []
|
||||
];
|
||||
|
||||
// Statistik nach Level
|
||||
foreach ($promotions as $promotion) {
|
||||
$levelName = $promotion['to_level_name'];
|
||||
if (!isset($stats['level_stats'][$levelName])) {
|
||||
$stats['level_stats'][$levelName] = 0;
|
||||
}
|
||||
$stats['level_stats'][$levelName]++;
|
||||
}
|
||||
|
||||
// Statistik nach Monat/Jahr
|
||||
foreach ($promotions as $promotion) {
|
||||
$period = $promotion['date'];
|
||||
if (!isset($stats['period_stats'][$period])) {
|
||||
$stats['period_stats'][$period] = 0;
|
||||
}
|
||||
$stats['period_stats'][$period]++;
|
||||
}
|
||||
|
||||
return $stats;
|
||||
}
|
||||
|
||||
public function exportToCsv(Collection $promotions, string $filename = null): string
|
||||
{
|
||||
if (!$filename) {
|
||||
$filename = 'level_promotions_' . date('Y-m-d_H-i-s') . '.csv';
|
||||
}
|
||||
|
||||
$filepath = storage_path('app/reports/' . $filename);
|
||||
|
||||
// Erstelle Verzeichnis falls nicht vorhanden
|
||||
if (!file_exists(dirname($filepath))) {
|
||||
mkdir(dirname($filepath), 0755, true);
|
||||
}
|
||||
|
||||
$file = fopen($filepath, 'w');
|
||||
|
||||
// UTF-8 BOM für korrekte Darstellung in Excel
|
||||
fwrite($file, "\xEF\xBB\xBF");
|
||||
|
||||
// CSV Headers
|
||||
$headers = [
|
||||
'Datum',
|
||||
'User ID',
|
||||
'Vorname',
|
||||
'Nachname',
|
||||
'E-Mail',
|
||||
'Von Level ID',
|
||||
'Von Level Name',
|
||||
'Zu Level ID',
|
||||
'Zu Level Name',
|
||||
'Zu Level KP Anforderung',
|
||||
'Zu Level PP Anforderung',
|
||||
'User PP Total',
|
||||
'User PP Qualifiziert',
|
||||
'Aktueller User Level ID',
|
||||
'Aktueller User Level Name',
|
||||
'Level bereits geupdatet',
|
||||
'Aktiver Account',
|
||||
'Monat',
|
||||
'Jahr'
|
||||
];
|
||||
|
||||
fputcsv($file, $headers, ';');
|
||||
|
||||
// Daten schreiben
|
||||
foreach ($promotions as $promotion) {
|
||||
$row = [
|
||||
$promotion['date'],
|
||||
$promotion['user_id'],
|
||||
$promotion['first_name'],
|
||||
$promotion['last_name'],
|
||||
$promotion['email'],
|
||||
$promotion['from_level_id'],
|
||||
$promotion['from_level_name'],
|
||||
$promotion['to_level_id'],
|
||||
$promotion['to_level_name'],
|
||||
$promotion['to_level_qual_kp'],
|
||||
$promotion['to_level_qual_pp'],
|
||||
$promotion['sales_volume_points_sum'],
|
||||
$promotion['payline_points_qual_kp'],
|
||||
$promotion['current_user_level_id'] ?? 'N/A',
|
||||
$promotion['current_user_level_name'],
|
||||
$promotion['level_updated'],
|
||||
$promotion['active_account'],
|
||||
$promotion['month'],
|
||||
$promotion['year']
|
||||
];
|
||||
|
||||
fputcsv($file, $row, ';');
|
||||
}
|
||||
|
||||
fclose($file);
|
||||
|
||||
return $filepath;
|
||||
}
|
||||
}
|
||||
34
dev/app-bak/Services/MyLog.php
Normal file
34
dev/app-bak/Services/MyLog.php
Normal file
|
|
@ -0,0 +1,34 @@
|
|||
<?php
|
||||
namespace App\Services;
|
||||
|
||||
use App\Mail\MailLog;
|
||||
use Illuminate\Support\Facades\Mail;
|
||||
|
||||
|
||||
class MyLog
|
||||
{
|
||||
|
||||
|
||||
|
||||
public static function writeLog($channel = 'payment', $context = 'error', $message = '', $data = []){
|
||||
|
||||
switch ($context) {
|
||||
case 'notice':
|
||||
\Log::channel($channel)->notice($message.' : '.json_encode($data));
|
||||
break;
|
||||
case 'warning':
|
||||
\Log::channel($channel)->warning($message.' : '.json_encode($data));
|
||||
break;
|
||||
case 'info':
|
||||
\Log::channel($channel)->info($message.' : '.json_encode($data));
|
||||
break;
|
||||
default:
|
||||
\Log::channel($channel)->error($message.' : '.json_encode($data));
|
||||
break;
|
||||
}
|
||||
Mail::to(config('app.exception_mail'))->send(new MailLog($channel, $context, $message, $data));
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
||||
125
dev/app-bak/Services/NextLevelBadgeHelper.php
Normal file
125
dev/app-bak/Services/NextLevelBadgeHelper.php
Normal file
|
|
@ -0,0 +1,125 @@
|
|||
<?php
|
||||
|
||||
namespace App\Services;
|
||||
|
||||
use App\Models\UserBusiness;
|
||||
|
||||
/**
|
||||
* Helper-Klasse für die optimierte Generierung von Next-Level-Badges
|
||||
*
|
||||
* Diese Klasse nutzt ausschließlich bereits berechnete und gespeicherte Daten
|
||||
* aus der UserBusiness-Tabelle, anstatt für jeden User eine neue TreeCalcBot-Instanz
|
||||
* zu erstellen. Dies führt zu erheblichen Performance-Verbesserungen bei DataTables.
|
||||
*/
|
||||
class NextLevelBadgeHelper
|
||||
{
|
||||
/**
|
||||
* Generiert Badge für nächsten Level Qualifikation basierend auf UserBusiness-Daten
|
||||
*
|
||||
* @param UserBusiness $userBusiness Bereits gespeicherte Business-Daten
|
||||
* @return string HTML Badge
|
||||
*/
|
||||
public static function generateBadgeFromUserBusiness(UserBusiness $userBusiness): string
|
||||
{
|
||||
return self::renderBadge($userBusiness);
|
||||
}
|
||||
|
||||
/**
|
||||
* Generiert Badge basierend auf BusinessUser-Objekt (für TreeCalcBot-Kompatibilität)
|
||||
*
|
||||
* @param object $businessUser Business-User-Objekt mit Level-Daten
|
||||
* @return string HTML Badge
|
||||
*/
|
||||
public static function generateBadgeFromBusinessUser($businessUser): string
|
||||
{
|
||||
return self::renderBadge($businessUser);
|
||||
}
|
||||
|
||||
/**
|
||||
* Zentrale Badge-Rendering-Logik
|
||||
*
|
||||
* @param mixed $source UserBusiness Model oder BusinessUser Objekt
|
||||
* @return string HTML Badge
|
||||
*/
|
||||
private static function renderBadge($source): string
|
||||
{
|
||||
// Prüfe ob User für den nächsten Level qualifiziert ist (grün)
|
||||
if (!empty($source->next_qual_user_level)) {
|
||||
return self::renderQualifiedBadge($source);
|
||||
}
|
||||
|
||||
// Prüfe ob User den Level erreichen könnte, aber noch nicht qualifiziert ist (gelb)
|
||||
if (!empty($source->next_can_user_level)) {
|
||||
return self::renderCanReachBadge($source);
|
||||
}
|
||||
|
||||
// Kein nächster Level verfügbar (rot)
|
||||
return self::renderNoLevelBadge();
|
||||
}
|
||||
|
||||
/**
|
||||
* Rendert Badge für qualifizierte User (grün)
|
||||
*/
|
||||
private static function renderQualifiedBadge($source): string
|
||||
{
|
||||
$level = $source->next_qual_user_level;
|
||||
$ku = formatNumber($source->sales_volume_points_KP_sum ?? 0, 0);
|
||||
$ku_required = formatNumber($level['qual_kp'] ?? 0, 0);
|
||||
$tp = formatNumber($source->payline_points_qual_kp ?? 0, 0);
|
||||
$tp_required = formatNumber($level['qual_pp'] ?? 0, 0);
|
||||
$levelName = TranslationHelper::transUserLevelName($level['name'] ?? 'Unbekannt');
|
||||
|
||||
return '<span class="badge badge-outline-success" title="Qualifiziert für nächsten Level">
|
||||
<i class="fa fa-check"></i> ' . e($levelName) . '<br/>
|
||||
<small>KU: ' . $ku . '/' . $ku_required . ' | TP: ' . $tp . '/' . $tp_required . '</small>
|
||||
</span>';
|
||||
}
|
||||
|
||||
/**
|
||||
* Rendert Badge für User die den Level erreichen könnten (gelb)
|
||||
*/
|
||||
private static function renderCanReachBadge($source): string
|
||||
{
|
||||
$level = $source->next_can_user_level;
|
||||
$ku = formatNumber($source->sales_volume_points_KP_sum ?? 0, 0);
|
||||
$ku_required = formatNumber($level['qual_kp'] ?? 0, 0);
|
||||
$tp = formatNumber($source->payline_points_qual_kp ?? 0, 0);
|
||||
$tp_required = formatNumber($level['qual_pp'] ?? 0, 0);
|
||||
$levelName = TranslationHelper::transUserLevelName($level['name'] ?? 'Unbekannt');
|
||||
|
||||
return '<span class="badge badge-outline-warning-dark" title="Noch nicht qualifiziert">
|
||||
<i class="fa fa-clock"></i> ' . e($levelName) . '<br/>
|
||||
<small>KU: ' . $ku . '/' . $ku_required . ' | TP: ' . $tp . '/' . $tp_required . '</small>
|
||||
</span>';
|
||||
}
|
||||
|
||||
/**
|
||||
* Rendert Badge wenn kein nächster Level verfügbar ist (rot)
|
||||
*/
|
||||
private static function renderNoLevelBadge(): string
|
||||
{
|
||||
return '<span class="badge badge-outline-warning" title="Kein nächster Level verfügbar">
|
||||
<i class="fa fa-times"></i>
|
||||
</span>';
|
||||
}
|
||||
|
||||
/**
|
||||
* Fallback-Badge bei Fehlern oder fehlenden Daten
|
||||
*/
|
||||
public static function renderErrorBadge(string $message = 'Fehler bei der Berechnung'): string
|
||||
{
|
||||
return '<span class="badge badge-outline-danger" title="' . e($message) . '">
|
||||
<i class="fa fa-exclamation"></i> Fehler
|
||||
</span>';
|
||||
}
|
||||
|
||||
/**
|
||||
* Badge für fehlende Daten
|
||||
*/
|
||||
public static function renderNoDataBadge(): string
|
||||
{
|
||||
return '<span class="badge badge-outline-secondary" title="Keine Daten verfügbar">
|
||||
<i class="fa fa-question"></i> Keine Daten
|
||||
</span>';
|
||||
}
|
||||
}
|
||||
180
dev/app-bak/Services/OrderPaymentService.php
Normal file
180
dev/app-bak/Services/OrderPaymentService.php
Normal file
|
|
@ -0,0 +1,180 @@
|
|||
<?php
|
||||
namespace App\Services;
|
||||
|
||||
use App\Models\ShoppingUser;
|
||||
use App\Models\ShoppingInstance;
|
||||
use Yard;
|
||||
|
||||
class OrderPaymentService
|
||||
{
|
||||
|
||||
public static function deleteInstance($identifier){
|
||||
|
||||
Yard::instance('shopping')->deleteStoredCart($identifier);
|
||||
\App\Models\ShoppingInstance::where('identifier', $identifier)->delete();
|
||||
//delete session
|
||||
/* if(\Session::has('user_shop_payment') && \Session::get('user_shop_payment') === 6){
|
||||
$user_shop_identifier = \Session::get('user_shop_identifier');
|
||||
Yard::instance('shopping')->deleteStoredCart($identifier);
|
||||
\App\Models\ShoppingInstance::where('identifier', $identifier)->delete();
|
||||
}*/
|
||||
}
|
||||
|
||||
public static function updateInstanceStatus($identifier, $status, $lower = true){
|
||||
if(!ShoppingInstance::where('identifier', $identifier)->exists()){
|
||||
return false;
|
||||
}
|
||||
if($lower){
|
||||
ShoppingInstance::where('identifier', $identifier)->where('status', '<', $status)
|
||||
->update(['status' => $status]);
|
||||
}else{
|
||||
ShoppingInstance::where('identifier', $identifier)
|
||||
->update(['status' => $status]);
|
||||
}
|
||||
}
|
||||
|
||||
public static function getInstanceStatus($identifier){
|
||||
$shopping_instance = ShoppingInstance::where('identifier', $identifier)->first();
|
||||
if(!$shopping_instance){
|
||||
return false;
|
||||
}
|
||||
return $shopping_instance->getStatus();
|
||||
}
|
||||
|
||||
public static function getTypeBadge(ShoppingInstance $shoppingInstance){
|
||||
$isFor = $shoppingInstance->shopping_data['is_for'] ?? '-';
|
||||
if ($isFor === 'abo-ot-customer' ) {
|
||||
return ' <span class="badge badge-pill badge-warning">'.__('abo.abo').'</span>';
|
||||
}
|
||||
if ($isFor === 'ot-customer' ) {
|
||||
return ' <span class="badge badge-pill badge-secondary">'.__('order.order').'</span>';
|
||||
}
|
||||
return "";
|
||||
}
|
||||
|
||||
public static function getStatusBadge(ShoppingInstance $shoppingInstance){
|
||||
$status = $shoppingInstance->getStatus();
|
||||
$badgeClasses = [
|
||||
'link_sent' => 'success',
|
||||
'link_openly' => 'warning',
|
||||
'link_paid' => 'secondary',
|
||||
'link_check' => 'warning',
|
||||
'link_pending' => 'warning',
|
||||
'link_appointed' => 'secondary',
|
||||
'link_failed' => 'danger',
|
||||
'link_canceled' => 'danger'
|
||||
];
|
||||
|
||||
if (isset($badgeClasses[$status])) {
|
||||
return sprintf(' <span class="badge badge-pill badge-%s">%s</span>',
|
||||
$badgeClasses[$status],
|
||||
__('payment.' . $status)
|
||||
);
|
||||
}
|
||||
|
||||
return '';
|
||||
}
|
||||
|
||||
public static function getStatusAlert($status){
|
||||
$badgeClasses = [
|
||||
'link_sent' => 'success',
|
||||
'link_openly' => 'success',
|
||||
'link_check' => 'warning',
|
||||
'link_pending' => 'warning',
|
||||
'link_failed' => 'danger',
|
||||
'link_canceled' => 'danger',
|
||||
'link_appointed' => 'success',
|
||||
'link_paid' => 'success',
|
||||
|
||||
];
|
||||
|
||||
if (isset($badgeClasses[$status])) {
|
||||
return sprintf(' <div class="alert alert-%s">%s</div>',
|
||||
$badgeClasses[$status],
|
||||
__('payment.alert_' . $status)
|
||||
);
|
||||
}
|
||||
|
||||
return '';
|
||||
}
|
||||
|
||||
public static function getCustomPayment($identifier){
|
||||
|
||||
$shopping_instance = ShoppingInstance::where('identifier', $identifier)->first();
|
||||
if(!$shopping_instance){
|
||||
abort(403, __('msg.shopping_instance_not_found'));
|
||||
}
|
||||
$shopping_data = $shopping_instance->shopping_data;
|
||||
$shopping_user = $shopping_data['shopping_user_id'] ? ShoppingUser::find($shopping_data['shopping_user_id']) : null;
|
||||
if(!$shopping_user){
|
||||
abort(403, __('msg.shopping_user_not_found'));
|
||||
}
|
||||
$yard_shopping_items = self::getRestoredYardShoppingItems($shopping_instance);
|
||||
|
||||
$data = [
|
||||
'shopping_instance' => $shopping_instance,
|
||||
'shopping_user' => $shopping_user,
|
||||
'yard_shopping_items' => $yard_shopping_items,
|
||||
'identifier' => $identifier,
|
||||
'is_abo' => $shopping_instance->shopping_data['is_abo'] ?? false,
|
||||
'is_for' => $shopping_instance->shopping_data['is_for'] ?? false,
|
||||
'backlink' => false,
|
||||
];
|
||||
return $data;
|
||||
}
|
||||
|
||||
public static function getRestoredYardShoppingItems($shopping_instance){
|
||||
|
||||
Yard::instance('shopping')->destroy();
|
||||
Yard::instance('shopping')->restore($shopping_instance->identifier, [], false);
|
||||
Yard::instance('shopping')->putYardExtra('user_shop_payment', $shopping_instance->payment);
|
||||
|
||||
Yard::instance('shopping')->putYardExtra('shopping_data', $shopping_instance->shopping_data);
|
||||
$is_for = isset($shopping_instance->shopping_data['is_for']) ? $shopping_instance->shopping_data['is_for'] : 'ot-member';
|
||||
Yard::instance('shopping')->setUserPriceInfos($shopping_instance->shopping_data['user_price_infos']);
|
||||
Yard::instance('shopping')->setShippingCountryWithPrice($shopping_instance->country_id, $is_for);
|
||||
|
||||
|
||||
$rows = Yard::instance('shopping')->getContentByOrder();
|
||||
$ret = [];
|
||||
$ret['items'] = [];
|
||||
$is_currency = Yard::instance('shopping')->isPriceCurrency();
|
||||
$tax_free = Yard::instance('shopping')->getUserTaxFree();
|
||||
|
||||
foreach($rows as $row){
|
||||
$product = \App\Models\Product::find($row->id);
|
||||
$item = new \stdClass();
|
||||
$item->image = $row->options->has('image') ? $row->options->image : null;
|
||||
$item->price_net = (float) Yard::instance('shopping')->rowPriceNet($row, 3, '.', '');
|
||||
$item->price_net_total = (float) Yard::instance('shopping')->rowSubtotalNet($row, 2, '.', '');
|
||||
$item->price_currency = $is_currency ? "~".Yard::instance('shopping')->getCurrencyByKey('rowPriceNetCurrency', $row, 3)." ".Yard::instance('shopping')->getPriceCurrencyUnit() : null;
|
||||
$item->price_currency_total = $is_currency ? "~".Yard::instance('shopping')->getCurrencyByKey('rowSubtotalCurrency', $row, 3)." ".Yard::instance('shopping')->getPriceCurrencyUnit() : null;
|
||||
$item->price = $row->price;
|
||||
$item->price_total = ($row->qty * $row->price);
|
||||
$item->qty = $row->qty;
|
||||
$item->name = $product->name;
|
||||
$item->contents = $product->contents;
|
||||
$item->numbers = $product->numbers;
|
||||
$item->abo_type = AboHelper::getAboShowOn($product);
|
||||
$item->number = $product->number;
|
||||
$item->contents = $product->contents;
|
||||
$ret['items'][] = $item;
|
||||
}
|
||||
|
||||
$ret['tax_free'] = $tax_free;
|
||||
$ret['total']['subtotal'] = Yard::instance('shopping')->subtotal();
|
||||
$ret['total']['subtotal_currency'] = $is_currency ? "~".Yard::instance('shopping')->getCurrencyByKey('subtotal')." ".Yard::instance('shopping')->getPriceCurrencyUnit() : null;
|
||||
$ret['total']['shippingCountryName'] = Yard::instance('shopping')->getShippingCountryName();
|
||||
$ret['total']['shippingNet'] = Yard::instance('shopping')->shippingNet();
|
||||
$ret['total']['shippingNet currency'] = $is_currency ? "~".Yard::instance('shopping')->getCurrencyByKey('shippingNet')." ".Yard::instance('shopping')->getPriceCurrencyUnit() : null;
|
||||
$ret['total']['subtotalWithShipping'] = Yard::instance('shopping')->subtotalWithShipping();
|
||||
$ret['total']['subtotalWithShipping_currency'] = $is_currency ? "~".Yard::instance('shopping')->getCurrencyByKey('subtotalWithShipping')." ".Yard::instance('shopping')->getPriceCurrencyUnit() : null;
|
||||
$ret['total']['taxWithShipping'] = Yard::instance('shopping')->taxWithShipping();
|
||||
$ret['total']['taxWithShipping_currency'] = $is_currency ? "~".Yard::instance('shopping')->getCurrencyByKey('taxWithShipping')." ".Yard::instance('shopping')->getPriceCurrencyUnit() : null;
|
||||
$ret['total']['totalWithShipping'] = Yard::instance('shopping')->totalWithShipping();
|
||||
$ret['total']['totalWithShipping_currency'] = $is_currency ? "~".Yard::instance('shopping')->getCurrencyByKey('totalWithShipping')." ".Yard::instance('shopping')->getPriceCurrencyUnit() : null;
|
||||
|
||||
return $ret;
|
||||
}
|
||||
|
||||
}
|
||||
300
dev/app-bak/Services/Payment.php
Normal file
300
dev/app-bak/Services/Payment.php
Normal file
|
|
@ -0,0 +1,300 @@
|
|||
<?php
|
||||
namespace App\Services;
|
||||
|
||||
|
||||
use App\User;
|
||||
use App\Models\UserLevel;
|
||||
use App\Mail\MailCheckout;
|
||||
use App\Services\UserUtil;
|
||||
use App\Services\AboHelper;
|
||||
use App\Models\ProductBuying;
|
||||
use App\Models\ShoppingOrder;
|
||||
use App\Models\UserCreditItem;
|
||||
use App\Models\ShoppingPayment;
|
||||
use App\Services\ShopApiOrderCart;
|
||||
use Illuminate\Support\Facades\Mail;
|
||||
use App\Repositories\InvoiceRepository;
|
||||
use App\Services\BusinessPlan\SalesPointsVolume;
|
||||
|
||||
class Payment
|
||||
{
|
||||
|
||||
public static $txaction_text = [
|
||||
'paid' => 'paid',
|
||||
'appointed' => 'open',
|
||||
'failed' => 'failed',
|
||||
'extern' => 'open', //offen
|
||||
'extern_paid' => 'paid',
|
||||
'invoice_open' => 'open',
|
||||
'invoice_paid' => 'paid',
|
||||
'invoice_non' => 'no_payment',
|
||||
'NULL' => 'no_payment',
|
||||
];
|
||||
|
||||
public static $txaction_filter_text = [
|
||||
'paid' => 'paymend_paid',
|
||||
'appointed' => 'paymend_open',
|
||||
'failed' => 'paymend_failed',
|
||||
'extern' => 'extern_open', //offen
|
||||
'extern_paid' => 'extern_paid',
|
||||
'invoice_open' => 'invoice_open',
|
||||
'invoice_paid' => 'invoice_paid',
|
||||
'invoice_non' => 'invoice_no_payment',
|
||||
'NULL' => 'no_payment',
|
||||
];
|
||||
|
||||
public static $txaction_invoice = [
|
||||
'invoice_open' => 'invoice_open',
|
||||
'invoice_paid' => 'invoice_paid',
|
||||
'invoice_non' => 'no_payment',
|
||||
];
|
||||
|
||||
public static $txaction_color = [
|
||||
'paid' => 'success',
|
||||
'appointed' => 'warning',
|
||||
'failed' => 'danger',
|
||||
'extern' => 'warning',
|
||||
'extern_paid' => 'success',
|
||||
'invoice_open' => 'warning',
|
||||
'invoice_paid' => 'success',
|
||||
'invoice_non' => 'failed',
|
||||
];
|
||||
|
||||
|
||||
public static function getFormattedTxaction($txaction){
|
||||
if($txaction && isset(self::$txaction_text[$txaction])){
|
||||
return __('payment.'.self::$txaction_text[$txaction]);
|
||||
}
|
||||
return __('payment.'.self::$txaction_text['NULL']);
|
||||
}
|
||||
|
||||
public static function getFormattedTxactionColor($txaction){
|
||||
if($txaction && isset(self::$txaction_color[$txaction])){
|
||||
return self::$txaction_color[$txaction];
|
||||
}
|
||||
return "warning";
|
||||
}
|
||||
|
||||
public static function getTransTxactionFilterText(){
|
||||
$ret = [];
|
||||
foreach(self::$txaction_filter_text as $key=>$val){
|
||||
$ret[$key] = trans('payment.'.$val);
|
||||
}
|
||||
return $ret;
|
||||
}
|
||||
|
||||
public static function getTransTxactionInvoice(){
|
||||
$ret = [];
|
||||
foreach(self::$txaction_invoice as $key=>$val){
|
||||
$ret[$key] = trans('payment.'.$val);
|
||||
}
|
||||
return $ret;
|
||||
}
|
||||
|
||||
public static function getShoppingOrderBadge(ShoppingOrder $shopping_order){
|
||||
|
||||
if($shopping_order->mode === 'test'){
|
||||
return '<span class="badge badge-pill badge-default">'.strtoupper($shopping_order->mode).' - '.self::getFormattedTxaction($shopping_order->txaction).'</span>';
|
||||
}
|
||||
if($shopping_order->mode === 'dev'){
|
||||
return '<span class="badge badge-pill badge-info">'.strtoupper($shopping_order->mode).' - '.self::getFormattedTxaction($shopping_order->txaction).'</span>';
|
||||
}
|
||||
return '<span class="badge badge-pill badge-'.self::getFormattedTxactionColor($shopping_order->txaction).'">'.self::getFormattedTxaction($shopping_order->txaction).'</span>';
|
||||
}
|
||||
|
||||
public static function getPaymentForBadge(ShoppingOrder $shopping_order){
|
||||
$abo = '';
|
||||
if($shopping_order->is_abo){
|
||||
$abo = ' <span class="badge badge-pill badge-success">'.__('abo.abo').'</span>';
|
||||
}
|
||||
return '<span class="badge badge-pill badge-'.$shopping_order->getPaymentForColor().'">'.$shopping_order->getPaymentForType().'</span>'.$abo;
|
||||
}
|
||||
|
||||
public static function getShoppingPaymentBadge(ShoppingPayment $shopping_payment){
|
||||
if($shopping_payment->mode === 'test'){
|
||||
return '<span class="badge badge-pill badge-default">'.strtoupper($shopping_payment->mode).' - '.self::getFormattedTxaction($shopping_payment->txaction).'</span>';
|
||||
}
|
||||
return '<span class="badge badge-pill badge-'.self::getFormattedTxactionColor($shopping_payment->txaction).'">'.self::getFormattedTxaction($shopping_payment->txaction).'</span>';
|
||||
}
|
||||
|
||||
public static function addUserCreditMargin(User $user, $credit, $status, $message){
|
||||
UserCreditItem::create([
|
||||
'user_id' => $user->id,
|
||||
'credit' => $credit,
|
||||
'message' => $message,
|
||||
'from_month' => date('n'),
|
||||
'from_year' => date('Y'),
|
||||
'status' => $status,
|
||||
]);
|
||||
}
|
||||
|
||||
public static function addBuyingRestriction(User $user, $product_id){
|
||||
ProductBuying::create([
|
||||
'user_id' => $user->id,
|
||||
'product_id' => $product_id,
|
||||
'amount' => 1
|
||||
]);
|
||||
}
|
||||
|
||||
public static function addSponsorBuyingPoints(User $user, $product){
|
||||
|
||||
if($user->user_sponsor){
|
||||
$data = [
|
||||
'user_id' => $user->user_sponsor->id,
|
||||
'total_net' => 0,
|
||||
'points' => $product->sponsor_buying_points_amount,
|
||||
'info' => 'VP: '.$user->getFullName(false).' | '.$product->name,
|
||||
'status_points' => 2,
|
||||
'status' => 5
|
||||
];
|
||||
SalesPointsVolume::addSalesPointsVolume($data);
|
||||
}
|
||||
}
|
||||
|
||||
public static function updateUserLevel(User $user, $to_level_id){
|
||||
//nur updaten, wenn der user->m_level kleiner ist als $to_level_id
|
||||
if($user->user_level){
|
||||
$ToUserLevel = UserLevel::find($to_level_id);
|
||||
if($user->user_level->pos < $ToUserLevel->pos){
|
||||
$user->m_level = $to_level_id;
|
||||
}
|
||||
}else{
|
||||
$user->m_level = $to_level_id;
|
||||
}
|
||||
$user->save();
|
||||
}
|
||||
/*
|
||||
Wir bei Zahlung aufgerufen.
|
||||
Betätigung durch Payone oder Zahlung auf MIVITA Rechnung
|
||||
$paid = Status der Zahlung, Payone = true, MIVITA Rechnung = false damit kann später die rechnung auf bezahlt gesetzt werden.
|
||||
*/
|
||||
|
||||
public static function paymentStatusPaidAction(ShoppingOrder $shopping_order, $paid, $shopping_payment = null){
|
||||
$send_link = false;
|
||||
$shopping_order->setUserHistoryValue(['status' => 8]);
|
||||
ShoppingUserService::snycOrdersByShoppingOrder($shopping_order);
|
||||
$shopping_order->paid = $paid;
|
||||
$shopping_order->save();
|
||||
|
||||
//if product has actions
|
||||
if($shopping_order->shopping_order_items && $shopping_order->auth_user_id){
|
||||
foreach($shopping_order->shopping_order_items as $shopping_order_item){
|
||||
if($shopping_order_item->product){
|
||||
$user = User::findOrFail($shopping_order->auth_user_id);
|
||||
$user->save();
|
||||
if($shopping_order_item->product->buying_restriction){
|
||||
self::addBuyingRestriction($user, $shopping_order_item->product->id);
|
||||
}
|
||||
if($shopping_order_item->product->sponsor_buying_points){
|
||||
self::addSponsorBuyingPoints($user, $shopping_order_item->product);
|
||||
}
|
||||
if($shopping_order_item->product->action){
|
||||
$send_link = true;
|
||||
//new date
|
||||
$date = \Carbon::now()->modify('1 year');
|
||||
if($user->payment_account && $user->daysActiveAccount()>0){
|
||||
$date = \Carbon::parse($user->payment_account)->modify('1 year');
|
||||
}
|
||||
foreach ($shopping_order_item->product->action as $do){
|
||||
if($shopping_order_item->product->getActionName($do) === 'payment_for_account'){
|
||||
$user->payment_order_id = $shopping_order_item->product->id; //34
|
||||
$user->payment_account = $date;
|
||||
$user->wizard = 100;
|
||||
//only date is > now and acount is deactive.
|
||||
if($date > \Carbon::now()){
|
||||
if($user->active === 0){
|
||||
$user->active = true;
|
||||
UserUtil::reactiveUserResetChilds($user->id, 'on payment_for_account Payment');
|
||||
}
|
||||
}
|
||||
|
||||
$shopping_order->setUserHistoryValue(['status' => 9]);
|
||||
}
|
||||
if($shopping_order_item->product->getActionName($do) === 'payment_for_shop'){
|
||||
$user->payment_order_id = $shopping_order_item->product->id; //35
|
||||
$user->payment_shop = $date;
|
||||
$user->wizard = 100;
|
||||
$shopping_order->setUserHistoryValue(['status' => 9]);
|
||||
}
|
||||
if($shopping_order_item->product->getActionName($do) === 'payment_for_shop_upgrade'){
|
||||
if($shopping_order_item->product->upgrade_to_id){
|
||||
$user->payment_order_id = $shopping_order_item->product->upgrade_to_id;
|
||||
}
|
||||
$user->payment_shop = $user->payment_account; //same Date, is upgrade
|
||||
$shopping_order->setUserHistoryValue(['status' => 9]);
|
||||
}
|
||||
if($shopping_order_item->product->getActionName($do) === 'payment_for_lead_upgrade'){
|
||||
if($shopping_order_item->product->upgrade_to_id){
|
||||
self::updateUserLevel($user, $shopping_order_item->product->upgrade_to_id);
|
||||
}
|
||||
}
|
||||
$user->save();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
if($shopping_order->homeparty){
|
||||
$shopping_order->setUserHistoryValue(['status' => 9]);
|
||||
$shopping_order->homeparty->completed = 1;
|
||||
$shopping_order->homeparty->save();
|
||||
}
|
||||
|
||||
if($shopping_order->shopping_collect_order){
|
||||
$shopping_order->setUserHistoryValue(['status' => 9]);
|
||||
ShopApiOrderCart::finishOrder($shopping_order->shopping_collect_order);
|
||||
}
|
||||
//the Order is Pay, so we can set the Status in the Abo
|
||||
if($shopping_order->is_abo){
|
||||
if($shopping_payment){
|
||||
Util::setInstanceStatusByPayment($shopping_payment, 10); //link_paid
|
||||
$shopping_payment->identifier = null;
|
||||
$shopping_payment->save();
|
||||
}
|
||||
AboHelper::setAboActive($shopping_order, 2);
|
||||
}
|
||||
|
||||
//make Invoice is not exist and is live
|
||||
if($shopping_order->mode === 'live'){
|
||||
$invoice_repo = new InvoiceRepository($shopping_order);
|
||||
if(!$shopping_order->isInvoice()){
|
||||
$invoice_repo->createAndSalesVolume();
|
||||
}
|
||||
}
|
||||
|
||||
return $send_link;
|
||||
}
|
||||
|
||||
public static function paymentStatusSendMail(ShoppingOrder $shopping_order, $shopping_payment, $data){
|
||||
$bcc = [];
|
||||
$billing_email = $shopping_order->shopping_user->billing_email;
|
||||
|
||||
// Überprüfung der Billing-E-Mail-Adresse
|
||||
|
||||
if(!$billing_email){
|
||||
if($data['mode'] === 'test'){
|
||||
$billing_email = config('app.checkout_test_mail');
|
||||
}else{
|
||||
$billing_email = config('app.checkout_mail');
|
||||
}
|
||||
}
|
||||
if(!filter_var($billing_email, FILTER_VALIDATE_EMAIL)){
|
||||
\Log::channel('payment')->error("Invalid billing email at shopping_order ".$shopping_order->id, ['billing_email' => $billing_email]);
|
||||
$billing_email = config('app.checkout_mail');
|
||||
}
|
||||
|
||||
if($data['mode'] === 'test'){
|
||||
$bcc[] = config('app.checkout_test_mail');
|
||||
}else{
|
||||
$bcc[] = config('app.checkout_mail');
|
||||
}
|
||||
|
||||
if(!$shopping_order->shopping_user->is_like && $shopping_order->shopping_user->member){
|
||||
$bcc[] = $shopping_order->shopping_user->member->email;
|
||||
}
|
||||
$data['payment_error'] = isset($data['payment_error']) ? $data['payment_error'] : false;
|
||||
Mail::to($billing_email)->bcc($bcc)->locale($shopping_order->getLocale())->send(new MailCheckout($data['txaction'], $shopping_order, $shopping_payment, $data['send_link'], $data['mode'], $data['payment_error']));
|
||||
}
|
||||
}
|
||||
170
dev/app-bak/Services/PaymentHelper.php
Normal file
170
dev/app-bak/Services/PaymentHelper.php
Normal file
|
|
@ -0,0 +1,170 @@
|
|||
<?php
|
||||
namespace App\Services;
|
||||
|
||||
use Yard;
|
||||
use App\User;
|
||||
use App\Models\UserHistory;
|
||||
use App\Models\ShoppingUser;
|
||||
use App\Models\ShoppingOrder;
|
||||
use App\Models\ShoppingOrderItem;
|
||||
use App\Models\PaymentTransaction;
|
||||
use App\Http\Controllers\Pay\PayoneController;
|
||||
|
||||
class PaymentHelper
|
||||
{
|
||||
|
||||
|
||||
|
||||
public function setProduct($product){
|
||||
Yard::instance('shopping')->destroy();
|
||||
Yard::instance('shopping')->add($product->id, $product->getLang('name'), 1, $product->price, false, false, ['image' => "", 'slug' => $product->slug, 'weight' => $product->weight, 'points' => $product->points, 'no_commission' => $product->no_commission, 'show_on' => $product->show_on]);
|
||||
}
|
||||
|
||||
public function initELVPayment($user){
|
||||
|
||||
$shopping_user = $this->makeShoppingUser($user);
|
||||
$shopping_order = $this->makeShoppingOrder($user, $shopping_user);
|
||||
|
||||
|
||||
$pay = new PayoneController();
|
||||
$pay->init($shopping_user, $shopping_order);
|
||||
$amount = Yard::instance('shopping')->totalWithShipping(2, '.', '') * 100;
|
||||
|
||||
$payment_method = 'elv';
|
||||
$ret['elv']['mandate_identification'] = isset($user->account->payment_data['mandate_identification']) ? $user->account->payment_data['mandate_identification'] : "";
|
||||
$ret['elv']['creditor_identifier'] = isset($user->account->payment_data['creditor_identifier']) ? $user->account->payment_data['creditor_identifier'] : "";
|
||||
$ret['elv']['iban'] = isset($user->account->payment_data['iban']) ? $user->account->payment_data['iban'] : "";
|
||||
$ret['elv']['bic'] = isset($user->account->payment_data['bic']) ? $user->account->payment_data['bic'] : "";
|
||||
$ret['elv']['bankaccountholder'] = isset($user->account->payment_data['bankaccountholder']) ? $user->account->payment_data['bankaccountholder'] : "";
|
||||
$reference = $pay->setPrePayment($payment_method, $amount, 'EUR', $ret);
|
||||
|
||||
$pay->setPersonalData();
|
||||
$response = $pay->onlyPaymentResponse();
|
||||
$shopping_payment = $pay->getShoppingPayment();
|
||||
if($response['status'] === 'ERROR'){
|
||||
$payT = PaymentTransaction::create([
|
||||
'shopping_payment_id' => $shopping_payment->id,
|
||||
'request' => 'authorization',
|
||||
'errorcode' => $response['errorcode'],
|
||||
'errormessage' => $response['errormessage'],
|
||||
'customermessage' => $response['customermessage'],
|
||||
'status' => $response['status'],
|
||||
'mode' => $shopping_payment->mode,
|
||||
]);
|
||||
UserHistory::create(['user_id'=>$user->id, 'shopping_order_id'=>$shopping_order->id, 'action'=>'abo_open_payment', 'referenz'=>$payT->id, 'identifier'=>$user->payment_account, 'status'=>3]);
|
||||
}
|
||||
if($response['status'] === 'REDIRECT'){
|
||||
$payT = PaymentTransaction::create([
|
||||
'shopping_payment_id' => $shopping_payment->id,
|
||||
'request' => 'authorization',
|
||||
'txid' => $response['txid'],
|
||||
'userid' => $response['userid'],
|
||||
'status' => $response['status'],
|
||||
'mode' => $shopping_payment->mode,
|
||||
|
||||
]);
|
||||
UserHistory::create(['user_id'=>$user->id, 'shopping_order_id'=>$shopping_order->id, 'action'=>'abo_open_payment', 'referenz'=>$payT->id, 'identifier'=>$user->payment_account, 'status'=>4]);
|
||||
}
|
||||
if($response['status'] === 'APPROVED'){
|
||||
$payT = PaymentTransaction::create([
|
||||
'shopping_payment_id' => $shopping_payment->id,
|
||||
'request' => 'authorization',
|
||||
'txid' => $response['txid'],
|
||||
'userid' => $response['userid'],
|
||||
'status' => $response['status'],
|
||||
'transmitted_data' => $response,
|
||||
'mode' => $shopping_payment->mode
|
||||
]);
|
||||
UserHistory::create(['user_id'=>$user->id, 'shopping_order_id'=>$shopping_order->id, 'action'=>'abo_open_payment', 'referenz'=>$payT->id, 'identifier'=>$user->payment_account, 'status'=>5]);
|
||||
}
|
||||
}
|
||||
|
||||
public function makeShoppingUser($user, $is_from = 'membership', $is_for = 'me'){
|
||||
$shopping_user = new ShoppingUser();
|
||||
$shopping_user->auth_user_id = $user->id;
|
||||
$shopping_user->mode = 'prev';
|
||||
$shopping_user->language = $user->getLocale();
|
||||
$shopping_user->billing_salutation = $user->account->salutation;
|
||||
$shopping_user->billing_company = $user->account->company;
|
||||
$shopping_user->billing_firstname = $user->account->first_name;
|
||||
$shopping_user->billing_lastname = $user->account->last_name;
|
||||
$shopping_user->billing_address = $user->account->address;
|
||||
$shopping_user->billing_address_2 = $user->account->address_2;
|
||||
$shopping_user->billing_zipcode = $user->account->zipcode;
|
||||
$shopping_user->billing_city = $user->account->city;
|
||||
$shopping_user->billing_country_id = $user->account->country_id;
|
||||
$shopping_user->billing_phone = $user->account->phone;
|
||||
$shopping_user->billing_email = $user->email;
|
||||
$shopping_user->faker_mail = false;
|
||||
$shopping_user->shipping_email = $user->email;
|
||||
$shopping_user->accepted_data_checkbox = 1;
|
||||
$shopping_user->is_for = $is_for;
|
||||
$shopping_user->is_from = $is_from;
|
||||
$shopping_user->homeparty_id = null;
|
||||
$shopping_user->same_as_billing = $user->account->same_as_billing ? false : true;
|
||||
$shopping_user->shipping_salutation = $user->account->shipping_salutation;
|
||||
$shopping_user->shipping_company = $user->account->shipping_company;
|
||||
$shopping_user->shipping_firstname = $user->account->shipping_firstname;
|
||||
$shopping_user->shipping_lastname = $user->account->shipping_lastname;
|
||||
$shopping_user->shipping_address = $user->account->shipping_address;
|
||||
$shopping_user->shipping_address_2 = $user->account->shipping_address_2;
|
||||
$shopping_user->shipping_zipcode = $user->account->shipping_zipcode;
|
||||
$shopping_user->shipping_city = $user->account->shipping_city;
|
||||
$shopping_user->shipping_country_id = $user->account->shipping_country_id;
|
||||
$shopping_user->shipping_phone = $user->account->shipping_phone;
|
||||
$shopping_user->save();
|
||||
return $shopping_user;
|
||||
}
|
||||
|
||||
public function makeShoppingOrder($user, $shopping_user){
|
||||
|
||||
$data = [
|
||||
'shopping_user_id' => $shopping_user->id,
|
||||
'auth_user_id' => $shopping_user->auth_user_id,
|
||||
'country_id' => Yard::instance('shopping')->getShippingCountryId(),
|
||||
'language' => \App::getLocale(),
|
||||
'user_shop_id' => 1,
|
||||
'payment_for' => $shopping_user->getOrderPaymentFor(),
|
||||
'total' => Yard::instance('shopping')->total(2, '.', ''),
|
||||
'subtotal' => Yard::instance('shopping')->subtotal(2, '.', ''),
|
||||
'shipping' => Yard::instance('shopping')->shipping(2, '.', ','),
|
||||
'shipping_net' => Yard::instance('shopping')->shippingNet(2, '.', ''),
|
||||
'subtotal_ws' => Yard::instance('shopping')->subtotalWithShipping(2, '.', ''),
|
||||
'tax' => Yard::instance('shopping')->taxWithShipping(2, '.', ''),
|
||||
'total_shipping' => Yard::instance('shopping')->totalWithShipping(2, '.', ''),
|
||||
'points' => Yard::instance('shopping')->points(),
|
||||
'weight' => Yard::instance('shopping')->weight(),
|
||||
'txaction' => 'prev',
|
||||
'mode' => $user->test_mode ? 'test' : 'live',
|
||||
];
|
||||
|
||||
$shopping_order = ShoppingOrder::create($data);
|
||||
$items = Yard::instance('shopping')->getContentByOrder();
|
||||
foreach ($items as $item) {
|
||||
if (!ShoppingOrderItem::where('shopping_order_id', $shopping_order->id)->where('row_id', $item->rowId)->count()){
|
||||
$price_net = Yard::instance('shopping')->rowPriceNet($item, 2, '.', '');
|
||||
$tax = $item->price - $price_net;
|
||||
$data = [
|
||||
'shopping_order_id' => $shopping_order->id,
|
||||
'row_id' => $item->rowId,
|
||||
'product_id' => $item->id,
|
||||
'comp' => $item->options->comp,
|
||||
'qty' => $item->qty,
|
||||
'price' => $item->price,
|
||||
'price_net' => $price_net,
|
||||
'tax_rate' => $item->taxRate,
|
||||
'tax' => $tax,
|
||||
'price_vk_net' => $shopping_order->getPriceVkNetBy($item->id),
|
||||
'discount' => $item->options->no_commission ? 0 : $shopping_order->getUserDiscount(),
|
||||
'points' => $item->options->points,
|
||||
'slug' => $item->options->slug
|
||||
];
|
||||
$shopping_order_item = ShoppingOrderItem::create($data);
|
||||
}
|
||||
}
|
||||
$shopping_order->makeTaxSplit();
|
||||
return $shopping_order;
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
173
dev/app-bak/Services/Payone.php
Normal file
173
dev/app-bak/Services/Payone.php
Normal file
|
|
@ -0,0 +1,173 @@
|
|||
<?php
|
||||
/**
|
||||
* This class is a wrapper to be able to send arrays of Payone request
|
||||
* to the Payone platform.
|
||||
*
|
||||
* Payone Connector is free software: you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation, either version 3 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* Payone Connector is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with Payone Connector. If not, see <http://www.gnu.org/licenses/>.
|
||||
*
|
||||
* @package Simple PHP Integration
|
||||
* @link https://www.bspayone.com/
|
||||
* @copyright (C) BS PAYONE GmbH 2016, 2018
|
||||
* @author Florian Bender <florian.bender@bspayone.com>
|
||||
* @author Timo Kuchel <timo.kuchel@bspayone.com>
|
||||
* @author Hannes Reinberger <hannes.reinberger@bspayone.com>
|
||||
*/
|
||||
|
||||
namespace App\Services;
|
||||
|
||||
|
||||
//require 'vendor/autoload.php';
|
||||
use Exception;
|
||||
|
||||
use GuzzleHttp\Client;
|
||||
use Psr\Http\Message\ResponseInterface;
|
||||
|
||||
/**
|
||||
* Class Payone
|
||||
*/
|
||||
class Payone {
|
||||
|
||||
/**
|
||||
* The URL of the Payone API
|
||||
*/
|
||||
const PAYONE_SERVER_API_URL = 'https://api.pay1.de/post-gateway/';
|
||||
const PAYONE_CLIENT_API_URL = 'https://secure.pay1.de/client-api/';
|
||||
|
||||
/**
|
||||
* performing the HTTP POST request to the PAYONE platform
|
||||
*
|
||||
* @param array $request
|
||||
* @param string $responsetype
|
||||
* @throws Exception
|
||||
* @return array|\Psr\Http\Message\StreamInterface Returns an array of response
|
||||
* parameters in "classic" mode, a Stream for any other mode.
|
||||
*/
|
||||
public static function sendRequest($request, $responsetype = "")
|
||||
{
|
||||
if ($responsetype === "json") {
|
||||
// appends the accept: application/json header to the request
|
||||
// This is used to retrieve structured JSON in the response
|
||||
// $client = new Client(['headers' => ['accept' => 'application/json', 'content-type' => 'text/plain;charset=UTF-8']]);
|
||||
$client = new Client(['headers' => ['accept' => 'application/json']]);
|
||||
|
||||
}
|
||||
else {
|
||||
// if $responsetype is set to anything else than "json", use the standard request
|
||||
// $client = new Client(['headers' => ['content-type' => 'text/plain;charset=UTF-8']]);
|
||||
$client = new Client();
|
||||
}
|
||||
|
||||
// echo "Requesting...";
|
||||
$begin = microtime(true);
|
||||
try {
|
||||
$response = $client->request('POST', self::PAYONE_SERVER_API_URL, ['form_params' => $request]);
|
||||
}
|
||||
catch (\GuzzleHttp\Exception\ClientException $e) {
|
||||
$error = $e->getResponse();
|
||||
$responseBodyAsString = $error->getBody()->getContents();
|
||||
MyLog::writeLog(
|
||||
'payone',
|
||||
'error',
|
||||
'Error:1002 Der Zahlungsanbieter ist nicht erreichbar, die Zahlung konnte nicht durchgeführt werden. App\Services\Payone::sendRequest Something went wrong during the HTTP request.',
|
||||
['error' => $error, 'responseBodyAsString' => $responseBodyAsString, 'request' => $request]
|
||||
);
|
||||
abort(403, 'Der Zahlungsanbieter ist nicht erreichbar, die Zahlung konnte nicht durchgeführt werden. Bitte versuchen Sie es später erneut. Fehlercode: 1002');
|
||||
|
||||
}
|
||||
if (isset($response)) {
|
||||
if (implode($response->getHeader('Content-Type')) == 'text/plain;charset=UTF-8'){
|
||||
// if the content type is text/plain, parse response into array
|
||||
$return = self::parseResponse($response);
|
||||
// \Log::channel('payone')->error('App\Services\Payone::sendRequest content type is text/plain: '.$response);
|
||||
|
||||
} else {
|
||||
// if the content type is anything else, just return the response body
|
||||
$return = json_decode($response->getBody(),true);
|
||||
MyLog::writeLog(
|
||||
'payone',
|
||||
'error',
|
||||
'Error: App\Services\Payone::sendRequest content type is anything else',
|
||||
['error' => $return, 'response' => $response, 'request' => $request]
|
||||
);
|
||||
}
|
||||
|
||||
} else {
|
||||
MyLog::writeLog(
|
||||
'payone',
|
||||
'error',
|
||||
'Error: App\Services\Payone::sendRequest Something went wrong during the HTTP request',
|
||||
['request' => $request]
|
||||
);
|
||||
throw new Exception('Something went wrong during the HTTP request.');
|
||||
}
|
||||
|
||||
$end = microtime(true);
|
||||
$duration = $end - $begin;
|
||||
if(!is_array($return)){
|
||||
MyLog::writeLog(
|
||||
'payone',
|
||||
'error',
|
||||
'Error: 1003 App\Http\Controllers\Pay\PayoneController::ResponseData response is non array: return:',
|
||||
['return'=>$return, 'response' => $response, 'request' => $request]
|
||||
);
|
||||
abort(403, 'Der Zahlungsanbieter ist nicht erreichbar, die Zahlung konnte nicht durchgeführt werden. Bitte versuchen Sie es später erneut. Fehlercode: 1003');
|
||||
}
|
||||
|
||||
if(!isset($return['status'])){
|
||||
MyLog::writeLog(
|
||||
'payone',
|
||||
'error',
|
||||
'Error: 1004 App\Http\Controllers\Pay\PayoneController::ResponseData response has non status',
|
||||
['return'=>$return, 'response' => $response, 'request' => $request]
|
||||
);
|
||||
abort(403, 'Der Zahlungsanbieter ist nicht erreichbar, die Zahlung konnte nicht durchgeführt werden. Bitte versuchen Sie es später erneut. Fehlercode: 1004');
|
||||
}
|
||||
/* echo "done.\n";
|
||||
echo "Request took " . $duration . " seconds.\n";
|
||||
echo "<br>";
|
||||
*/
|
||||
return $return;
|
||||
}
|
||||
|
||||
/**
|
||||
* gets response string an puts it into an array
|
||||
*
|
||||
* @param \Psr\Http\Message\ResponseInterface $response
|
||||
* @throws Exception
|
||||
* @return array
|
||||
*/
|
||||
public static function parseResponse(ResponseInterface $response)
|
||||
{
|
||||
$responseArray = array();
|
||||
$explode = explode("\n", $response->getBody());
|
||||
foreach ($explode as $e) {
|
||||
$keyValue = explode("=", $e);
|
||||
if (trim($keyValue[0]) != "") {
|
||||
if (count($keyValue) == 2) {
|
||||
$responseArray[$keyValue[0]] = trim($keyValue[1]);
|
||||
} else {
|
||||
$key = $keyValue[0];
|
||||
unset($keyValue[0]);
|
||||
$value = implode("=", $keyValue);
|
||||
$responseArray[$key] = $value;
|
||||
}
|
||||
}
|
||||
}
|
||||
/*if ($responseArray['status'] == "ERROR") {
|
||||
$msg = "Payone returned an error:\n" . print_r($responseArray, true);
|
||||
throw new Exception($msg);
|
||||
}*/
|
||||
return $responseArray;
|
||||
}
|
||||
}
|
||||
80
dev/app-bak/Services/SessionCleaner.php
Normal file
80
dev/app-bak/Services/SessionCleaner.php
Normal file
|
|
@ -0,0 +1,80 @@
|
|||
<?php
|
||||
|
||||
namespace App\Services;
|
||||
|
||||
use Illuminate\Support\Facades\Log;
|
||||
use Illuminate\Support\Facades\Session;
|
||||
|
||||
/**
|
||||
* Zentrale Session-Bereinigung
|
||||
*
|
||||
* Verhindert Error-Message-Persistierung durch intelligente Session-Bereinigung
|
||||
* vor dem Speichern. Wird von allen Controllern und Services verwendet.
|
||||
*/
|
||||
class SessionCleaner
|
||||
{
|
||||
/**
|
||||
* Session bereinigen und speichern (verhindert Error-Persistierung)
|
||||
*/
|
||||
public static function cleanAndSave(string $context = 'unknown'): void
|
||||
{
|
||||
Log::info("SessionCleaner: Session cleanup - $context", [
|
||||
'session_id' => Session::getId(),
|
||||
'context' => $context
|
||||
]);
|
||||
|
||||
// Error-Bags bereinigen
|
||||
if (Session::has('errors')) {
|
||||
Session::forget('errors');
|
||||
}
|
||||
|
||||
// Alte Input-Daten bereinigen
|
||||
if (Session::has('_old_input')) {
|
||||
Session::forget('_old_input');
|
||||
}
|
||||
|
||||
// Session speichern
|
||||
try {
|
||||
Session::save();
|
||||
Log::info("SessionCleaner: Session cleaned and saved - $context", [
|
||||
'session_id' => Session::getId()
|
||||
]);
|
||||
} catch (\Throwable $e) {
|
||||
Log::error("SessionCleaner: Session save failed - $context", [
|
||||
'error' => $e->getMessage(),
|
||||
'session_id' => Session::getId()
|
||||
]);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Nur Error-Messages bereinigen (ohne Session zu speichern)
|
||||
*/
|
||||
public static function cleanErrors(): void
|
||||
{
|
||||
// Error-Bags bereinigen
|
||||
if (Session::has('errors')) {
|
||||
Session::forget('errors');
|
||||
}
|
||||
|
||||
// Alte Input-Daten bereinigen
|
||||
if (Session::has('_old_input')) {
|
||||
Session::forget('_old_input');
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Session nur speichern (ohne Bereinigung)
|
||||
*/
|
||||
public static function saveOnly(): void
|
||||
{
|
||||
try {
|
||||
Session::save();
|
||||
} catch (\Throwable $e) {
|
||||
Log::error("SessionCleaner: Session save failed", [
|
||||
'error' => $e->getMessage(),
|
||||
'session_id' => Session::getId()
|
||||
]);
|
||||
}
|
||||
}
|
||||
}
|
||||
479
dev/app-bak/Services/Shop.php
Normal file
479
dev/app-bak/Services/Shop.php
Normal file
|
|
@ -0,0 +1,479 @@
|
|||
<?php
|
||||
|
||||
namespace App\Services;
|
||||
|
||||
|
||||
use App\Models\Country;
|
||||
use App\Models\Product;
|
||||
use App\Models\Setting;
|
||||
use App\Models\ShippingCountry;
|
||||
use App\Models\ShoppingInstance;
|
||||
use App\Models\ShoppingUser;
|
||||
use App\Services\dbip\MyDBIP;
|
||||
use App\Services\IPinfo\IPinfo;
|
||||
use App\User;
|
||||
use Yard;
|
||||
|
||||
class Shop
|
||||
{
|
||||
public static $user_country;
|
||||
public static $shipping_country;
|
||||
public static $user_tax_free;
|
||||
public static $shipping_free;
|
||||
public static $user_reverse_charge = false;
|
||||
|
||||
|
||||
public static function newUserOrder($number)
|
||||
{
|
||||
ShoppingUserService::snycOrdersByNumber($number);
|
||||
}
|
||||
|
||||
public static function getShippingCountryCountryId($shipping_country_id)
|
||||
{
|
||||
$shippingCountry = ShippingCountry::find($shipping_country_id);
|
||||
if ($shippingCountry && $shippingCountry->country) {
|
||||
return $shippingCountry->country->id;
|
||||
}
|
||||
return 1; //default DE
|
||||
}
|
||||
|
||||
public static function getCountryShippingCountryId($country_id)
|
||||
{
|
||||
$shippingCountry = ShippingCountry::whereCountryId($country_id)->first();
|
||||
if ($shippingCountry) {
|
||||
return $shippingCountry->id;
|
||||
}
|
||||
return ShippingCountry::all()->first()->id;
|
||||
}
|
||||
|
||||
|
||||
public static function getLangChange($instance = 'shopping')
|
||||
{
|
||||
$ret = [];
|
||||
$countries = Country::whereActive(true)->whereSwitch(true)->get();
|
||||
$first_country = null;
|
||||
foreach ($countries as $country) {
|
||||
$ShippingCountry = ShippingCountry::whereCountryId($country->id)->first();
|
||||
if ($ShippingCountry && $ShippingCountry->shipping && $ShippingCountry->shipping->active) {
|
||||
if (!$first_country) {
|
||||
$first_country = $country;
|
||||
}
|
||||
$ret[strtolower($country->code)] = $country;
|
||||
}
|
||||
}
|
||||
Shop::getUserShopLang($first_country, $instance);
|
||||
return $ret;
|
||||
}
|
||||
|
||||
public static function getUserShopLang($country = null, $instance = 'shopping')
|
||||
{
|
||||
// Session-Wert prüfen (wenn bereits gesetzt, verwenden)
|
||||
if (\Session::has('user_shop_lang')) {
|
||||
if ($user_shop_lang = \Session::get('user_shop_lang')) {
|
||||
\Log::info('getUserShopLang - Using existing session', ['user_shop_lang' => $user_shop_lang]);
|
||||
return $user_shop_lang;
|
||||
}
|
||||
}
|
||||
|
||||
// Nur wenn KEIN Session-Wert vorhanden UND Country gegeben
|
||||
if ($country) {
|
||||
\Log::info('getUserShopLang - No session found, initializing with country', ['country' => $country->code]);
|
||||
Shop::initUserShopLang($country, $instance);
|
||||
return strtolower($country->code);
|
||||
}
|
||||
|
||||
\Log::warning('getUserShopLang - No language available', [
|
||||
'has_session' => \Session::has('user_shop_lang'),
|
||||
'country_provided' => $country !== null
|
||||
]);
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
//init User Shop Lang for Webshop
|
||||
public static function initUserShopLang($country, $instance = 'shopping')
|
||||
{
|
||||
\Log::info('initUserShopLang', ['country' => $country]);
|
||||
$newLangCode = strtolower($country->code);
|
||||
// Anti-Duplikate: Session nur schreiben wenn Value sich geändert hat
|
||||
$currentLangCode = \Session::get('user_shop_lang');
|
||||
$sessionNeedsUpdate = ($currentLangCode !== $newLangCode);
|
||||
|
||||
// Das Warenkorb-System braucht die korrekte Länder/Steuer-Konfiguration
|
||||
Yard::instance($instance)->destroy();
|
||||
self::initUserShopYard($country, $instance);
|
||||
|
||||
// Session nur updaten wenn nötig (Anti-Duplikate)
|
||||
if ($sessionNeedsUpdate) {
|
||||
\Session::put('user_shop_lang', $newLangCode);
|
||||
\Log::info('initUserShopLang - Session updated', ['newLangCode' => $newLangCode, 'currentLangCode' => $currentLangCode]);
|
||||
} else {
|
||||
\Log::info('initUserShopLang - Session unchanged but Yard reinitialized', ['langCode' => $newLangCode]);
|
||||
}
|
||||
}
|
||||
|
||||
//init Yard for user shop Webshop
|
||||
public static function initUserShopYard($country, $instance = 'shopping')
|
||||
{
|
||||
\Log::info('initUserShopYard', ['country' => $country]);
|
||||
//Lieferadresse im Drittland?
|
||||
self::$user_tax_free = $country->supply_country ? true : false;
|
||||
$ShippingCountry = ShippingCountry::whereCountryId($country->id)->first();
|
||||
self::$shipping_free = $ShippingCountry->shipping->free;
|
||||
self::$shipping_country = $ShippingCountry;
|
||||
self::$user_country = $country;
|
||||
|
||||
Yard::instance($instance)->setShippingCountryWithPrice($ShippingCountry->id);
|
||||
Yard::instance($instance)->setUserPriceInfos(Shop::getShopYardInfo());
|
||||
\App\Services\SessionCleaner::cleanAndSave('Shop::initUserShopYard');
|
||||
}
|
||||
|
||||
|
||||
public static function getShopYardInfo()
|
||||
{
|
||||
return [
|
||||
'user_tax_free' => self::$user_tax_free,
|
||||
'shipping_free' => self::$shipping_free,
|
||||
'user_reverse_charge' => self::$user_reverse_charge,
|
||||
'user_country_id' => self::$user_country->id,
|
||||
'shipping_country_id' => self::$shipping_country->id,
|
||||
];
|
||||
}
|
||||
|
||||
public static function checkShoppingUser($id, $user)
|
||||
{
|
||||
if ($id === null) {
|
||||
abort(403, 'Error: Keine User ID');
|
||||
}
|
||||
$shopping_user = ShoppingUser::findOrFail($id);
|
||||
if ($shopping_user->member_id !== $user->id) {
|
||||
abort(403, 'Error: Falsche User ID');
|
||||
}
|
||||
$shopping_user = ShoppingUser::findOrFail($id);
|
||||
if ($shopping_user->is_like) {
|
||||
abort(403, 'Error: Kunde in Prüfung');
|
||||
}
|
||||
return $shopping_user;
|
||||
}
|
||||
|
||||
//prüfe ob checkout bereits gestartet wurde, und wenn ja, dann lösche die Instanz
|
||||
public static function deleteCheckoutInstance()
|
||||
{
|
||||
|
||||
|
||||
if (Yard::instance('checkout')->count() > 0) {
|
||||
Yard::instance('checkout')->destroy();
|
||||
}
|
||||
if (\Session::has('user_shop_identifier')) {
|
||||
ShoppingInstance::where('identifier', \Session::get('user_shop_identifier'))->delete();
|
||||
\Session::forget('user_shop_identifier');
|
||||
}
|
||||
\Session::forget('user_shop_payment');
|
||||
\Session::forget('auth_user');
|
||||
\Session::forget('back_link');
|
||||
\Session::forget('new_session');
|
||||
\App\Services\SessionCleaner::cleanAndSave('Shop::deleteCheckoutInstance');
|
||||
}
|
||||
|
||||
public static function checkShoppingCountry($for, $id = null)
|
||||
{
|
||||
$country_id = null;
|
||||
if ($for === 'me' || $for === 'abo-me') {
|
||||
$user = User::find(\Auth::user()->id);
|
||||
if ($user->account->same_as_billing) {
|
||||
$country_id = $user->account->country_id;
|
||||
} else {
|
||||
$country_id = $user->account->shipping_country_id;
|
||||
}
|
||||
}
|
||||
if (strpos($for, 'ot') !== false && $id) {
|
||||
$shopping_user = ShoppingUser::findOrFail($id);
|
||||
if ($shopping_user->same_as_billing) {
|
||||
$country_id = $shopping_user->billing_country->id;
|
||||
} else {
|
||||
$country_id = $shopping_user->shipping_country->id;
|
||||
}
|
||||
}
|
||||
if ($country_id) {
|
||||
if ($shipping_country = ShippingCountry::whereCountryId($country_id)->first()) {
|
||||
if ($shipping_country->shipping && $shipping_country->shipping->active) {
|
||||
return $shipping_country->id;
|
||||
}
|
||||
}
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
public static function getDeliveryCountry($for, $id = null)
|
||||
{
|
||||
$country_id = null;
|
||||
if ($for === 'me' || $for === 'abo-me') {
|
||||
$user = User::find(\Auth::user()->id);
|
||||
if ($user->account->same_as_billing) {
|
||||
return $user->account->country ? $user->account->country->getLocated() : '';
|
||||
} else {
|
||||
return $user->account->shipping_country ? $user->account->shipping_country->getLocated() : '';
|
||||
}
|
||||
}
|
||||
if (strpos($for, 'ot') !== false && $id) {
|
||||
$shopping_user = ShoppingUser::findOrFail($id);
|
||||
if ($shopping_user->same_as_billing) {
|
||||
return $shopping_user->billing_country ? $shopping_user->billing_country->getLocated() : '';
|
||||
} else {
|
||||
return $shopping_user->shipping_country ? $shopping_user->shipping_country->getLocated() : '';
|
||||
}
|
||||
}
|
||||
return '';
|
||||
}
|
||||
|
||||
|
||||
public static function getShippingPriceByShippingCountryId($shipping_country_id, $shipping_weight)
|
||||
{
|
||||
$shippingCountry = ShippingCountry::find($shipping_country_id);
|
||||
if (!$shippingCountry) {
|
||||
abort(403, 'Fehler: Versandland nicht gefunden');
|
||||
}
|
||||
if (!isset($shippingCountry->shipping) && count($shippingCountry->shipping->shipping_prices) === 0) {
|
||||
abort(403, 'Fehler: Kein Preise für das Versandland angelegt');
|
||||
}
|
||||
$shipping_price = $shippingCountry->shipping->shipping_prices->first();
|
||||
if (!$shipping_price) {
|
||||
abort(403, 'Fehler: Preis vom Versandland nicht gefunden');
|
||||
}
|
||||
|
||||
/*if(!$shipping_weight){
|
||||
abort(403, 'Fehler: Kein Versandgewicht');
|
||||
}*/
|
||||
|
||||
if ($shipping_weight == 0) {
|
||||
$shipping_price->price = 0;
|
||||
$shipping_price->price_comp = 0;
|
||||
return $shipping_price;
|
||||
}
|
||||
|
||||
if ($shipping_weight > 0) {
|
||||
/*
|
||||
if($this->shipping_free && $this->total(2, '.', '') >= $this->shipping_free){
|
||||
if($this->weightByFreeShipping() == 0){
|
||||
$shipping_price->price = 0;
|
||||
$shipping_price->price_comp = 0;
|
||||
}else{
|
||||
$shipping_price = $this->shippingPriceByWeight($shipping->shipping_prices, $this->weightByFreeShipping());
|
||||
}
|
||||
|
||||
}else{
|
||||
*/
|
||||
|
||||
return self::shippingPriceByWeight($shippingCountry->shipping->shipping_prices, $shipping_weight);
|
||||
}
|
||||
/*if($this->weight() == 0){
|
||||
|
||||
}else{
|
||||
|
||||
$shipping_price = $this->shippingPriceByWeight($shipping->shipping_prices, $this->weight());
|
||||
//first by price
|
||||
//$shipping_price = $this->shippingPriceByTotal($shipping->shipping_prices, $this->total(2, '.', ''));
|
||||
//sec by weight
|
||||
//if(!$shipping_price){
|
||||
//}
|
||||
}
|
||||
//default
|
||||
|
||||
}*/
|
||||
}
|
||||
|
||||
public static function shippingPriceByWeight($shipping_prices, $shipping_weight)
|
||||
{
|
||||
foreach ($shipping_prices as $price) {
|
||||
if ($price->weight_from > 0 && $price->weight_to > 0) {
|
||||
if ($shipping_weight >= $price->weight_from && $shipping_weight <= $price->weight_to) {
|
||||
return $price;
|
||||
}
|
||||
}
|
||||
}
|
||||
abort(403, 'Fehler: Preis nach Gewicht im Versandland nicht gefunden');
|
||||
}
|
||||
|
||||
public static function isCompProducts($for)
|
||||
{
|
||||
/*
|
||||
$for = me, ot-member, ot-customer, abo-ot-member, abo-ot-customer, abo-me
|
||||
*/
|
||||
if ($for === 'me') {
|
||||
return (bool) Setting::getContentBySlug('is_comp_me_order');
|
||||
}
|
||||
if ($for === 'abo-me') {
|
||||
return (bool) Setting::getContentBySlug('is_comp_me_abo');
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
public static function getCompProducts($for)
|
||||
{
|
||||
if (Shop::isCompProducts($for)) {
|
||||
$show_on = '0';
|
||||
switch ($for) {
|
||||
case 'me':
|
||||
$show_on = '2';
|
||||
break;
|
||||
case 'abo-me':
|
||||
$show_on = '12';
|
||||
break;
|
||||
case 'ot-member':
|
||||
$show_on = '3';
|
||||
break;
|
||||
case 'ot-customer':
|
||||
$show_on = '3';
|
||||
break;
|
||||
case 'abo-ot-member':
|
||||
$show_on = '13';
|
||||
break;
|
||||
case 'abo-ot-customer':
|
||||
$show_on = '13';
|
||||
break;
|
||||
}
|
||||
return Product::whereActive(true)->where('shipping_addon', true)->whereJsonContains('show_on', $show_on)->orderBy('pos', 'DESC')->get();
|
||||
}
|
||||
return [];
|
||||
}
|
||||
|
||||
public static function getIPDatabaseInfo()
|
||||
{
|
||||
|
||||
//first check the DBs for the IP
|
||||
|
||||
|
||||
/* testing
|
||||
|
||||
foreach(self::testIps() as $ip_address){
|
||||
$country = MyDBIP::lookup($ip_address);
|
||||
dump($country);
|
||||
if($country !== false){
|
||||
continue;
|
||||
//return strtolower($country);
|
||||
}
|
||||
dump("not found ".$ip_address);
|
||||
//not found search in IPinfo
|
||||
$access_token = 'e1054aa11daf1e';
|
||||
$client = new IPinfo($access_token);
|
||||
|
||||
$details = $client->getDetails($ip_address);
|
||||
if(isset($details->error) && $details->error !== null){
|
||||
//return 'error';
|
||||
dump("not foun on IPinfo ".$details->error);
|
||||
}
|
||||
if(isset($details->country) && $details->country !== null){
|
||||
MyDBIP::insert($ip_address, $details->country);
|
||||
dump("found on IPinfo ".$details->country);
|
||||
//return strtolower($details->country);
|
||||
}
|
||||
//return 'error';
|
||||
}
|
||||
|
||||
dd("done");
|
||||
*/
|
||||
|
||||
/* live */
|
||||
|
||||
$ip_address = \Request::ip();
|
||||
// $ip_address = '86.189.47.78'; //testing
|
||||
$country = MyDBIP::lookup($ip_address);
|
||||
if ($country !== false) {
|
||||
return strtolower($country);
|
||||
}
|
||||
//not found search in IPinfo
|
||||
$access_token = 'e1054aa11daf1e';
|
||||
$client = new IPinfo($access_token);
|
||||
|
||||
$details = $client->getDetails($ip_address);
|
||||
if (isset($details->error) && $details->error !== null) {
|
||||
return 'error';
|
||||
}
|
||||
if (isset($details->country) && $details->country !== null) {
|
||||
MyDBIP::insert($ip_address, $details->country);
|
||||
return strtolower($details->country);
|
||||
}
|
||||
return 'error';
|
||||
}
|
||||
|
||||
|
||||
private static function testIps()
|
||||
{
|
||||
return [
|
||||
'58.217.40.197',
|
||||
'207.117.144.54',
|
||||
'65.169.228.128',
|
||||
'6.84.3.236',
|
||||
'214.56.36.93',
|
||||
'9.43.145.245',
|
||||
'231.199.26.76',
|
||||
'86.189.47.78',
|
||||
'3.122.58.75',
|
||||
'251.133.143.149',
|
||||
'6.142.181.83',
|
||||
'2.55.191.86',
|
||||
'90.189.58.233',
|
||||
'57.3.139.111',
|
||||
'41.130.99.194',
|
||||
'1.59.123.14',
|
||||
'9.119.131.109',
|
||||
'54.240.231.9',
|
||||
'117.19.131.144',
|
||||
'221.217.39.211',
|
||||
'7.43.125.76',
|
||||
'224.86.233.79',
|
||||
'32.151.38.98',
|
||||
'4.134.40.92',
|
||||
'4.70.188.58',
|
||||
'24.7.152.228',
|
||||
'58.122.179.1',
|
||||
'5.123.9.44',
|
||||
'3.175.206.5',
|
||||
'8.142.119.47',
|
||||
'40.248.58.203',
|
||||
'7.84.254.187',
|
||||
'215.215.239.71',
|
||||
'124.40.66.196',
|
||||
'215.87.143.102',
|
||||
'143.39.97.13',
|
||||
'202.56.79.198',
|
||||
'143.60.125.142',
|
||||
'73.233.153.126',
|
||||
'121.144.28.245',
|
||||
'53.232.193.122',
|
||||
'104.222.102.209',
|
||||
'216.55.215.13',
|
||||
'84.106.145.239',
|
||||
'200.131.52.20',
|
||||
'132.252.158.0',
|
||||
'220.11.129.27',
|
||||
'8.153.0.186',
|
||||
'119.206.117.107',
|
||||
'222.93.42.133',
|
||||
'105.104.224.98',
|
||||
'252.156.181.78',
|
||||
'7.139.235.187',
|
||||
'111.140.127.91',
|
||||
'1.186.17.84',
|
||||
'85.59.39.221',
|
||||
'231.152.252.43',
|
||||
'125.214.216.123',
|
||||
'69.31.65.238',
|
||||
'126.12.105.55',
|
||||
'211.39.4.118',
|
||||
'73.102.88.79',
|
||||
'210.229.38.137',
|
||||
'5.3.230.214',
|
||||
'208.92.91.242',
|
||||
'4.105.177.199',
|
||||
'38.10.48.92',
|
||||
'133.33.44.13',
|
||||
'202.189.24.255',
|
||||
'5.101.244.234',
|
||||
'2.52.110.194',
|
||||
'1.130.73.146',
|
||||
'84.237.232.120',
|
||||
'25.163.83.194'
|
||||
];
|
||||
}
|
||||
}
|
||||
211
dev/app-bak/Services/ShopApiOrderCart.php
Normal file
211
dev/app-bak/Services/ShopApiOrderCart.php
Normal file
|
|
@ -0,0 +1,211 @@
|
|||
<?php
|
||||
namespace App\Services;
|
||||
|
||||
use App\Models\ShoppingCollectOrder;
|
||||
use stdClass;
|
||||
use App\Models\ShoppingOrder;
|
||||
use Auth;
|
||||
|
||||
class ShopApiOrderCart
|
||||
{
|
||||
|
||||
public $shoppingCollectOrder;
|
||||
|
||||
public function __construct()
|
||||
{
|
||||
$this->shoppingCollectOrder = new ShoppingCollectOrder();
|
||||
$this->shoppingCollectOrder->shipping = 0;
|
||||
$this->shoppingCollectOrder->shipping_net = 0;
|
||||
$this->shoppingCollectOrder->shipping_tax = 0;
|
||||
$this->shoppingCollectOrder->points = 0;
|
||||
$this->shoppingCollectOrder->price_total_net = 0;
|
||||
$this->shoppingCollectOrder->price_total = 0;
|
||||
$this->shoppingCollectOrder->tax_total = 0;
|
||||
$this->shoppingCollectOrder->qty_total = 0;
|
||||
|
||||
$this->shoppingCollectOrder->tax_split = [];
|
||||
$this->shoppingCollectOrder->orders = [];
|
||||
$this->shoppingCollectOrder->shop_items = [];
|
||||
|
||||
}
|
||||
|
||||
public function add(ShoppingOrder $shopping_order){
|
||||
|
||||
$order = new stdClass();
|
||||
$order->order_id = $shopping_order->id;
|
||||
$order->wp_order_number = $shopping_order->shopping_user->wp_order_number;
|
||||
$order->billing_address = $this->setOrderAdress('billing', $shopping_order->shopping_user);
|
||||
$order->shipping_address = $this->setOrderAdress('shipping', $shopping_order->shopping_user);
|
||||
$order->shopping_order = $shopping_order;
|
||||
|
||||
$this->shoppingCollectOrder->shipping += $shopping_order->shipping;
|
||||
$this->shoppingCollectOrder->shipping_net += $shopping_order->shipping_net;
|
||||
|
||||
foreach ($shopping_order->shopping_order_items as $item){
|
||||
|
||||
$tax_rate = intval($item->product->tax);
|
||||
$user_price_net = $this->calcuPriceWith($item->price, $tax_rate, $item->discount);
|
||||
$user_price_net_qty = round($user_price_net * $item->qty, 2);
|
||||
$user_tax = $this->calcuTaxWith($user_price_net, $tax_rate);
|
||||
$user_tax_qty = round($user_tax * $item->qty, 2);
|
||||
|
||||
$shop_item_id = $item->product->id.'-'.$item->price;
|
||||
//set to item
|
||||
if(isset($this->shoppingCollectOrder->shop_items[$shop_item_id])){
|
||||
$shop_item = $this->shoppingCollectOrder->shop_items[$shop_item_id];
|
||||
if ($shop_item instanceof stdClass) {
|
||||
$shop_item->user_price_total_net += $user_price_net_qty;
|
||||
$shop_item->user_tax_total += $user_tax_qty;
|
||||
$shop_item->points_total += ($item->points * $item->qty);
|
||||
$shop_item->qty += $item->qty;
|
||||
}
|
||||
}else{
|
||||
$shop_item = new stdClass();
|
||||
$shop_item->pid = $item->product->id;
|
||||
|
||||
$shop_item->article = $item->product->wp_number;
|
||||
$shop_item->number = $item->product->number;
|
||||
$shop_item->name = $item->product->name;
|
||||
$shop_item->qty = $item->qty;
|
||||
|
||||
$shop_item->tax_rate = $tax_rate;
|
||||
$shop_item->points = $item->points;
|
||||
$shop_item->user_price_net = round($user_price_net, 2);
|
||||
$shop_item->user_price_total_net = round($user_price_net_qty, 2);
|
||||
$shop_item->user_tax = round($user_tax, 2);
|
||||
$shop_item->user_tax_total = round($user_tax_qty, 2);
|
||||
$shop_item->points_total = ($item->points * $item->qty);
|
||||
}
|
||||
|
||||
//only for tax split / tax and price on calculate function
|
||||
|
||||
$this->shoppingCollectOrder->addTaxToSplit((int)$tax_rate, (float)$user_tax_qty);
|
||||
$this->shoppingCollectOrder->addNetToSplit((int)$tax_rate, (float)$user_price_net_qty);
|
||||
$this->shoppingCollectOrder->tax_total += $user_tax_qty;
|
||||
$this->shoppingCollectOrder->price_total_net += $user_price_net_qty;
|
||||
$this->shoppingCollectOrder->points += ($item->points * $item->qty);
|
||||
$this->shoppingCollectOrder->qty_total += $item->qty;
|
||||
|
||||
$this->shoppingCollectOrder->addShopItem($shop_item_id, $shop_item);
|
||||
}
|
||||
$this->shoppingCollectOrder->addOrder($order);
|
||||
}
|
||||
|
||||
public function calculate(){
|
||||
|
||||
$this->shoppingCollectOrder->shipping_tax = round($this->shoppingCollectOrder->shipping - $this->shoppingCollectOrder->shipping_net, 2);
|
||||
$this->shoppingCollectOrder->tax_total += $this->shoppingCollectOrder->shipping_tax;
|
||||
//add shipping tax to split
|
||||
$this->shoppingCollectOrder->addTaxToSplit(config('app.main_tax_rate'), $this->shoppingCollectOrder->shipping_tax);
|
||||
$this->shoppingCollectOrder->addNetToSplit(config('app.main_tax_rate'), $this->shoppingCollectOrder->shipping_net);
|
||||
|
||||
$this->shoppingCollectOrder->price_total_net += $this->shoppingCollectOrder->shipping_net;
|
||||
$this->shoppingCollectOrder->price_total = round($this->shoppingCollectOrder->tax_total + $this->shoppingCollectOrder->price_total_net, 2);
|
||||
}
|
||||
|
||||
public function store(){
|
||||
$this->shoppingCollectOrder->user_id = \Auth::user()->id;
|
||||
$this->shoppingCollectOrder->status = 1;
|
||||
//remove shopping_order
|
||||
$temp = [];
|
||||
foreach($this->orders as $order){
|
||||
$order->shopping_order = null;
|
||||
$temp[] = $order;
|
||||
}
|
||||
$this->shoppingCollectOrder->orders = $temp;
|
||||
$this->shoppingCollectOrder->save();
|
||||
}
|
||||
|
||||
//price brutto calu with
|
||||
private function calcuPriceWith($price, $tax_rate = null, $discount = null){
|
||||
$tax_dec = ($tax_rate + 100) / 100;
|
||||
$price = $price / $tax_dec;
|
||||
$margin = (($discount -100)*-1) / 100;
|
||||
$price = $price * $margin;
|
||||
return round($price, 2);
|
||||
}
|
||||
|
||||
private function calcuTaxWith($price, $tax_rate = null){
|
||||
$tax_dec = ($tax_rate + 100) / 100;
|
||||
$tax = ($price * $tax_dec) - $price;
|
||||
return round($tax, 2);
|
||||
}
|
||||
|
||||
private function setOrderAdress($from, $shopping_user){
|
||||
$ret = "";
|
||||
if($from === 'billing'){
|
||||
$ret .= $shopping_user->billing_company ? 'Firma: '.$shopping_user->billing_company.' | ' : '';
|
||||
$ret .= \App\Services\HTMLHelper::getSalutationLang($shopping_user->billing_salutation).' ';
|
||||
$ret .= $shopping_user->billing_firstname.' ';
|
||||
$ret .= $shopping_user->billing_lastname.' | ';
|
||||
$ret .= $shopping_user->billing_address.' | ';
|
||||
$ret .= $shopping_user->billing_zipcode.' ';
|
||||
$ret .= $shopping_user->billing_city.' | ';
|
||||
$ret .= $shopping_user->billing_country->getLocated().' | ';
|
||||
$ret .= $shopping_user->billing_email;
|
||||
|
||||
}
|
||||
if($from === 'shipping'){
|
||||
if($shopping_user->same_as_billing == 1){
|
||||
return 'Lieferadresse ist gleich Rechnungsadresse';
|
||||
}
|
||||
$ret .= $shopping_user->shipping_company ? 'Firma: '.$shopping_user->shipping_company.' | ' : '';
|
||||
$ret .= \App\Services\HTMLHelper::getSalutationLang($shopping_user->shipping_salutation).' ';
|
||||
$ret .= $shopping_user->shipping_firstname.' ';
|
||||
$ret .= $shopping_user->shipping_lastname.' | ';
|
||||
$ret .= $shopping_user->shipping_address.' | ';
|
||||
$ret .= $shopping_user->shipping_zipcode.' ';
|
||||
$ret .= $shopping_user->shipping_city.' | ';
|
||||
$ret .= $shopping_user->shipping_country->getLocated().' | ';
|
||||
|
||||
}
|
||||
return $ret;
|
||||
}
|
||||
|
||||
|
||||
public function __get($property) {
|
||||
if (property_exists($this->shoppingCollectOrder, $property)) {
|
||||
return $this->shoppingCollectOrder->$property;
|
||||
}
|
||||
if (isset($this->shoppingCollectOrder->{$property})) {
|
||||
return $this->shoppingCollectOrder->{$property};
|
||||
}
|
||||
}
|
||||
|
||||
public function getTotalTax()
|
||||
{
|
||||
return $this->shoppingCollectOrder->tax_total;
|
||||
}
|
||||
|
||||
public function getTotalPriceNetto()
|
||||
{
|
||||
return $this->shoppingCollectOrder->price_total_net;
|
||||
}
|
||||
|
||||
public function getTotalPrice()
|
||||
{
|
||||
return $this->shoppingCollectOrder->price_total;
|
||||
}
|
||||
|
||||
public function getTaxSplit()
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
|
||||
public static function finishOrder(ShoppingCollectOrder $shoppingCollectOrder){
|
||||
|
||||
//get orders an set
|
||||
foreach($shoppingCollectOrder->orders as $order){
|
||||
$ShoppingOrder = ShoppingOrder::findOrFail($order['order_id']);
|
||||
$ShoppingOrder->api_status = 2; //bestellt
|
||||
$api_notice = $ShoppingOrder->api_notice;
|
||||
$api_notice['shopping_order_id'] = $shoppingCollectOrder->shopping_order_id;
|
||||
$ShoppingOrder->api_notice = $api_notice;
|
||||
$ShoppingOrder->txaction = 'extern_paid';
|
||||
$ShoppingOrder->save();
|
||||
}
|
||||
$shoppingCollectOrder->status = 2; //order
|
||||
$shoppingCollectOrder->save();
|
||||
}
|
||||
|
||||
}
|
||||
198
dev/app-bak/Services/ShoppingUserService.php
Normal file
198
dev/app-bak/Services/ShoppingUserService.php
Normal file
|
|
@ -0,0 +1,198 @@
|
|||
<?php
|
||||
namespace App\Services;
|
||||
|
||||
use App\Models\ShoppingOrder;
|
||||
use App\Models\ShoppingUser;
|
||||
use App\User;
|
||||
use Yard;
|
||||
use Illuminate\Support\Facades\DB;
|
||||
use Illuminate\Database\QueryException;
|
||||
|
||||
class ShoppingUserService
|
||||
{
|
||||
|
||||
/**
|
||||
* Gibt alle Bestellungen eines Mitglieds zurück
|
||||
*
|
||||
* @param ShoppingUser $shopping_user Das Mitglied, dessen Bestellungen zurückgegeben werden sollen
|
||||
* @return Collection Die Bestellungen des Mitglieds
|
||||
*/
|
||||
public static function getAllOrdersByMember($shopping_user){
|
||||
$users = ShoppingUser::where('billing_email', '=', $shopping_user->billing_email)->where('member_id', '=', $shopping_user->member_id)->get();
|
||||
return $users->flatMap(function($user) {
|
||||
return $user->shopping_orders;
|
||||
})->sortByDesc('created_at');
|
||||
}
|
||||
|
||||
public static function syncOrdersByEmail($user)
|
||||
{
|
||||
$maxAttempts = 3;
|
||||
$attempt = 1;
|
||||
|
||||
while ($attempt <= $maxAttempts) {
|
||||
try {
|
||||
DB::beginTransaction();
|
||||
|
||||
$shopping_user = ShoppingUser::where('member_id', $user->id)
|
||||
->first();
|
||||
|
||||
if (!$shopping_user) {
|
||||
DB::commit();
|
||||
return;
|
||||
}
|
||||
|
||||
$shopping_users = ShoppingUser::where('billing_email', '=', $shopping_user->billing_email)
|
||||
->whereHas('shopping_order', function($q) {
|
||||
$q->where('txaction', 'paid')
|
||||
->orWhere('txaction', 'appointed')
|
||||
->orWhere('txaction', 'extern')
|
||||
->orWhere('txaction', 'invoice_open')
|
||||
->orWhere('txaction', 'invoice_paid');
|
||||
})
|
||||
->lockForUpdate()
|
||||
->get();
|
||||
|
||||
$order_count = $shopping_users->count();
|
||||
|
||||
foreach($shopping_users as $user) {
|
||||
$user->orders = $order_count;
|
||||
$user->save();
|
||||
}
|
||||
|
||||
DB::commit();
|
||||
return; // Erfolgreicher Fall
|
||||
|
||||
} catch (QueryException $e) {
|
||||
DB::rollBack();
|
||||
|
||||
// Wenn es ein Deadlock ist, versuchen wir es erneut
|
||||
if ($e->getCode() == 40001 && $attempt < $maxAttempts) {
|
||||
$sleepTime = pow(2, $attempt) * 100000; // Exponentielles Backoff in Mikrosekunden
|
||||
usleep($sleepTime);
|
||||
$attempt++;
|
||||
continue;
|
||||
}
|
||||
|
||||
throw $e; // Andere Fehler oder zu viele Versuche
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/*public static function syncOrdersByEmail($user){
|
||||
ShoppingUser::where('member_id', $user->id)
|
||||
->whereNotNull('billing_email')
|
||||
->where('billing_email', '!=', '')
|
||||
->select('billing_email')
|
||||
->groupBy('billing_email')
|
||||
->get()
|
||||
->each(function($shopping_user) {
|
||||
self::snycOrdersByShoppingUser($shopping_user);
|
||||
});
|
||||
}*/
|
||||
/**
|
||||
* Synchronisiert die Bestellungen eines ShoppingOrders mit den Bestellungen des zugehörigen ShoppingUsers
|
||||
*
|
||||
* @param ShoppingOrder $shopping_order Der zu synchronisierende ShoppingOrder
|
||||
*/
|
||||
public static function snycOrdersByShoppingOrder(ShoppingOrder $shopping_order) {
|
||||
$shopping_user = $shopping_order->shopping_user ? $shopping_order->shopping_user : null;
|
||||
if($shopping_user){
|
||||
self::snycOrdersByShoppingUser($shopping_user);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Synchronisiert die Bestellungen eines ShoppingUsers mit den Bestellungen des zugehörigen Benutzers
|
||||
*
|
||||
* @param ShoppingUser $shopping_user Der zu synchronisierende ShoppingUser
|
||||
*/
|
||||
public static function snycOrdersByShoppingUser(ShoppingUser $shopping_user) {
|
||||
|
||||
// Aktualisiere alle Benutzer mit einer einzigen Datenbankabfrage
|
||||
ShoppingUser::where('billing_email', $shopping_user->billing_email)
|
||||
->update([
|
||||
'orders' => ShoppingUser::where('billing_email', $shopping_user->billing_email)
|
||||
->whereHas('shopping_order', function($q) {
|
||||
$q->whereIn('txaction', ['paid', 'appointed', 'extern', 'invoice_open', 'invoice_paid']);
|
||||
})
|
||||
->count()
|
||||
]);
|
||||
|
||||
}
|
||||
|
||||
public static function snycOrdersByNumber($number){
|
||||
if($number <= 0) {
|
||||
return;
|
||||
}
|
||||
// Aktualisiere alle Benutzer mit einer einzigen Datenbankabfrage
|
||||
|
||||
ShoppingUser::where('number', '=', $number)
|
||||
->update([
|
||||
'orders' => ShoppingUser::where('number', '=', $number)
|
||||
->whereHas('shopping_order', function($q) {
|
||||
$q->whereIn('txaction', ['paid', 'appointed', 'extern', 'invoice_open', 'invoice_paid']);
|
||||
})
|
||||
->count()
|
||||
]);
|
||||
// Setze orders auf NULL für alle anderen
|
||||
ShoppingUser::where('number', '=', $number)
|
||||
->whereDoesntHave('shopping_order', function($q) {
|
||||
$q->whereIn('txaction', ['paid', 'appointed', 'extern', 'extern_paid']);
|
||||
})
|
||||
->update(['orders' => null]);
|
||||
}
|
||||
|
||||
/**
|
||||
* Synchronisiert die Nummern aller ShoppingUser eines Benutzers anhand der E-Mails
|
||||
*
|
||||
* @param User $user Der Benutzer, dessen ShoppingUser synchronisiert werden sollen
|
||||
*/
|
||||
public static function syncNumbersByEmail($user) {
|
||||
// Hole alle ShoppingUser mit E-Mail gruppiert
|
||||
$emailGroups = ShoppingUser::where('member_id', $user->id)
|
||||
->whereNotNull('billing_email')
|
||||
->where('billing_email', '!=', '')
|
||||
->get()
|
||||
->groupBy('billing_email');
|
||||
|
||||
foreach($emailGroups as $email => $users) {
|
||||
// Suche ob es bereits eine Nummer für diese E-Mail gibt
|
||||
$existingNumber = ($users->whereNotNull('number')->first()) ? $users->whereNotNull('number')->first()->number : null;
|
||||
|
||||
if($existingNumber) {
|
||||
// Wenn eine Nummer existiert, nutze diese für alle User mit der E-Mail
|
||||
ShoppingUser::where('member_id', $user->id)
|
||||
->where('billing_email', $email)
|
||||
->whereNull('number')
|
||||
->update(['number' => $existingNumber]);
|
||||
} else {
|
||||
// Wenn keine Nummer existiert, generiere eine neue
|
||||
$maxNumber = ShoppingUser::max('number') ?: 1000;
|
||||
$newNumber = $maxNumber + 1;
|
||||
|
||||
ShoppingUser::where('member_id', $user->id)
|
||||
->where('billing_email', $email)
|
||||
->update(['number' => $newNumber]);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Setzt alle Faker-E-Mails für einen Benutzer auf 1
|
||||
*
|
||||
* @param User $user Der Benutzer, dessen Faker-E-Mails gesetzt werden sollen
|
||||
*/
|
||||
public static function setFakerMail($user){
|
||||
// Aktualisiere alle Faker-E-Mails für den Benutzer in einem einzigen Update
|
||||
// Schneller da nur ein einzelner SQL Query ausgeführt wird
|
||||
ShoppingUser::where('member_id', $user->id)
|
||||
->where('faker_mail', '!=', 1)
|
||||
->where('billing_email', 'LIKE', '%faker@mivita.care')
|
||||
->update(['faker_mail' => 1]);
|
||||
|
||||
// Setze alle anderen auf NULL zurück
|
||||
ShoppingUser::where('member_id', $user->id)
|
||||
->where('billing_email', 'NOT LIKE', '%faker@mivita.care')
|
||||
->update(['faker_mail' => null]);
|
||||
}
|
||||
}
|
||||
255
dev/app-bak/Services/Slim.php
Normal file
255
dev/app-bak/Services/Slim.php
Normal file
|
|
@ -0,0 +1,255 @@
|
|||
<?php
|
||||
namespace App\Services;
|
||||
|
||||
abstract class SlimStatus {
|
||||
const FAILURE = 'failure';
|
||||
const SUCCESS = 'success';
|
||||
}
|
||||
|
||||
class Slim {
|
||||
|
||||
public static function getImages($inputName = 'slim') {
|
||||
|
||||
$values = Slim::getPostData($inputName);
|
||||
|
||||
// test for errors
|
||||
if ($values === false) {
|
||||
return false;
|
||||
}
|
||||
|
||||
// determine if contains multiple input values, if is singular, put in array
|
||||
$data = array();
|
||||
if (!is_array($values)) {
|
||||
$values = array($values);
|
||||
}
|
||||
|
||||
// handle all posted fields
|
||||
foreach ($values as $value) {
|
||||
$inputValue = Slim::parseInput($value);
|
||||
if ($inputValue) {
|
||||
array_push($data, $inputValue);
|
||||
}
|
||||
}
|
||||
|
||||
// return the data collected from the fields
|
||||
return $data;
|
||||
|
||||
}
|
||||
|
||||
// $value should be in JSON format
|
||||
private static function parseInput($value) {
|
||||
|
||||
// if no json received, exit, don't handle empty input values.
|
||||
if (empty($value)) {return null;}
|
||||
|
||||
// If magic quotes enabled
|
||||
// Magic quotes were removed in PHP 5.4, no need to check in PHP 8.2
|
||||
|
||||
// The data is posted as a JSON String so to be used it needs to be deserialized first
|
||||
$data = json_decode($value);
|
||||
|
||||
// shortcut
|
||||
$input = null;
|
||||
$actions = null;
|
||||
$output = null;
|
||||
$meta = null;
|
||||
|
||||
if (isset ($data->input)) {
|
||||
|
||||
$inputData = null;
|
||||
if (isset($data->input->image)) {
|
||||
$inputData = Slim::getBase64Data($data->input->image);
|
||||
}
|
||||
else if (isset($data->input->field)) {
|
||||
$filename = $_FILES[$data->input->field]['tmp_name'];
|
||||
if ($filename) {
|
||||
$inputData = file_get_contents($filename);
|
||||
}
|
||||
}
|
||||
|
||||
$input = array(
|
||||
'data' => $inputData,
|
||||
'name' => $data->input->name,
|
||||
'type' => $data->input->type,
|
||||
'size' => $data->input->size,
|
||||
'width' => $data->input->width,
|
||||
'height' => $data->input->height,
|
||||
);
|
||||
|
||||
}
|
||||
|
||||
if (isset($data->output)) {
|
||||
|
||||
$outputDate = null;
|
||||
if (isset($data->output->image)) {
|
||||
$outputData = Slim::getBase64Data($data->output->image);
|
||||
}
|
||||
else if (isset ($data->output->field)) {
|
||||
$filename = $_FILES[$data->output->field]['tmp_name'];
|
||||
if ($filename) {
|
||||
$outputData = file_get_contents($filename);
|
||||
}
|
||||
}
|
||||
|
||||
$output = array(
|
||||
'data' => $outputData,
|
||||
'name' => $data->output->name,
|
||||
'type' => $data->output->type,
|
||||
'width' => $data->output->width,
|
||||
'height' => $data->output->height
|
||||
);
|
||||
}
|
||||
|
||||
if (isset($data->actions)) {
|
||||
$actions = array(
|
||||
'crop' => $data->actions->crop ? array(
|
||||
'x' => $data->actions->crop->x,
|
||||
'y' => $data->actions->crop->y,
|
||||
'width' => $data->actions->crop->width,
|
||||
'height' => $data->actions->crop->height,
|
||||
'type' => $data->actions->crop->type
|
||||
) : null,
|
||||
'size' => $data->actions->size ? array(
|
||||
'width' => $data->actions->size->width,
|
||||
'height' => $data->actions->size->height
|
||||
) : null,
|
||||
'rotation' => $data->actions->rotation,
|
||||
'filters' => $data->actions->filters ? array(
|
||||
'sharpen' => $data->actions->filters->sharpen
|
||||
) : null
|
||||
);
|
||||
}
|
||||
|
||||
if (isset($data->meta)) {
|
||||
$meta = $data->meta;
|
||||
}
|
||||
|
||||
// We've sanitized the base64data and will now return the clean file object
|
||||
return array(
|
||||
'input' => $input,
|
||||
'output' => $output,
|
||||
'actions' => $actions,
|
||||
'meta' => $meta
|
||||
);
|
||||
}
|
||||
|
||||
// $path should have trailing slash
|
||||
public static function saveFile($data, $name, $path = 'tmp/', $uid = true) {
|
||||
|
||||
// Add trailing slash if omitted
|
||||
if (substr($path, -1) !== '/') {
|
||||
$path .= '/';
|
||||
}
|
||||
|
||||
// Test if directory already exists
|
||||
if(!is_dir($path)){
|
||||
mkdir($path, 0755, true);
|
||||
}
|
||||
|
||||
// Sanitize characters in file name
|
||||
$name = Slim::sanitizeFileName($name);
|
||||
|
||||
// Let's put a unique id in front of the filename so we don't accidentally overwrite other files
|
||||
if ($uid) {
|
||||
$name = uniqid() . '_' . $name;
|
||||
}
|
||||
|
||||
// Add name to path, we need the full path including the name to save the file
|
||||
$path = $path . $name;
|
||||
|
||||
// store the file
|
||||
Slim::save($data, $path);
|
||||
|
||||
// return the files new name and location
|
||||
return array(
|
||||
'name' => $name,
|
||||
'path' => $path
|
||||
);
|
||||
}
|
||||
|
||||
/**
|
||||
* Get data from remote URL
|
||||
* @param $url
|
||||
* @return string
|
||||
*/
|
||||
public static function fetchURL($url, $maxFileSize) {
|
||||
if (!ini_get('allow_url_fopen')) {
|
||||
return null;
|
||||
}
|
||||
$content = null;
|
||||
try {
|
||||
$content = @file_get_contents($url, false, null, 0, $maxFileSize);
|
||||
} catch(Exception $e) {
|
||||
return false;
|
||||
}
|
||||
return $content;
|
||||
}
|
||||
|
||||
public static function outputJSON($data) {
|
||||
header('Content-Type: application/json');
|
||||
echo json_encode($data);
|
||||
}
|
||||
|
||||
/**
|
||||
* http://stackoverflow.com/a/2021729
|
||||
* Remove anything which isn't a word, whitespace, number
|
||||
* or any of the following characters -_~,;[]().
|
||||
* If you don't need to handle multi-byte characters
|
||||
* you can use preg_replace rather than mb_ereg_replace
|
||||
* @param $str
|
||||
* @return string
|
||||
*/
|
||||
public static function sanitizeFileName($str) {
|
||||
// Basic clean up
|
||||
$str = preg_replace('([^\w\s\d\-_~,;\[\]\(\).])', '', $str);
|
||||
// Remove any runs of periods
|
||||
$str = preg_replace('([\.]{2,})', '', $str);
|
||||
|
||||
$str = (strlen($str) > 33) ? substr($str,-33) : $str;
|
||||
|
||||
return $str;
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets the posted data from the POST or FILES object. If was using Slim to upload it will be in POST (as posted with hidden field) if not enhanced with Slim it'll be in FILES.
|
||||
* @param $inputName
|
||||
* @return array|bool
|
||||
*/
|
||||
private static function getPostData($inputName) {
|
||||
|
||||
$values = array();
|
||||
|
||||
if (isset($_POST[$inputName])) {
|
||||
$values = $_POST[$inputName];
|
||||
}
|
||||
else if (isset($_FILES[$inputName])) {
|
||||
// Slim was not used to upload this file
|
||||
return false;
|
||||
}
|
||||
|
||||
return $values;
|
||||
}
|
||||
|
||||
/**
|
||||
* Saves the data to a given location
|
||||
* @param $data
|
||||
* @param $path
|
||||
* @return bool
|
||||
*/
|
||||
private static function save($data, $path) {
|
||||
if (!file_put_contents($path, $data)) {
|
||||
return false;
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
/**
|
||||
* Strips the "data:image..." part of the base64 data string so PHP can save the string as a file
|
||||
* @param $data
|
||||
* @return string
|
||||
*/
|
||||
private static function getBase64Data($data) {
|
||||
return base64_decode(preg_replace('#^data:image/\w+;base64,#i', '', $data));
|
||||
}
|
||||
|
||||
}
|
||||
51
dev/app-bak/Services/SyS/BusinessStructur.php
Normal file
51
dev/app-bak/Services/SyS/BusinessStructur.php
Normal file
|
|
@ -0,0 +1,51 @@
|
|||
<?php
|
||||
namespace App\Services\SyS;
|
||||
|
||||
use App\Cron\BusinessUsersStore;
|
||||
use Carbon;
|
||||
use Request;
|
||||
use App\Models\SySetting;
|
||||
|
||||
class BusinessStructur
|
||||
{
|
||||
|
||||
public static function show()
|
||||
{
|
||||
$month = 2;
|
||||
$year = 2021;
|
||||
dd("function on: php artisan business:store month year");
|
||||
|
||||
/*$businessUsersStore = new BusinessUsersStore($month, $year);
|
||||
$businessUsersStore->storeUserBusinessStructure();
|
||||
$businessUsersStore->storeBusinessUsersDetail();
|
||||
$businessUsersStore->storeBusinessCompleted();*/
|
||||
|
||||
|
||||
$data = [
|
||||
'year' => $year,
|
||||
'month' => $month,
|
||||
];
|
||||
|
||||
return view('sys.tools.business_structur', $data);
|
||||
}
|
||||
|
||||
|
||||
public static function store()
|
||||
{
|
||||
|
||||
$data = Request::all();
|
||||
|
||||
$data['active'] = isset($data['active']) ? true : false;
|
||||
if($data['id'] === "new"){
|
||||
$model = SySetting::create($data);
|
||||
}else{
|
||||
$model = SySetting::find($data['id']);
|
||||
$model->fill($data);
|
||||
$model->save();
|
||||
}
|
||||
|
||||
\Session()->flash('alert-save', '1');
|
||||
return redirect(route('sysadmin_tool', ['sales_members']));
|
||||
|
||||
}
|
||||
}
|
||||
80
dev/app-bak/Services/SyS/BuyingsProducts.php
Normal file
80
dev/app-bak/Services/SyS/BuyingsProducts.php
Normal file
|
|
@ -0,0 +1,80 @@
|
|||
<?php
|
||||
namespace App\Services\SyS;
|
||||
|
||||
use Carbon;
|
||||
use Request;
|
||||
use App\Models\SySetting;
|
||||
use App\Models\ProductBuying;
|
||||
use App\Cron\BusinessUsersStore;
|
||||
use App\Models\ShoppingOrderItem;
|
||||
|
||||
class BuyingsProducts
|
||||
{
|
||||
|
||||
public static function show()
|
||||
{
|
||||
|
||||
$data = [
|
||||
];
|
||||
|
||||
return view('sys.tools.buyings_products', $data);
|
||||
}
|
||||
|
||||
|
||||
public static function store()
|
||||
{
|
||||
|
||||
$ShoppingOrderItems = ShoppingOrderItem::where('product_id', 37)->get();
|
||||
$count = 0;
|
||||
foreach($ShoppingOrderItems as $ShoppingOrderItem){
|
||||
if(!ProductBuying::where('user_id', $ShoppingOrderItem->shopping_order->auth_user_id)->where('product_id', $ShoppingOrderItem->product_id)->count()){
|
||||
ProductBuying::create([
|
||||
'user_id' => $ShoppingOrderItem->shopping_order->auth_user_id,
|
||||
'product_id' => 37,
|
||||
'amount' => 1
|
||||
]);
|
||||
$count ++;
|
||||
}
|
||||
|
||||
}
|
||||
dump("ADD ".$count." product_id 37");
|
||||
|
||||
$ShoppingOrderItems = ShoppingOrderItem::where('product_id', 100)->get();
|
||||
$count = 0;
|
||||
foreach($ShoppingOrderItems as $ShoppingOrderItem){
|
||||
if(!ProductBuying::where('user_id', $ShoppingOrderItem->shopping_order->auth_user_id)->where('product_id', $ShoppingOrderItem->product_id)->count()){
|
||||
ProductBuying::create([
|
||||
'user_id' => $ShoppingOrderItem->shopping_order->auth_user_id,
|
||||
'product_id' => 118,
|
||||
'amount' => 1
|
||||
]);
|
||||
$count ++;
|
||||
}
|
||||
|
||||
}
|
||||
dump("ADD ".$count." product_id 100 to 118");
|
||||
|
||||
|
||||
$ShoppingOrderItems = ShoppingOrderItem::where('product_id', 118)->get();
|
||||
$count = 0;
|
||||
foreach($ShoppingOrderItems as $ShoppingOrderItem){
|
||||
if(!ProductBuying::where('user_id', $ShoppingOrderItem->shopping_order->auth_user_id)->where('product_id', $ShoppingOrderItem->product_id)->count()){
|
||||
ProductBuying::create([
|
||||
'user_id' => $ShoppingOrderItem->shopping_order->auth_user_id,
|
||||
'product_id' => 118,
|
||||
'amount' => 1
|
||||
]);
|
||||
$count ++;
|
||||
}
|
||||
|
||||
}
|
||||
dump("ADD ".$count." product_id 118");
|
||||
|
||||
|
||||
die();
|
||||
|
||||
\Session()->flash('alert-save', '1');
|
||||
return redirect(route('sysadmin_tool', ['buyings_products']));
|
||||
|
||||
}
|
||||
}
|
||||
67
dev/app-bak/Services/SyS/ChangeUserBusinesses.php
Normal file
67
dev/app-bak/Services/SyS/ChangeUserBusinesses.php
Normal file
|
|
@ -0,0 +1,67 @@
|
|||
<?php
|
||||
namespace App\Services\SyS;
|
||||
|
||||
use Request;
|
||||
use App\Models\UserBusiness;
|
||||
|
||||
|
||||
class ChangeUserBusinesses
|
||||
{
|
||||
|
||||
public static function show()
|
||||
{
|
||||
|
||||
dump("ChangeUserBusinesses");
|
||||
dd('check function');
|
||||
$UserBusiness = UserBusiness::all();
|
||||
$c = 0;
|
||||
foreach($UserBusiness as $user_business){
|
||||
|
||||
if($user_business->qual_user_level){
|
||||
$qual_user_level = $user_business->qual_user_level;
|
||||
if(isset($qual_user_level['qual_tp'])){
|
||||
$qual_user_level['qual_pp'] = $qual_user_level['qual_tp'];
|
||||
unset($qual_user_level['qual_tp']);
|
||||
}
|
||||
if(!isset($qual_user_level['paylines'])){
|
||||
$qual_user_level['paylines'] = 6;
|
||||
|
||||
}
|
||||
$user_business->qual_user_level = $qual_user_level;
|
||||
$c ++;
|
||||
$user_business->save();
|
||||
}
|
||||
|
||||
if($user_business->next_qual_user_level){
|
||||
$next_qual_user_level = $user_business->next_qual_user_level;
|
||||
if(isset($next_qual_user_level['qual_tp'])){
|
||||
$next_qual_user_level['qual_pp'] = $next_qual_user_level['qual_tp'];
|
||||
unset($next_qual_user_level['qual_tp']);
|
||||
}
|
||||
if(!isset($next_qual_user_level['paylines'])){
|
||||
$next_qual_user_level['paylines'] = 6;
|
||||
}
|
||||
$user_business->next_qual_user_level = $next_qual_user_level;
|
||||
|
||||
$c ++;
|
||||
$user_business->save();
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
dump("counter");
|
||||
dd($c);
|
||||
|
||||
|
||||
}
|
||||
|
||||
|
||||
public static function store()
|
||||
{
|
||||
$data = Request::all();
|
||||
\Session()->flash('alert-save', true);
|
||||
return back();
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
102
dev/app-bak/Services/SyS/CleanHTMLProductDescription.php
Normal file
102
dev/app-bak/Services/SyS/CleanHTMLProductDescription.php
Normal file
|
|
@ -0,0 +1,102 @@
|
|||
<?php
|
||||
namespace App\Services\SyS;
|
||||
|
||||
use App\Models\Product;
|
||||
use Request;
|
||||
use App\Models\TransProduct;
|
||||
use App\Models\UserCreditItem;
|
||||
|
||||
class CleanHTMLProductDescription
|
||||
{
|
||||
|
||||
public static function show()
|
||||
{
|
||||
dump("CleanHTMLProductDescription");
|
||||
// dd('check function');
|
||||
$TransProducts = TransProduct::limit(2000)->get();
|
||||
dump(count($TransProducts));
|
||||
$c = 0;
|
||||
foreach($TransProducts as $item){
|
||||
if($item->value){
|
||||
$item->value = self::cleanHTML($item->value);
|
||||
$item->save();
|
||||
|
||||
//dump($item->value);
|
||||
$c++;
|
||||
}
|
||||
}
|
||||
dump("counter TransProduct");
|
||||
dump($c);
|
||||
|
||||
$Products = Product::limit(2000)->get();
|
||||
dump(count($Products));
|
||||
$c = 0;
|
||||
foreach($Products as $item){
|
||||
if($item){
|
||||
$item->copy = self::cleanHTML($item->copy);
|
||||
$item->description = self::cleanHTML($item->description);
|
||||
$item->usage = self::cleanHTML($item->usage);
|
||||
$item->ingredients = self::cleanHTML($item->ingredients);
|
||||
|
||||
$item->save();
|
||||
|
||||
//dump($item->value);
|
||||
$c++;
|
||||
}
|
||||
}
|
||||
|
||||
dump("counter");
|
||||
dd($c);
|
||||
}
|
||||
|
||||
public static function cleanHTML($html)
|
||||
{
|
||||
// $html = preg_replace("/(</?)div/", "$1p", $html);
|
||||
|
||||
$html = str_replace('<p> </p>', '', $html);
|
||||
$html = str_replace('<p></p>', '', $html);
|
||||
$html = str_replace('<p><br></p>', '', $html);
|
||||
$html = str_replace('<p><br></p>', '', $html);
|
||||
|
||||
$html = str_replace('<br>', '', $html);
|
||||
$html = str_replace('text -primary', 'text-primary', $html);
|
||||
$html = str_replace('fa -check', 'fa-check', $html);
|
||||
$html = str_replace('text- primary', 'text-primary', $html);
|
||||
$html = str_replace('fa- check', 'fa-check', $html);
|
||||
$html = str_replace('<ul class="list-unstyled list-icons" style="padding-left: 15px;"> </ul>', '', $html);
|
||||
|
||||
$html = str_replace('</span>', '', $html);
|
||||
$html = preg_replace('/(<[^>]+) style=".*?"/i', '$1', $html);
|
||||
|
||||
$html = str_replace('<li></li>', '', $html);
|
||||
$html = str_replace('<li> </li>', '', $html);
|
||||
$html = str_replace('< i', '<i', $html);
|
||||
$html = str_replace('< li>', '<li>', $html);
|
||||
|
||||
$html = str_replace('</ i>', '</i>', $html);
|
||||
$html = str_replace('</ li>', '</li>', $html);
|
||||
|
||||
$html = str_replace('</ b>', '</b>', $html);
|
||||
$html = str_replace('< /b>', '</b>', $html);
|
||||
|
||||
$html = str_replace('</ p>', '</p>', $html);
|
||||
$html = str_replace('< /p>', '</p>', $html);
|
||||
|
||||
$html = str_replace('< /i>', '</i>', $html);
|
||||
$html = str_replace('< /li>', '</li>', $html);
|
||||
$html = str_replace('<div>', '', $html);
|
||||
$html = str_replace('</div>', '', $html);
|
||||
$html = str_replace('>>', '>', $html);
|
||||
return $html;
|
||||
|
||||
}
|
||||
|
||||
public static function store()
|
||||
{
|
||||
$data = Request::all();
|
||||
\Session()->flash('alert-save', true);
|
||||
return back();
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
307
dev/app-bak/Services/SyS/Correction.php
Normal file
307
dev/app-bak/Services/SyS/Correction.php
Normal file
|
|
@ -0,0 +1,307 @@
|
|||
<?php
|
||||
namespace App\Services\SyS;
|
||||
|
||||
use Carbon;
|
||||
use Request;
|
||||
use App\Models\Product;
|
||||
use App\Models\Homeparty;
|
||||
use App\Models\SySetting;
|
||||
use App\Models\ShoppingUser;
|
||||
use App\Models\ShoppingOrder;
|
||||
use App\Models\UserSalesVolume;
|
||||
use App\Models\ShoppingOrderItem;
|
||||
use App\Repositories\ImportRepository;
|
||||
use App\Services\BusinessPlan\SalesPointsVolume;
|
||||
|
||||
class Correction
|
||||
{
|
||||
|
||||
private static function calcuUserSalesVolume($order){
|
||||
/*
|
||||
status
|
||||
1 => 'hinzugefügt aus Bestellung',
|
||||
2 => 'hinzugefügt aus Shop',
|
||||
3 => 'hinzugefügt aus Shop / pending',
|
||||
|
||||
*/
|
||||
$status = SalesPointsVolume::getStatusByOrderPaymentFor($order);
|
||||
$user_id = $order->auth_user_id ? $order->auth_user_id : $order->member_id;
|
||||
//akuteller tag / Monat.
|
||||
$month = $order->created_at->format('m');
|
||||
$year = $order->created_at->format('Y');
|
||||
$date = $order->created_at->format('d.m.Y');
|
||||
|
||||
|
||||
if($status === 3){ //shop bestellung User pending
|
||||
$user_id = $order->auth_user_id ? $order->auth_user_id : $order->member_id;
|
||||
$month_points = 0;
|
||||
$month_total_net = 0;
|
||||
$month_shop_points = 0;
|
||||
$month_shop_total_net = 0;
|
||||
}else{
|
||||
$month_points = UserSalesVolume::where('user_id', $user_id)->where('status', 1)->where('month', $month)->where('year', $year)->sum('points');
|
||||
$month_total_net = UserSalesVolume::where('user_id', $user_id)->where('status', 1)->where('month', $month)->where('year', $year)->sum('total_net');
|
||||
$month_shop_points = UserSalesVolume::where('user_id', $user_id)->where('status', 2)->where('month', $month)->where('year', $year)->sum('points');
|
||||
$month_shop_total_net = UserSalesVolume::where('user_id', $user_id)->where('status', 2)->where('month', $month)->where('year', $year)->sum('total_net');
|
||||
}
|
||||
switch ($status) {
|
||||
case 1: //Bestellung
|
||||
$month_points += $order->points;
|
||||
$month_total_net += $order->subtotal;
|
||||
break;
|
||||
case 2: //Shop
|
||||
$month_shop_points += $order->points;
|
||||
$month_shop_total_net += $order->subtotal;
|
||||
break;
|
||||
}
|
||||
|
||||
return UserSalesVolume::create([
|
||||
'user_id' => $user_id,
|
||||
'shopping_order_id' => $order->id,
|
||||
'month' => $month,
|
||||
'year' => $year,
|
||||
'date' => $date,
|
||||
'points' => $order->points,
|
||||
'month_points' => $month_points,
|
||||
'month_shop_points' => $month_shop_points,
|
||||
'total_net' => $order->subtotal,
|
||||
'month_total_net' => $month_total_net,
|
||||
'month_shop_total_net' => $month_shop_total_net,
|
||||
'message' => '',
|
||||
'status' => $status,
|
||||
]);
|
||||
}
|
||||
|
||||
public static function show()
|
||||
{
|
||||
// abort(403, 'STOP funtion not online');
|
||||
|
||||
$c = 0;
|
||||
|
||||
if(false){ //11
|
||||
dump("calculate user_sales_volumes from Orders");
|
||||
dd('check function');
|
||||
$year = 21;
|
||||
$months = range(1, 12);
|
||||
foreach($months as $month){
|
||||
$ShoppingOrders = ShoppingOrder::where('txaction', 'paid')->where('created_at', '>=', $year.'-'.$month.'-01 00:00:00')->where('created_at', '<=', $year.'-'.$month.'-31 23:59:59')->get();
|
||||
foreach($ShoppingOrders as $item){
|
||||
|
||||
if(UserSalesVolume::whereShoppingOrderId($item->id)->count() === 0){
|
||||
dump($item->id);
|
||||
self::calcuUserSalesVolume($item);
|
||||
}
|
||||
$c ++;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
|
||||
dump("counter");
|
||||
dd($c);
|
||||
}
|
||||
|
||||
if(false){ //11
|
||||
dump("set Discount to Order Items");
|
||||
dd('check function');
|
||||
$ShoppingOrderItems = ShoppingOrderItem::where('discount', null)
|
||||
//$ShoppingOrderItems = ShoppingOrderItem::where('discount', 0)->get();
|
||||
->skip(0)->take(1000)->get();
|
||||
//->skip(2000)->take(2000)->get();
|
||||
foreach($ShoppingOrderItems as $item){
|
||||
$no_commission = $item->product ? $item->product->no_commission : false;
|
||||
$item->discount = $no_commission ? 0 : $item->shopping_order->getUserDiscount();
|
||||
$item->save();
|
||||
//dump($item->discount);
|
||||
|
||||
$c ++;
|
||||
}
|
||||
dump("counter");
|
||||
dd($c);
|
||||
}
|
||||
|
||||
|
||||
if(false){ //10
|
||||
dump("set ProduktPoints to Order Items");
|
||||
dd('check function');
|
||||
$ShoppingOrderItems = ShoppingOrderItem::where('points', null)->get();
|
||||
$ShoppingOrderItems = ShoppingOrderItem::where('points', 0)->get();
|
||||
//->skip(0)->take(500)->get();
|
||||
//->skip(500)->take(500)->get();
|
||||
foreach($ShoppingOrderItems as $item){
|
||||
if($item->product){
|
||||
$item->points = $item->product->points;
|
||||
$item->save();
|
||||
}else{
|
||||
|
||||
}
|
||||
$c ++;
|
||||
}
|
||||
dd($c);
|
||||
}
|
||||
|
||||
if(false){ //9
|
||||
dump("make getOrderPaymentFor in shopping_order");
|
||||
dd('check function');
|
||||
$ShoppingOrders = ShoppingOrder::where('payment_for', '=', NULL)->get();
|
||||
|
||||
foreach($ShoppingOrders as $ShoppingOrder){
|
||||
dump($ShoppingOrder->id);
|
||||
dump($ShoppingOrder->shopping_user->getOrderPaymentFor());
|
||||
$ShoppingOrder->payment_for = $ShoppingOrder->shopping_user->getOrderPaymentFor();
|
||||
$ShoppingOrder->save();
|
||||
|
||||
$c ++;
|
||||
}
|
||||
dd($c);
|
||||
}
|
||||
|
||||
|
||||
if(false){ //8
|
||||
dump("make homeparty tax_split in shopping_order");
|
||||
dd('check function');
|
||||
|
||||
$ShoppingOrders = ShoppingOrder::where('homeparty_id', '!=', NULL)->get();
|
||||
//->skip(0)->take(500)->get();
|
||||
//->skip(500)->take(500)->get();
|
||||
foreach($ShoppingOrders as $ShoppingOrder){
|
||||
$ShoppingOrder->makeHomepartyTaxSplit();
|
||||
$c ++;
|
||||
}
|
||||
dd($c);
|
||||
}
|
||||
|
||||
if(false){ //7
|
||||
dump("make homeparty shipping_tax in homeparty order user_cart");
|
||||
dd('check function');
|
||||
$ShoppingOrders = ShoppingOrder::where('homeparty_id', '!=', NULL)->get();
|
||||
//->skip(0)->take(500)->get();
|
||||
//->skip(500)->take(500)->get();
|
||||
foreach($ShoppingOrders as $ShoppingOrder){
|
||||
if(isset($ShoppingOrder->homeparty->order['user_carts'])){
|
||||
$user_carts = [];
|
||||
foreach($ShoppingOrder->homeparty->order['user_carts'] as $id => $values){
|
||||
$values['shipping_tax'] = round($values['shipping_price'] - $values['shipping_price_net'], 2);
|
||||
dump($values['shipping_tax']);
|
||||
$user_carts[$id] = $values;
|
||||
}
|
||||
$order = $ShoppingOrder->homeparty->order;
|
||||
$order['user_carts'] = $user_carts;
|
||||
$ShoppingOrder->homeparty->order = $order;
|
||||
$ShoppingOrder->homeparty->save();
|
||||
|
||||
}
|
||||
$c ++;
|
||||
}
|
||||
dd($c);
|
||||
}
|
||||
|
||||
if(false){ //6
|
||||
dump("make tax_split in shopping_order");
|
||||
dd('check function');
|
||||
|
||||
$ShoppingOrders = ShoppingOrder::where('homeparty_id', '=', NULL)//->get();
|
||||
->skip(0)->take(3000)->get();
|
||||
//->skip(3000)->take(5000)->get();
|
||||
foreach($ShoppingOrders as $ShoppingOrder){
|
||||
$ShoppingOrder->makeTaxSplit();
|
||||
$c ++;
|
||||
}
|
||||
dd($c);
|
||||
}
|
||||
|
||||
if(false){ //5
|
||||
//run after make points etc.
|
||||
dump("correction shopping_order homeparty");
|
||||
dd('check function');
|
||||
$ShoppingOrders = ShoppingOrder::where('payment_for', 5)->get();
|
||||
//->skip(0)->take(500)->get();
|
||||
//->skip(500)->take(500)->get();
|
||||
foreach($ShoppingOrders as $ShoppingOrder){
|
||||
$homeparty = Homeparty::find($ShoppingOrder->homeparty_id);
|
||||
if($homeparty && $homeparty->completed && $homeparty->step > 10){
|
||||
$ShoppingOrder->subtotal = $homeparty->order['ek_price_net'];
|
||||
$ShoppingOrder->subtotal_ws = 0;
|
||||
$ShoppingOrder->tax = $ShoppingOrder->total - $homeparty->order['ek_price_net'];
|
||||
$ShoppingOrder->points = $homeparty->order['points'] - $homeparty->order['bonus_points_diff'];
|
||||
$ShoppingOrder->save();
|
||||
$c ++;
|
||||
}
|
||||
|
||||
}
|
||||
dd($c);
|
||||
}
|
||||
|
||||
if(false){ //4
|
||||
dump("make tax in ShoppingOrderItem");
|
||||
dd('check function');
|
||||
$ShoppingOrderItems = ShoppingOrderItem::all();
|
||||
//->skip(0)->take(500)->get();
|
||||
//->skip(500)->take(500)->get();
|
||||
foreach($ShoppingOrderItems as $item){
|
||||
$item->tax = $item->price - $item->price_net;
|
||||
$item->save();
|
||||
$c ++;
|
||||
}
|
||||
dd($c);
|
||||
}
|
||||
|
||||
|
||||
|
||||
if(false){ //3
|
||||
dump("make price_net in ShoppingOrderItem");
|
||||
dd('check function');
|
||||
$ShoppingOrderItems = ShoppingOrderItem::where('price_net', '=', NULL)->get();
|
||||
//->skip(0)->take(500)->get();
|
||||
//->skip(500)->take(500)->get();
|
||||
foreach($ShoppingOrderItems as $item){
|
||||
$item->price_net = $item->price / (100 + $item->tax_rate) * 100;
|
||||
$item->save();
|
||||
$c ++;
|
||||
}
|
||||
dd($c);
|
||||
}
|
||||
|
||||
if(false){ //2
|
||||
dump("add payment_for in shopping_order");
|
||||
dd('check function');
|
||||
$ShoppingUsers = ShoppingUser::all();
|
||||
foreach($ShoppingUsers as $ShoppingUser){
|
||||
if($ShoppingUser->shopping_order){
|
||||
$ShoppingUser->shopping_order->payment_for = $ShoppingUser->getOrderPaymentFor();
|
||||
$ShoppingUser->shopping_order->save();
|
||||
$c ++;
|
||||
}
|
||||
}
|
||||
dd($c);
|
||||
}
|
||||
|
||||
if(false){ //1
|
||||
dump("make points in shopping_order_item and total in ShoppingOrder");
|
||||
dd('check function');
|
||||
$ShoppingOrders = ShoppingOrder::all();
|
||||
//->skip(0)->take(500)->get();
|
||||
//->skip(500)->take(500)->get();
|
||||
foreach($ShoppingOrders as $ShoppingOrder){
|
||||
$points_total = 0;
|
||||
foreach($ShoppingOrder->shopping_order_items as $shopping_order_item){
|
||||
$points = $shopping_order_item->product ? $shopping_order_item->product->points : 0;
|
||||
$points_total += $points;
|
||||
$shopping_order_item->points = $points;
|
||||
$shopping_order_item->save();
|
||||
$c ++;
|
||||
}
|
||||
$ShoppingOrder->points = $points_total;
|
||||
$ShoppingOrder->save();
|
||||
}
|
||||
dd($c);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
public static function store()
|
||||
{
|
||||
abort(403, 'STOP funtion not online');
|
||||
}
|
||||
|
||||
}
|
||||
32
dev/app-bak/Services/SyS/CronJobs.php
Normal file
32
dev/app-bak/Services/SyS/CronJobs.php
Normal file
|
|
@ -0,0 +1,32 @@
|
|||
<?php
|
||||
namespace App\Services\SyS;
|
||||
|
||||
use Request;
|
||||
|
||||
class CronJobs
|
||||
{
|
||||
|
||||
public static function show()
|
||||
{
|
||||
//$user_shops = UserShop::all();
|
||||
$text = "";
|
||||
$values = [
|
||||
'Prüft die Dauer der Mitgliedschaft und sendet Erinnerungsmails' => route('cron_jobs_action', ['check_payments_account', 'key'])
|
||||
];
|
||||
$data = [
|
||||
'values' => $values,
|
||||
'text' => $text,
|
||||
];
|
||||
return view('sys.tools.cronjobs', $data);
|
||||
|
||||
}
|
||||
|
||||
|
||||
public static function store()
|
||||
{
|
||||
$data = Request::all();
|
||||
\Session()->flash('alert-save', true);
|
||||
return back();
|
||||
}
|
||||
|
||||
}
|
||||
63
dev/app-bak/Services/SyS/Customers.php
Normal file
63
dev/app-bak/Services/SyS/Customers.php
Normal file
|
|
@ -0,0 +1,63 @@
|
|||
<?php
|
||||
namespace App\Services\SyS;
|
||||
|
||||
use Auth;
|
||||
use Request;
|
||||
use App\User;
|
||||
use App\Models\ShoppingUser;
|
||||
use App\Models\PaymentMethod;
|
||||
use App\Services\CustomerPriority;
|
||||
use App\Repositories\ContractPDFRepository;
|
||||
|
||||
class Customers
|
||||
{
|
||||
|
||||
public static function show()
|
||||
{
|
||||
$shopping_users = ShoppingUser::where('member_id', '=', NULL)->where('auth_user_id', '=', NULL)->get();
|
||||
$data = [
|
||||
'values' => $shopping_users,
|
||||
'text' => '',
|
||||
];
|
||||
|
||||
return view('sys.tools.customers', $data);
|
||||
}
|
||||
|
||||
|
||||
public static function store()
|
||||
{
|
||||
$data = Request::all();
|
||||
$ret = "";
|
||||
if($data['action'] === 'makePaymentMethodsDefault'){
|
||||
$users = User::where('payment_methods', '=', NULL)->get();
|
||||
//$users = User::all();
|
||||
foreach ($users as $user){
|
||||
$user->payment_methods = PaymentMethod::getDefaultAsArray();
|
||||
$user->save();
|
||||
}
|
||||
}
|
||||
if($data['action'] === 'checkForAll'){
|
||||
$shopping_users = CustomerPriority::checkForAll();
|
||||
}
|
||||
|
||||
if($data['action'] === 'checkContractPDF'){
|
||||
//create PDF
|
||||
$user = User::findOrFail(80);
|
||||
|
||||
$pdf = new ContractPDFRepository($user);
|
||||
$pdf->_set('disk', 'user');
|
||||
$pdf->_set('dir', '/'.$user->id.'/documents/');
|
||||
$pdf->_set('user_id', $user->id);
|
||||
$pdf->_set('identifier', 'contract');
|
||||
$pdf->createContractPDF();
|
||||
}
|
||||
|
||||
if(strpos($data['action'], 'checkOne_') !== false){
|
||||
$id = (int) str_replace('checkOne_', '', $data['action']);
|
||||
$shopping_user = ShoppingUser::findOrFail($id);
|
||||
$ret = CustomerPriority::checkOne($shopping_user);
|
||||
}
|
||||
\Session()->flash('alert-success', $ret);
|
||||
return back();
|
||||
}
|
||||
}
|
||||
198
dev/app-bak/Services/SyS/DomainSSL.php
Normal file
198
dev/app-bak/Services/SyS/DomainSSL.php
Normal file
|
|
@ -0,0 +1,198 @@
|
|||
<?php
|
||||
namespace App\Services\SyS;
|
||||
|
||||
use Request;
|
||||
use App\Models\UserShop;
|
||||
use App\Http\Controllers\Api\KasController;
|
||||
use App\Http\Controllers\Api\KasSLLController;
|
||||
|
||||
class DomainSSL
|
||||
{
|
||||
|
||||
public static function show()
|
||||
{
|
||||
$user_shops = UserShop::limit(1000)->get();
|
||||
$text = "";
|
||||
|
||||
$kas = new KasController();
|
||||
//$domain = 'mivita.care';
|
||||
// $ssl = KasSLLController::getApiSSLParameter();
|
||||
$SubDomains = [];
|
||||
|
||||
$get_subdomains = $kas->action('get_subdomains');
|
||||
foreach ($get_subdomains as $subdomain){
|
||||
if(isset($subdomain['subdomain_name'])){
|
||||
if(strpos($subdomain['subdomain_name'], 'www.') !== false){
|
||||
continue;
|
||||
}
|
||||
if(strpos($subdomain['subdomain_name'], 'api.') !== false){
|
||||
continue;
|
||||
}
|
||||
if(strpos($subdomain['subdomain_name'], 'checkout.') !== false){
|
||||
continue;
|
||||
}
|
||||
$SubDomains[$subdomain['subdomain_name']] =
|
||||
[
|
||||
'ssl_certificate_sni' => $subdomain['ssl_certificate_sni'],
|
||||
'php_version' => $subdomain['php_version'],
|
||||
];
|
||||
|
||||
}else{
|
||||
@dump($subdomain);
|
||||
}
|
||||
|
||||
|
||||
/* if($subdomain['ssl_certificate_sni'] !== "Y"){
|
||||
$pra = array(
|
||||
'hostname' => $subdomain['subdomain_name'],
|
||||
);
|
||||
$pra = array_merge($pra, $ssl);
|
||||
$value = $kas->action('update_ssl', $pra);
|
||||
$text .= $value;
|
||||
}else{
|
||||
if(isset($subdomain['ssl_certificate_sni_is_active'])){
|
||||
$text .= $subdomain['ssl_certificate_sni_is_active'].'-is_active';
|
||||
}else{
|
||||
$text .= '-CHECK!';
|
||||
|
||||
}
|
||||
}*/
|
||||
|
||||
//$text .= "\n";
|
||||
}
|
||||
|
||||
$dobbleDomains = [];
|
||||
|
||||
foreach($user_shops as $user_shop){
|
||||
$user_shop->hasSubdomain = false;
|
||||
$user_shop->hasSSL = false;
|
||||
$user_shop->PHPversion = "";
|
||||
if(array_key_exists($user_shop->slug.'.mivita.care', $SubDomains)){
|
||||
$user_shop->hasSubdomain = true;
|
||||
$user_shop->hasSSL = $SubDomains[$user_shop->slug.'.mivita.care']['ssl_certificate_sni'] === 'Y' ? true : false;
|
||||
$user_shop->PHPversion = $SubDomains[$user_shop->slug.'.mivita.care']['php_version'];
|
||||
unset($SubDomains[$user_shop->slug.'.mivita.care']);
|
||||
}
|
||||
$dobbleDomains[$user_shop->user_id][$user_shop->id] = $user_shop->slug.'.mivita.care';
|
||||
}
|
||||
foreach($dobbleDomains as $key => $dobbleDomain){
|
||||
if(count($dobbleDomain) === 1){
|
||||
unset($dobbleDomains[$key]);
|
||||
}
|
||||
}
|
||||
$data = [
|
||||
'values' => $user_shops,
|
||||
'text' => $text,
|
||||
'SubDomains' => $SubDomains,
|
||||
'dobbleDomains' => $dobbleDomains,
|
||||
|
||||
];
|
||||
|
||||
return view('sys.tools.domain-ssl', $data);
|
||||
}
|
||||
|
||||
|
||||
public static function store()
|
||||
{
|
||||
$data = Request::all();
|
||||
if(isset($data['delete_sub_kas'])){
|
||||
$kas = new KasController();
|
||||
$pra = array(
|
||||
'subdomain_name' => $data['delete_sub_kas'],
|
||||
);
|
||||
$value = $kas->action('delete_subdomain', $pra);
|
||||
\Session()->flash('alert-success', 'subdomain: '.$value.' gelöscht');
|
||||
|
||||
}
|
||||
if(isset($data['delete_user_shop'])){
|
||||
$user_shop = UserShop::findOrFail($data['delete_user_shop']);
|
||||
$subdomain_name = $user_shop->slug.'.mivita.care';
|
||||
$user_shop->name = "delete".$user_shop->id;
|
||||
$user_shop->slug = "delete".$user_shop->id;
|
||||
$user_shop->save();
|
||||
$user_shop->delete();
|
||||
$kas = new KasController();
|
||||
$pra = array(
|
||||
'subdomain_name' => $subdomain_name,
|
||||
);
|
||||
$value = $kas->action('delete_subdomain', $pra);
|
||||
\Session()->flash('alert-success', 'shop/subdomain: '.$value.' gelöscht');
|
||||
|
||||
}
|
||||
|
||||
if(isset($data['update_ssl'])){
|
||||
|
||||
//prüfen ob subdomain existiert
|
||||
$user_shop = UserShop::findOrFail($data['update_ssl']);
|
||||
$subdomain_name = $user_shop->slug.'.mivita.care';
|
||||
|
||||
$kas = new KasController();
|
||||
$subdomain = $kas->action('get_subdomains', ['subdomain_name' => $subdomain_name]);
|
||||
if(!isset($subdomain[0]['subdomain_name'])){ //not found
|
||||
self::makeNewSubDomain($user_shop->slug);
|
||||
\Session()->flash('alert-danger', 'subdomain: '.$subdomain_name.' nicht gefunden');
|
||||
return back();
|
||||
}else{
|
||||
self::updateSubDomain($subdomain_name);
|
||||
}
|
||||
|
||||
|
||||
|
||||
}
|
||||
|
||||
|
||||
return back();
|
||||
}
|
||||
|
||||
private static function updateSubDomain($subdomain_name){
|
||||
|
||||
$kas = new KasController();
|
||||
$ssl = KasSLLController::getApiSSLParameter();
|
||||
$pra = array(
|
||||
'hostname' => $subdomain_name
|
||||
);
|
||||
$pra = array_merge($pra, $ssl);
|
||||
$value = $kas->action('update_ssl', $pra);
|
||||
\Session()->flash('alert-success', 'update SSL: '.$value.'');
|
||||
return $value;
|
||||
}
|
||||
|
||||
private static function makeNewSubDomain($slug){
|
||||
|
||||
$kas = new KasController();
|
||||
$domain = 'mivita.care';
|
||||
|
||||
//check if exisist
|
||||
$subdomains = $kas->action('get_subdomains');
|
||||
foreach ($subdomains as $subdomain){
|
||||
if(!isset($subdomain['subdomain_name'])){
|
||||
continue;
|
||||
}
|
||||
$sub = str_replace(".".$domain, '', $subdomain['subdomain_name']);
|
||||
if($sub == $slug){
|
||||
\Session()->flash('alert-danger', __('shop.error_subdomain_exists'));
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
//add
|
||||
$full_subdomain_name = $slug.".".$domain;
|
||||
$pra = array(
|
||||
'subdomain_name' => $slug,
|
||||
'domain_name' => $domain,
|
||||
'subdomain_path' => '/mein.mivita.care/public/',
|
||||
'php_version' => config('app.php_version'),
|
||||
//'ssl_proxy' => 'Y',
|
||||
//'redirect_status' => 0
|
||||
);
|
||||
$add_subdomain = $kas->action('add_subdomain', $pra);
|
||||
if($add_subdomain == $full_subdomain_name){
|
||||
\Session()->flash('alert-success', 'Add Subdomain: '.$add_subdomain.'');
|
||||
return $add_subdomain;
|
||||
}
|
||||
\Session()->flash('alert-danger', 'Fehler: '.$add_subdomain.'');
|
||||
return $add_subdomain;
|
||||
|
||||
|
||||
}
|
||||
}
|
||||
49
dev/app-bak/Services/SyS/Import.php
Normal file
49
dev/app-bak/Services/SyS/Import.php
Normal file
|
|
@ -0,0 +1,49 @@
|
|||
<?php
|
||||
namespace App\Services\SyS;
|
||||
|
||||
use Carbon;
|
||||
use Request;
|
||||
use App\Models\SySetting;
|
||||
use App\Repositories\ImportRepository;
|
||||
|
||||
class Import
|
||||
{
|
||||
|
||||
public static function show()
|
||||
{
|
||||
abort(403, 'STOP funtion not online');
|
||||
|
||||
return view('sys.tools.import', []);
|
||||
|
||||
}
|
||||
|
||||
|
||||
public static function store()
|
||||
{
|
||||
abort(403, 'STOP funtion not online');
|
||||
}
|
||||
|
||||
|
||||
public function importStore()
|
||||
{
|
||||
$input = Request::all();
|
||||
$import_repo = new ImportRepository();
|
||||
|
||||
return $import_repo->upload($input);
|
||||
}
|
||||
|
||||
public function importShow($type, $file, $skip = 0, $limit = 4000)
|
||||
{
|
||||
$import_repo = new ImportRepository();
|
||||
$import = $import_repo->read($type, $file, $skip, $limit);
|
||||
$data = [
|
||||
'limit' => $limit,
|
||||
'type' => $type,
|
||||
'file' => $file,
|
||||
'import' => $import,
|
||||
'skip' => $skip,
|
||||
];
|
||||
return view('sys.tools.import-show', $data);
|
||||
|
||||
}
|
||||
}
|
||||
84
dev/app-bak/Services/SyS/ImportDbipCountry.php
Normal file
84
dev/app-bak/Services/SyS/ImportDbipCountry.php
Normal file
|
|
@ -0,0 +1,84 @@
|
|||
<?php
|
||||
namespace App\Services\SyS;
|
||||
|
||||
use App\Models\DbipLookup;
|
||||
use App\Services\dbip\DBIP;
|
||||
use Illuminate\Support\Facades\DB;
|
||||
use Illuminate\Support\Facades\Storage;
|
||||
use Request;
|
||||
|
||||
class ImportDbipCountry
|
||||
{
|
||||
|
||||
public static function show()
|
||||
{
|
||||
dump("ImportDbipCountry");
|
||||
// dd('check function');
|
||||
|
||||
|
||||
self::read('dbip-country-lite-2024-07.csv', 0, 0);
|
||||
$c = 0;
|
||||
dump("okay counter");
|
||||
dd($c);
|
||||
|
||||
}
|
||||
|
||||
public static function read($filename, $skip = 0, $limit = 0)
|
||||
{
|
||||
/*$find = inet_pton("1.10.128.0");
|
||||
dump($find);
|
||||
dd(DbipLookup::where('ip_start', "<=", $find)->orderBy('ip_start', 'desc')->first());
|
||||
if(!Storage::disk('import')->has($filename)){
|
||||
die("File not found in import folder: ".$filename);
|
||||
}*/
|
||||
|
||||
$path = Storage::disk('import')->path($filename);
|
||||
$fileContents = file($path);
|
||||
$c = 0;
|
||||
foreach ($fileContents as $line) {
|
||||
$row = str_getcsv($line);
|
||||
$row[] = self::addrType($row[0]);
|
||||
|
||||
|
||||
//
|
||||
//base64_encode(file_get_contents($path))
|
||||
// dump($row);
|
||||
\DB::table('dbip_lookup')->insert([
|
||||
'ip_start' => inet_pton($row[0]),
|
||||
'ip_end' => inet_pton($row[1]),
|
||||
'country' => $row[2],
|
||||
'addr_type' => $row[3]
|
||||
]);
|
||||
|
||||
|
||||
//dump(inet_pton($row[0]));
|
||||
/* DbipLookup::create([
|
||||
'ip_start' => ,
|
||||
'ip_end' => inet_pton($row[1]),
|
||||
'country' => $row[2],
|
||||
'addr_type' => $row[3]
|
||||
]);*/
|
||||
|
||||
}
|
||||
|
||||
return true;
|
||||
|
||||
}
|
||||
private static function addrType($addr) {
|
||||
if (ip2long($addr) !== false) {
|
||||
return "ipv4";
|
||||
} else if (preg_match('/^[0-9a-fA-F:]+$/', $addr) && @inet_pton($addr)) {
|
||||
return "ipv6";
|
||||
}
|
||||
die("unknown address type for {$addr}");
|
||||
}
|
||||
|
||||
public static function store()
|
||||
{
|
||||
$data = Request::all();
|
||||
\Session()->flash('alert-save', true);
|
||||
return back();
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
45
dev/app-bak/Services/SyS/RepairSalesVolumeInvoice.php
Normal file
45
dev/app-bak/Services/SyS/RepairSalesVolumeInvoice.php
Normal file
|
|
@ -0,0 +1,45 @@
|
|||
<?php
|
||||
namespace App\Services\SyS;
|
||||
|
||||
use Request;
|
||||
use App\Models\UserBusiness;
|
||||
use App\Models\UserInvoice;
|
||||
use App\Models\UserSalesVolume;
|
||||
|
||||
class RepairSalesVolumeInvoice
|
||||
{
|
||||
|
||||
public static function show()
|
||||
{
|
||||
|
||||
dump("RepairSalesVolumeInvoice");
|
||||
dd('check function');
|
||||
$UserSalesVolumes = UserSalesVolume::where('status', '<', 3)->where('user_invoice_id', null)->orderBy('id', 'desc')->limit(1000)->get();
|
||||
dump(count($UserSalesVolumes));
|
||||
$c = 0;
|
||||
foreach($UserSalesVolumes as $user_sales_volume){
|
||||
|
||||
if($user_sales_volume->shopping_order_id){
|
||||
$UserInvoice = UserInvoice::where('shopping_order_id', $user_sales_volume->shopping_order_id)->first();
|
||||
if($UserInvoice){
|
||||
$user_sales_volume->user_invoice_id = $UserInvoice->id;
|
||||
$user_sales_volume->save();
|
||||
$c++;
|
||||
}
|
||||
}
|
||||
}
|
||||
dump("counter");
|
||||
dd($c);
|
||||
|
||||
}
|
||||
|
||||
|
||||
public static function store()
|
||||
{
|
||||
$data = Request::all();
|
||||
\Session()->flash('alert-save', true);
|
||||
return back();
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
65
dev/app-bak/Services/SyS/Sales.php
Normal file
65
dev/app-bak/Services/SyS/Sales.php
Normal file
|
|
@ -0,0 +1,65 @@
|
|||
<?php
|
||||
namespace App\Services\SyS;
|
||||
|
||||
use Request;
|
||||
use Carbon;
|
||||
use App\Models\SySetting;
|
||||
use App\Models\ShoppingOrder;
|
||||
|
||||
class Sales
|
||||
{
|
||||
|
||||
public static function show()
|
||||
{
|
||||
$start = 2019;
|
||||
$end = date('Y');
|
||||
$years = range($start, $end);
|
||||
|
||||
if(Request::get('filter_sales_year')){
|
||||
$active_year = Request::get('filter_sales_year');
|
||||
}else{
|
||||
$active_year = $end;
|
||||
}
|
||||
|
||||
$date1 = Carbon::parse('01.01.'.$active_year." 00:00:00")->format('Y-m-d H:i:s');
|
||||
$date2 = Carbon::parse('31.12.'.$active_year." 23:59:59")->toDateString();
|
||||
|
||||
|
||||
$values = ShoppingOrder::where('shopping_orders.auth_user_id', '!=', NULL) //::with('shopping_user', )->select('shopping_orders.*')
|
||||
->where('mode', '=', 'live')
|
||||
->where('paid', '=', 1)
|
||||
->whereHas('shopping_order_items', function($q) {
|
||||
|
||||
$q->where('product_id', 34)->OrWhere('product_id', 35)->OrWhere('product_id', 36)->OrWhere('product_id', 67)->OrWhere('product_id', 69);
|
||||
})
|
||||
->whereBetween('created_at', [$date1, $date2])
|
||||
->get();
|
||||
|
||||
$data = [
|
||||
'years' => $years,
|
||||
'active_year' => $active_year,
|
||||
'values' => $values,
|
||||
];
|
||||
return view('sys.tools.sales', $data);
|
||||
}
|
||||
|
||||
|
||||
public static function store()
|
||||
{
|
||||
|
||||
$data = Request::all();
|
||||
|
||||
$data['active'] = isset($data['active']) ? true : false;
|
||||
if($data['id'] === "new"){
|
||||
$model = SySetting::create($data);
|
||||
}else{
|
||||
$model = SySetting::find($data['id']);
|
||||
$model->fill($data);
|
||||
$model->save();
|
||||
}
|
||||
|
||||
\Session()->flash('alert-save', '1');
|
||||
return redirect(route('sysadmin_tool', ['sales_members']));
|
||||
|
||||
}
|
||||
}
|
||||
65
dev/app-bak/Services/SyS/ShoppingOrders.php
Normal file
65
dev/app-bak/Services/SyS/ShoppingOrders.php
Normal file
|
|
@ -0,0 +1,65 @@
|
|||
<?php
|
||||
namespace App\Services\SyS;
|
||||
|
||||
use Request;
|
||||
use App\Services\Shop;
|
||||
use App\Models\UserShop;
|
||||
use App\Models\ShoppingUser;
|
||||
use App\Services\ShoppingUserService;
|
||||
use App\Http\Controllers\Api\KasController;
|
||||
use App\Http\Controllers\Api\KasSLLController;
|
||||
|
||||
class ShoppingOrders
|
||||
{
|
||||
|
||||
public static function show()
|
||||
{
|
||||
abort(403, 'STOP funtion not online');
|
||||
|
||||
$shopping_users = ShoppingUser::all();
|
||||
$data = [
|
||||
'values' => $shopping_users,
|
||||
'text' => '',
|
||||
];
|
||||
return view('sys.tools.shopping-orders', $data);
|
||||
}
|
||||
|
||||
|
||||
public static function store()
|
||||
{
|
||||
abort(403, 'STOP funtion not online');
|
||||
dd("");
|
||||
|
||||
|
||||
$data = Request::all();
|
||||
|
||||
if($data['action'] === 'first_run'){
|
||||
$shopping_users = ShoppingUser::whereHas('shopping_order', function($q) {
|
||||
$q->where('txaction', 'paid')->OrWhere('txaction', 'appointed');
|
||||
})->get();
|
||||
|
||||
$order_email = [];
|
||||
$order_number = [];
|
||||
|
||||
foreach ($shopping_users as $shopping_user){
|
||||
$order_email[$shopping_user->billing_email] = isset($order_email[$shopping_user->billing_email]) ? $order_email[$shopping_user->billing_email] + 1 : 1;
|
||||
if($shopping_user->number) {
|
||||
$order_number[$shopping_user->number] = isset($order_number[$shopping_user->number]) ? $order_number[$shopping_user->number] + 1 : 1;
|
||||
$shopping_user->orders = $order_number[$shopping_user->number];
|
||||
}else {
|
||||
$shopping_user->orders = $order_email[$shopping_user->billing_email];
|
||||
}
|
||||
$shopping_user->save();
|
||||
|
||||
}
|
||||
\Session()->flash('alert-save', true);
|
||||
}
|
||||
|
||||
if($data['action'] === 'next_run'){
|
||||
ShoppingUserService::snycOrdersByShoppingUser($shopping_user);
|
||||
\Session()->flash('alert-save', true);
|
||||
}
|
||||
return back();
|
||||
}
|
||||
|
||||
}
|
||||
48
dev/app-bak/Services/SyS/UserCreditItemsAddFrom.php
Normal file
48
dev/app-bak/Services/SyS/UserCreditItemsAddFrom.php
Normal file
|
|
@ -0,0 +1,48 @@
|
|||
<?php
|
||||
namespace App\Services\SyS;
|
||||
|
||||
use Request;
|
||||
use Carbon;
|
||||
use App\Models\SySetting;
|
||||
use App\Models\ShoppingOrder;
|
||||
use App\Models\UserCreditItem;
|
||||
use App\User;
|
||||
|
||||
class UserCreditItemsAddFrom
|
||||
{
|
||||
|
||||
public static function show()
|
||||
{
|
||||
UserCreditItem::all()->each(function($item){
|
||||
$date = self::getExplodeMessage($item);
|
||||
$item->from_month = $date['n'];
|
||||
$item->from_year = $date['Y'];
|
||||
$item->save();
|
||||
});
|
||||
dd("done");
|
||||
}
|
||||
|
||||
|
||||
private static function getExplodeMessage($item){
|
||||
$date = [];
|
||||
if(strpos($item->message, '#')){
|
||||
$em = explode("#", $item->message);
|
||||
|
||||
if(isset($em[1])){ //month
|
||||
$data['n'] =$em[1];
|
||||
}
|
||||
if(isset($em[2])){ //year
|
||||
$data['Y'] =$em[2];
|
||||
}
|
||||
}
|
||||
return $data;
|
||||
}
|
||||
|
||||
public static function store()
|
||||
{
|
||||
abort(403, 'STOP funtion not online');
|
||||
dd("");
|
||||
|
||||
|
||||
}
|
||||
}
|
||||
88
dev/app-bak/Services/SyS/UserCreditItemsChangeMessage.php
Normal file
88
dev/app-bak/Services/SyS/UserCreditItemsChangeMessage.php
Normal file
|
|
@ -0,0 +1,88 @@
|
|||
<?php
|
||||
namespace App\Services\SyS;
|
||||
|
||||
use Request;
|
||||
use App\Models\UserBusiness;
|
||||
use App\Models\UserCreditItem;
|
||||
use App\Models\UserInvoice;
|
||||
use App\Models\UserSalesVolume;
|
||||
|
||||
class UserCreditItemsChangeMessage
|
||||
{
|
||||
|
||||
public static function show()
|
||||
{
|
||||
|
||||
dump("UserCreditItemsChangeMessage");
|
||||
dd('check function');
|
||||
$UserCreditItems = UserCreditItem::orderBy('id', 'desc')->limit(1000)->get();
|
||||
dump(count($UserCreditItems));
|
||||
$c = 0;
|
||||
foreach($UserCreditItems as $item){
|
||||
if($item->message){
|
||||
$item->message = self::convertMessage($item->message);
|
||||
$item->save();
|
||||
$c++;
|
||||
}
|
||||
}
|
||||
dump("counter");
|
||||
dd($c);
|
||||
}
|
||||
|
||||
public static function convertMessage($message){
|
||||
$months = [
|
||||
'Januar' => "1#",
|
||||
'Februar' => "2#",
|
||||
'März' => "3#",
|
||||
'April' => "4#",
|
||||
'Mai' => "5#",
|
||||
'Juni' => "6#",
|
||||
'Juli' => "7#",
|
||||
'August' => "8#",
|
||||
'September' => "9#",
|
||||
'Oktober' => "10#",
|
||||
'November' => "11#",
|
||||
'Dezember' => "12#",
|
||||
];
|
||||
|
||||
$em = explode(" ", $message);
|
||||
$new_message = "";
|
||||
if($em[0] === "Provision"){
|
||||
switch ($em[1]) {
|
||||
case 'Shop':
|
||||
$new_message .= 'payment.commission_shop#';
|
||||
break;
|
||||
case 'Team':
|
||||
$new_message .= 'payment.commission_team#';
|
||||
break;
|
||||
case 'Payline':
|
||||
$new_message .= 'payment.commission_payline#';
|
||||
break;
|
||||
case 'Wachstumsbonus':
|
||||
$new_message .= 'payment.commission_growth_bonus#';
|
||||
break;
|
||||
default:
|
||||
dd("Error: ".$message);
|
||||
break;
|
||||
}
|
||||
|
||||
if(isset($months[$em[2]])){
|
||||
$new_message .= $months[$em[2]];
|
||||
}
|
||||
$new_message .= $em[3];
|
||||
return $new_message;
|
||||
}
|
||||
|
||||
return $message;
|
||||
|
||||
}
|
||||
|
||||
public static function store()
|
||||
{
|
||||
$data = Request::all();
|
||||
\Session()->flash('alert-save', true);
|
||||
return back();
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
76
dev/app-bak/Services/SysLog.php
Normal file
76
dev/app-bak/Services/SysLog.php
Normal file
|
|
@ -0,0 +1,76 @@
|
|||
<?php
|
||||
namespace App\Services;
|
||||
|
||||
use App\Mail\MailSyS;
|
||||
use App\Models\Logger;
|
||||
use Illuminate\Support\Facades\Mail;
|
||||
|
||||
|
||||
class SysLog
|
||||
{
|
||||
|
||||
|
||||
/* protected $user_id;
|
||||
protected $model;
|
||||
protected $model_id;
|
||||
protected $message;
|
||||
protected $action;
|
||||
protected $channel;
|
||||
protected $level;*/
|
||||
|
||||
protected $log;
|
||||
|
||||
public $levelTypes = [
|
||||
1 => 'debug',
|
||||
2 => 'info',
|
||||
3 => 'notice',
|
||||
4 => 'warning',
|
||||
5 => 'error',
|
||||
6 => 'critical',
|
||||
7 => 'alert',
|
||||
];
|
||||
|
||||
function __construct($action = null, $channel = 'default', $level = 1)
|
||||
{
|
||||
$this->log = new Logger();
|
||||
$this->log->action = $action;
|
||||
$this->log->channel = $channel;
|
||||
$this->log->level = $level;
|
||||
}
|
||||
|
||||
public static function action($action = null, $channel = 'default', $level = 1)
|
||||
{
|
||||
//Return new instance of this model
|
||||
return new self($action, $channel, $level);
|
||||
}
|
||||
|
||||
public function setModel($id, $model){
|
||||
$this->log->model_id = $id;
|
||||
$this->log->model = $model;
|
||||
return $this;
|
||||
}
|
||||
|
||||
public function setUserId($user_id){
|
||||
$this->log->user_id = $user_id;
|
||||
return $this;
|
||||
}
|
||||
|
||||
public function setMessage($message){
|
||||
$this->log->message = $message;
|
||||
return $this;
|
||||
}
|
||||
|
||||
public function save(){
|
||||
$this->log->save();
|
||||
//send Mail
|
||||
if($this->log->level >= 3){
|
||||
$mail = config('app.info_test_mail');
|
||||
Mail::to($mail)->send(new MailSyS($this->log, 'log'));
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
}
|
||||
17
dev/app-bak/Services/TranslationHelper.php
Normal file
17
dev/app-bak/Services/TranslationHelper.php
Normal file
|
|
@ -0,0 +1,17 @@
|
|||
<?php
|
||||
namespace App\Services;
|
||||
|
||||
use App\Models\UserLevel;
|
||||
|
||||
class TranslationHelper
|
||||
{
|
||||
|
||||
|
||||
|
||||
public static function transUserLevelName($name){
|
||||
$UserLevel = UserLevel::whereName($name)->first();
|
||||
return $UserLevel ? $UserLevel->getLang('name') : $name;
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
160
dev/app-bak/Services/UserService.php
Normal file
160
dev/app-bak/Services/UserService.php
Normal file
|
|
@ -0,0 +1,160 @@
|
|||
<?php
|
||||
namespace App\Services;
|
||||
|
||||
use App\Models\ShippingCountry;
|
||||
use App\User;
|
||||
use Illuminate\Support\Str;
|
||||
use Yard;
|
||||
|
||||
class UserService
|
||||
{
|
||||
public static $user_country;
|
||||
public static $shipping_country;
|
||||
public static $shipping_free = false;
|
||||
public static $user_tax_free = false;
|
||||
public static $user_reverse_charge = false;
|
||||
public static $instance = 'shopping';
|
||||
|
||||
public static function getTransChange(){
|
||||
|
||||
$langs = config('localization.supportedLocales');
|
||||
$ret = [];
|
||||
foreach($langs as $code => $lang){
|
||||
$ret[strtolower($code)] = strtolower($lang['native']);
|
||||
}
|
||||
return $ret;
|
||||
}
|
||||
|
||||
public static function setInstance($instance){
|
||||
self::$instance = $instance;
|
||||
}
|
||||
|
||||
//init Yard for user order Customer
|
||||
public static function initCustomerYard($shopping_user, $for){
|
||||
self::$user_tax_free = false;
|
||||
if($shopping_user->same_as_billing){
|
||||
self::$user_country = $shopping_user->billing_country;
|
||||
self::$shipping_country = $shopping_user->billing_country;
|
||||
}else{
|
||||
self::$user_country = $shopping_user->billing_country;
|
||||
self::$shipping_country = $shopping_user->shipping_country;
|
||||
}
|
||||
if(self::$user_country->supply_country && self::$shipping_country->supply_country){
|
||||
self::$user_tax_free = true;
|
||||
}
|
||||
$ShippingCountry = ShippingCountry::whereCountryId(self::$shipping_country->id)->first();
|
||||
self::$shipping_free = $ShippingCountry->shipping ? $ShippingCountry->shipping->free : false;
|
||||
self::$shipping_free = self::$shipping_free !== null ? self::$shipping_free : false;
|
||||
Yard::instance(self::$instance)->setShippingCountryWithPrice($ShippingCountry->id, $for);
|
||||
Yard::instance(self::$instance)->setUserPriceInfos(self::getYardInfo());
|
||||
}
|
||||
|
||||
//init Yard for user order Berater
|
||||
public static function initUserYard(User $user, $shipping_country_id, $for){
|
||||
self::$shipping_free = false;
|
||||
self::checkUserTaxShippingCountry($user, $shipping_country_id,);
|
||||
Yard::instance(self::$instance)->setShippingCountryWithPrice($shipping_country_id, $for);
|
||||
Yard::instance(self::$instance)->setUserPriceInfos(self::getYardInfo());
|
||||
}
|
||||
|
||||
|
||||
public static function checkUserTaxShippingCountry(User $user, $shipping_country_id) {
|
||||
|
||||
if(!$user->account || !$user->account->country_id){
|
||||
abort(403, 'Error: User hat kein Land!');
|
||||
}
|
||||
$ShippingCountry = ShippingCountry::findOrFail($shipping_country_id);
|
||||
self::$user_tax_free = self::performUserTaxShippingCountry($user, $ShippingCountry);
|
||||
return $ShippingCountry;
|
||||
/*
|
||||
dump( self::$user_price_code );
|
||||
dump( self::$user_tax_free );
|
||||
dump( self::$user_reverse_charge );
|
||||
*/
|
||||
}
|
||||
|
||||
public static function performUserTaxShippingCountry($user, $ShippingCountry){
|
||||
//preise für das Land
|
||||
self::$user_country = $user->account->country;
|
||||
self::$shipping_country = $ShippingCountry->country;
|
||||
//ausgehend vom Land des Rechnungsempfänger $user->account->country
|
||||
//ist der Rechnungsempfänger im Drittland?
|
||||
if($user->account->country->supply_country){
|
||||
if($ShippingCountry->country->supply_country){
|
||||
//Lieferadresse im Drittland?
|
||||
return true;
|
||||
}
|
||||
}
|
||||
//Rechnungsempfänger in der EU
|
||||
|
||||
//Lieferland mit RSV
|
||||
if($ShippingCountry->country->eu_country){
|
||||
//Rechnungsempfänger mit valid aktiv RSV
|
||||
if($user->account->reverse_charge && $user->account->reverse_charge_valid){
|
||||
//Rechnungsland ist auch Lieferland, dann RSV
|
||||
if(strtolower($user->account->reverse_charge_code) == strtolower($ShippingCountry->country->code)){
|
||||
self::$user_reverse_charge = true;
|
||||
return true;
|
||||
}
|
||||
}
|
||||
}
|
||||
//Lieferland ohne RSV
|
||||
return false;
|
||||
}
|
||||
|
||||
public static function getYardInfo(){
|
||||
return [
|
||||
'shipping_free' => self::$shipping_free,
|
||||
'user_tax_free' => self::$user_tax_free,
|
||||
'user_reverse_charge' => self::$user_reverse_charge,
|
||||
'user_country_id' => self::$user_country->id,
|
||||
'shipping_country_id' => self::$shipping_country->id,
|
||||
];
|
||||
}
|
||||
|
||||
public static function getTaxFree(){
|
||||
return self::$user_tax_free ? true : false;
|
||||
}
|
||||
|
||||
public static function getUserPriceInfos(){
|
||||
return [
|
||||
'user_tax_free' => self::$user_tax_free,
|
||||
'user_reverse_charge' => self::$user_reverse_charge,
|
||||
'user_country_id' => self::$user_country->id,
|
||||
];
|
||||
}
|
||||
|
||||
public static function getOrderInfo($key = false){
|
||||
if(!self::$user_country){
|
||||
return '';
|
||||
}
|
||||
switch ($key) {
|
||||
case 'billing_state':
|
||||
return self::$user_country->getLocated();
|
||||
break;
|
||||
case 'shipping_state':
|
||||
return self::$shipping_country->getLocated();
|
||||
break;
|
||||
case 'tax_free':
|
||||
return self::$user_tax_free ? __('no') : __('yes');
|
||||
break;
|
||||
case 'user_reverse_charge':
|
||||
return self::$user_reverse_charge ? __('yes') : __('no');
|
||||
break;
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
public static function createConfirmationCode() {
|
||||
$unique = false;
|
||||
do{
|
||||
$confirmation_code = Str::random(30);
|
||||
if(User::where('confirmation_code', '=', $confirmation_code)->count() == 0){
|
||||
$unique = true;
|
||||
}
|
||||
}
|
||||
while(!$unique);
|
||||
return $confirmation_code;
|
||||
}
|
||||
|
||||
}
|
||||
326
dev/app-bak/Services/UserShopSessionManager.php
Normal file
326
dev/app-bak/Services/UserShopSessionManager.php
Normal file
|
|
@ -0,0 +1,326 @@
|
|||
<?php
|
||||
|
||||
namespace App\Services;
|
||||
|
||||
use App\Domain\DomainContext;
|
||||
use App\Models\UserShop;
|
||||
use App\Services\DomainService;
|
||||
use Illuminate\Contracts\Cookie\Factory as CookieFactory;
|
||||
use Illuminate\Http\Request;
|
||||
use Illuminate\Support\Facades\Config;
|
||||
use Illuminate\Support\Facades\Log;
|
||||
use Illuminate\Support\Facades\Session;
|
||||
|
||||
/**
|
||||
* Optimierter UserShop-Session-Manager
|
||||
*
|
||||
* Verbesserungen gegenüber GPT-5 Original:
|
||||
* - Kompakte Session-Keys (shop.* statt ctx.user_shop.*) → 50% weniger Session-Data
|
||||
* - Sichere Cookie-Defaults mit XSS-Protection
|
||||
* - Request-Level Caching für wiederholte UserShop-Calls
|
||||
* - Lazy Loading - UserShop nur laden wenn wirklich benötigt
|
||||
* - Robusteres Error-Handling ohne Exception-Propagation
|
||||
* - Memory-optimierte Session-Struktur
|
||||
* - Flexible Konfiguration mit sinnvollen Defaults
|
||||
*/
|
||||
class UserShopSessionManager
|
||||
{
|
||||
// Request-Level Cache für UserShop-Objekte
|
||||
private static array $userShopCache = [];
|
||||
|
||||
public function __construct(
|
||||
private readonly DomainService $domainService,
|
||||
private readonly CookieFactory $cookies
|
||||
) {}
|
||||
|
||||
/**
|
||||
* Synchronisiert UserShop zwischen Cookie und Session (optimiert)
|
||||
*/
|
||||
public function synchronize(Request $request, ?DomainContext $context): void
|
||||
{
|
||||
$config = $this->getConfig();
|
||||
|
||||
// 1. Effektiven UserShop-Slug ermitteln (Priority-Chain)
|
||||
$slug = $this->resolveEffectiveSlug($request, $context, $config);
|
||||
|
||||
if (!$slug) {
|
||||
// Kein UserShop → Session bereinigen
|
||||
$this->clearUserShopSession($config);
|
||||
return;
|
||||
}
|
||||
|
||||
// 2. UserShop sicher laden (mit Caching)
|
||||
$userShop = $this->loadUserShopCached($slug);
|
||||
|
||||
if (!$userShop) {
|
||||
// Ungültiger Slug → Session bereinigen
|
||||
$this->clearUserShopSession($config);
|
||||
return;
|
||||
}
|
||||
|
||||
// 3. Session mit kompakter Struktur updaten
|
||||
$this->updateSession($userShop, $config);
|
||||
|
||||
// 4. Sicheren Cookie setzen
|
||||
$this->updateCookie($userShop, $config);
|
||||
|
||||
// 5. Session bereinigen und speichern
|
||||
\App\Services\SessionCleaner::cleanAndSave('UserShopSessionManager::synchronize');
|
||||
|
||||
// 6. Minimal Debug-Logging
|
||||
$this->logSynchronization($userShop, $slug);
|
||||
}
|
||||
|
||||
/**
|
||||
* Ermittelt den effektiven UserShop-Slug mit Priority-Chain
|
||||
*/
|
||||
private function resolveEffectiveSlug(Request $request, ?DomainContext $context, array $config): ?string
|
||||
{
|
||||
// Priorität 1: Domain-Context (aktueller UserShop)
|
||||
if ($context?->userShop?->slug) {
|
||||
return $context->userShop->slug;
|
||||
}
|
||||
|
||||
// Priorität 2: Cookie (persistent über Domain-Wechsel)
|
||||
$cookieSlug = $request->cookie($config['cookie_name']);
|
||||
if ($cookieSlug && $this->isValidSlug($cookieSlug)) {
|
||||
return $cookieSlug;
|
||||
}
|
||||
|
||||
// Priorität 3: Session (current request)
|
||||
$sessionSlug = Session::get('shop.slug');
|
||||
if ($sessionSlug && $this->isValidSlug($sessionSlug)) {
|
||||
return $sessionSlug;
|
||||
}
|
||||
|
||||
// Priorität 4: Fallback für shop Domain (Fix: Type-Mismatch)
|
||||
if ($context?->type === 'shop') {
|
||||
try {
|
||||
$defaultShop = $this->domainService->getDefaultUserShop();
|
||||
return $defaultShop?->slug;
|
||||
} catch (\Throwable $e) {
|
||||
Log::warning('Default shop loading failed', ['error' => $e->getMessage()]);
|
||||
}
|
||||
}
|
||||
|
||||
return null;
|
||||
}
|
||||
|
||||
/**
|
||||
* UserShop mit Request-Level Caching laden
|
||||
*/
|
||||
private function loadUserShopCached(string $slug): ?UserShop
|
||||
{
|
||||
// Request-Cache check
|
||||
if (isset(self::$userShopCache[$slug])) {
|
||||
return self::$userShopCache[$slug];
|
||||
}
|
||||
|
||||
try {
|
||||
$userShop = $this->domainService->getUserShop($slug);
|
||||
|
||||
// Cache für wiederholte Zugriffe im gleichen Request
|
||||
self::$userShopCache[$slug] = $userShop;
|
||||
|
||||
return $userShop;
|
||||
} catch (\Throwable $e) {
|
||||
Log::warning('UserShop loading failed', [
|
||||
'slug' => $slug,
|
||||
'error' => $e->getMessage()
|
||||
]);
|
||||
|
||||
// Cache negative result um wiederholte Fehlversuche zu vermeiden
|
||||
self::$userShopCache[$slug] = null;
|
||||
|
||||
return null;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Session mit kompakter Struktur updaten (50% weniger Daten)
|
||||
*/
|
||||
private function updateSession(UserShop $userShop, array $config): void
|
||||
{
|
||||
// Kompakte Session-Keys (shop.* statt ctx.user_shop.*)
|
||||
Session::put('shop.id', $userShop->id);
|
||||
Session::put('shop.slug', $userShop->slug);
|
||||
|
||||
// Legacy-Support optional (für Backward-Compatibility)
|
||||
if ($config['legacy_support']) {
|
||||
Session::put('user_shop', $userShop);
|
||||
Session::put('user_shop_domain', $this->buildUserShopHost($userShop->slug));
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Sicheren Cookie mit XSS-Protection setzen (Duplikate-vermeidend)
|
||||
*/
|
||||
private function updateCookie(UserShop $userShop, array $config): void
|
||||
{
|
||||
$cookieValue = $this->sanitizeCookieValue($userShop->slug);
|
||||
$sessionDomain = Config::get('session.domain');
|
||||
|
||||
// Anti-Duplikate: Prüfen ob Cookie-Value sich geändert hat
|
||||
$currentCookieValue = request()->cookie($config['cookie_name']);
|
||||
if ($currentCookieValue === $cookieValue) {
|
||||
// Cookie ist bereits korrekt gesetzt → Skip um Duplikate zu vermeiden
|
||||
if ($config['debug_logging']) {
|
||||
Log::debug('UserShop cookie unchanged, skipping update', [
|
||||
'cookie_name' => $config['cookie_name'],
|
||||
'current_value' => $currentCookieValue,
|
||||
'user_shop_slug' => $userShop->slug
|
||||
]);
|
||||
}
|
||||
return;
|
||||
}
|
||||
|
||||
// Cookie-Value hat sich geändert → Update notwendig
|
||||
cookie()->queue(
|
||||
cookie(
|
||||
$config['cookie_name'],
|
||||
$cookieValue,
|
||||
$config['cookie_ttl_minutes'],
|
||||
path: '/',
|
||||
domain: $sessionDomain,
|
||||
secure: $config['cookie_secure'],
|
||||
httpOnly: true, // XSS-Protection
|
||||
sameSite: $config['cookie_same_site'] // Fix: SameSite konfigurierbar
|
||||
)
|
||||
);
|
||||
|
||||
// Debug-Logging für Cookie-Updates
|
||||
if ($config['debug_logging']) {
|
||||
Log::debug('UserShop cookie updated', [
|
||||
'cookie_name' => $config['cookie_name'],
|
||||
'old_value' => $currentCookieValue ?? 'none',
|
||||
'new_value' => $cookieValue,
|
||||
'domain' => $sessionDomain,
|
||||
'ttl_minutes' => $config['cookie_ttl_minutes'],
|
||||
'user_shop_slug' => $userShop->slug
|
||||
]);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Session bereinigen
|
||||
*/
|
||||
private function clearUserShopSession(array $config): void
|
||||
{
|
||||
// Kompakte Keys entfernen
|
||||
Session::forget(['shop.id', 'shop.slug']);
|
||||
|
||||
// Legacy-Keys optional entfernen
|
||||
if ($config['legacy_support']) {
|
||||
Session::forget(['user_shop', 'user_shop_domain']);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Konfiguration mit sinnvollen Defaults laden
|
||||
*/
|
||||
private function getConfig(): array
|
||||
{
|
||||
$config = Config::get('subdomain', []);
|
||||
|
||||
return [
|
||||
'cookie_name' => $config['cookie']['name'] ?? 'mivita_shop',
|
||||
'cookie_ttl_minutes' => ($config['cookie']['ttl_days'] ?? 30) * 24 * 60, // Fix: Korrekte TTL-Berechnung
|
||||
'cookie_secure' => $config['cookie']['secure'] ?? (config('app.env') === 'production'),
|
||||
'cookie_same_site' => $config['cookie']['same_site'] ?? 'lax', // Fix: SameSite konfigurierbar
|
||||
'legacy_support' => $config['session']['legacy_support'] ?? true,
|
||||
'debug_logging' => $config['debug']['log_domain_switches'] ?? false,
|
||||
];
|
||||
}
|
||||
|
||||
/**
|
||||
* UserShop-Host URL erstellen
|
||||
*/
|
||||
private function buildUserShopHost(string $slug): string
|
||||
{
|
||||
try {
|
||||
return parse_url($this->domainService->buildUrl('user-shop', null, $slug), PHP_URL_HOST) ?? '';
|
||||
} catch (\Throwable $e) {
|
||||
Log::warning('UserShop host generation failed', [
|
||||
'slug' => $slug,
|
||||
'error' => $e->getMessage()
|
||||
]);
|
||||
return '';
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Cookie-Value gegen XSS sanitizen
|
||||
*/
|
||||
private function sanitizeCookieValue(string $value): string
|
||||
{
|
||||
// Nur alphanumerische Zeichen und Bindestriche erlauben
|
||||
return preg_replace('/[^a-z0-9-]/i', '', $value);
|
||||
}
|
||||
|
||||
/**
|
||||
* Slug-Format validieren
|
||||
*/
|
||||
private function isValidSlug(string $slug): bool
|
||||
{
|
||||
return !empty($slug)
|
||||
&& strlen($slug) >= 3
|
||||
&& strlen($slug) <= 50
|
||||
&& preg_match('/^[a-z0-9-]+$/', $slug);
|
||||
}
|
||||
|
||||
/**
|
||||
* Minimal Debug-Logging
|
||||
*/
|
||||
private function logSynchronization(UserShop $userShop, string $slug): void
|
||||
{
|
||||
if (!$this->getConfig()['debug_logging']) {
|
||||
return;
|
||||
}
|
||||
|
||||
Log::debug('UserShop synchronized', [
|
||||
'user_shop_id' => $userShop->id,
|
||||
'slug' => $slug,
|
||||
'session_id' => Session::getId(),
|
||||
'cache_entries' => count(self::$userShopCache),
|
||||
'memory_mb' => round(memory_get_usage() / 1024 / 1024, 2)
|
||||
]);
|
||||
}
|
||||
|
||||
/**
|
||||
* Aktuellen UserShop aus Session laden (Helper für Controller/Views)
|
||||
*/
|
||||
public function getCurrentUserShop(): ?UserShop
|
||||
{
|
||||
$slug = Session::get('shop.slug');
|
||||
|
||||
return $slug ? $this->loadUserShopCached($slug) : null;
|
||||
}
|
||||
|
||||
/**
|
||||
* Prüfen ob aktuell ein UserShop aktiv ist
|
||||
*/
|
||||
public function hasActiveUserShop(): bool
|
||||
{
|
||||
return Session::has('shop.id') && Session::has('shop.slug');
|
||||
}
|
||||
|
||||
/**
|
||||
* Cache-Statistiken für Debugging
|
||||
*/
|
||||
public static function getCacheStats(): array
|
||||
{
|
||||
return [
|
||||
'cached_shops' => count(self::$userShopCache),
|
||||
'memory_usage_kb' => round(memory_get_usage() / 1024, 2)
|
||||
];
|
||||
}
|
||||
|
||||
/**
|
||||
* Cache für Testing zurücksetzen
|
||||
*/
|
||||
public static function clearCache(): void
|
||||
{
|
||||
self::$userShopCache = [];
|
||||
}
|
||||
}
|
||||
241
dev/app-bak/Services/UserUtil.php
Normal file
241
dev/app-bak/Services/UserUtil.php
Normal file
|
|
@ -0,0 +1,241 @@
|
|||
<?php
|
||||
namespace App\Services;
|
||||
|
||||
|
||||
use App\User;
|
||||
use App\Models\ShoppingUser;
|
||||
use App\Models\UserCleanUpLog;
|
||||
use App\Models\ShoppingUserMemberLog;
|
||||
use App\Http\Controllers\Api\KasController;
|
||||
|
||||
class UserUtil
|
||||
{
|
||||
|
||||
|
||||
public static function setShoppingUserToNewMember($pre_member_id, $new_member_id)
|
||||
{
|
||||
$ShoppingUsers = ShoppingUser::where('member_id', $pre_member_id)->get();
|
||||
foreach($ShoppingUsers as $shopping_user){
|
||||
ShoppingUserMemberLog::create([
|
||||
'pre_member_id' => $shopping_user->member_id,
|
||||
'shopping_user_id' => $shopping_user->id,
|
||||
'new_member_id' => $new_member_id
|
||||
]);
|
||||
$shopping_user->member_id = $new_member_id;
|
||||
$shopping_user->save();
|
||||
}
|
||||
}
|
||||
|
||||
public static function setNewSponsorToChilds($inactive_sponsor_id, $new_sponsor_id){
|
||||
//alle User die diesen inaktivien Sponsor haben
|
||||
$child_users = User::where('m_sponsor', $inactive_sponsor_id)->get(); //auch deaktiverte
|
||||
foreach($child_users as $child_user){
|
||||
UserCleanUpLog::create([
|
||||
'inactive_sponsor_id' => $inactive_sponsor_id,
|
||||
'child_user_id' => $child_user->id,
|
||||
'new_sponsor_id' => $new_sponsor_id,
|
||||
]);
|
||||
$child_user->m_sponsor = $new_sponsor_id;
|
||||
$child_user->save();
|
||||
}
|
||||
}
|
||||
|
||||
public static function resetChildsToSponsor($re_sponsor_id){
|
||||
//alle alten Childs vom re_sponsor_id / User wieder herstellen
|
||||
$UserCleanUpUsers = UserCleanUpLog::where('inactive_sponsor_id', $re_sponsor_id)->get();
|
||||
foreach($UserCleanUpUsers as $UserCleanUpUser){
|
||||
$child_user = User::find($UserCleanUpUser->child_user_id);
|
||||
if($child_user){
|
||||
//delete Logs from user child where is newer then this
|
||||
$deleteUserCleanUpLogs = UserCleanUpLog::where('child_user_id', $UserCleanUpUser->child_user_id)->where('created_at', '>', $UserCleanUpUser->created_at)->get();
|
||||
foreach($deleteUserCleanUpLogs as $deleteUserCleanUpLog){
|
||||
$deleteUserCleanUpLog->delete();
|
||||
}
|
||||
if($child_user->m_sponsor){ // child is active
|
||||
$child_user->m_sponsor = $re_sponsor_id;
|
||||
}
|
||||
if($child_user->pre_sponsor){ //child is inactive
|
||||
$child_user->pre_sponsor = $re_sponsor_id;
|
||||
}
|
||||
$child_user->save();
|
||||
//delete this log
|
||||
$UserCleanUpUser->delete();
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
public static function setUserToClient($user_id, $sponsor_id){
|
||||
$user = User::find($user_id);
|
||||
|
||||
if($user){
|
||||
$data = [
|
||||
'member_id' => $sponsor_id,
|
||||
'language' => $user->lang ? $user->lang : 'de',
|
||||
'billing_salutation' => $user->account->salutation,
|
||||
'billing_company' => $user->account->company,
|
||||
'billing_firstname' => $user->account->first_name,
|
||||
'billing_lastname' => $user->account->last_name,
|
||||
'billing_address' => $user->account->address,
|
||||
'billing_address_2' => $user->account->address_2,
|
||||
'billing_zipcode' => $user->account->zipcode,
|
||||
'billing_city' => $user->account->city,
|
||||
'billing_country_id' => $user->account->country_id,
|
||||
'billing_phone' => $user->account->getPhoneNumber(),
|
||||
'billing_email' => $user->email,
|
||||
'same_as_billing' => $user->account->same_as_billing,
|
||||
'shipping_salutation' => $user->account->shipping_salutation,
|
||||
'shipping_company' => $user->account->shipping_company,
|
||||
'shipping_firstname' => $user->account->shipping_firstname,
|
||||
'shipping_lastname' => $user->account->shipping_lastname,
|
||||
'shipping_address' => $user->account->shipping_address,
|
||||
'shipping_address_2' => $user->account->shipping_address_2,
|
||||
'shipping_zipcode' => $user->account->shipping_zipcode,
|
||||
'shipping_city' => $user->account->shipping_city,
|
||||
'shipping_country_id' => $user->account->shipping_country_id,
|
||||
'shipping_phone' => $user->account->getShippingPhoneFull(),
|
||||
];
|
||||
ShoppingUser::create($data);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
find next activ sponsor on user id
|
||||
first $sponsor_id can user_id, looks has m_sponsor or pre_sponsor.
|
||||
*/
|
||||
public static function findNextActiveSponsor($sponsor_id){
|
||||
|
||||
$user = User::withTrashed()->find($sponsor_id);
|
||||
if(!$user){ //kein User unter der ID - to root
|
||||
return User::find(6);
|
||||
}
|
||||
//user ist aktiv
|
||||
if($user->isActiveAccount()){
|
||||
return $user;
|
||||
}
|
||||
if($user->m_sponsor){ //hat der User einen m_sponsor
|
||||
return self::findNextActiveSponsor($user->m_sponsor);
|
||||
}
|
||||
if($user->pre_sponsor){ //hat der User einen pre_sponsor - schon inaktiv
|
||||
return self::findNextActiveSponsor($user->pre_sponsor);
|
||||
}
|
||||
//dump('not sponsor');
|
||||
return $user;
|
||||
}
|
||||
|
||||
public static function deactiveUser($user){
|
||||
|
||||
$user->pre_sponsor = $user->m_sponsor; //den sponsor speichern für wiederherstellung
|
||||
$user->m_sponsor = null;
|
||||
$user->active = false;
|
||||
$user->save();
|
||||
}
|
||||
|
||||
public static function reactiveUser($user){
|
||||
|
||||
if($user->pre_sponsor){
|
||||
$pre_sponsor = self::findNextActiveSponsor($user->pre_sponsor);
|
||||
$user->m_sponsor = $pre_sponsor->id; //den sponsor wiederherstellen
|
||||
$user->pre_sponsor = null;
|
||||
}
|
||||
$user->active = true;
|
||||
$user->save();
|
||||
}
|
||||
|
||||
public static function deleteUser(User $user, $complete = false)
|
||||
{
|
||||
//shop wird gelöscht
|
||||
if($user->shop){
|
||||
$subdomain_name = $user->shop->slug.'.mivita.care';
|
||||
$user->shop->name = "delete".$user->shop->id;
|
||||
$user->shop->slug = "delete".$user->shop->id;
|
||||
$user->shop->save();
|
||||
$user->shop->delete();
|
||||
//isset KAS - delete Subdomain
|
||||
if(!Util::isTestSystem()){
|
||||
$kas = new KasController();
|
||||
$pra = array(
|
||||
'subdomain_name' => $subdomain_name,
|
||||
);
|
||||
$kas->action('delete_subdomain', $pra);
|
||||
}
|
||||
}
|
||||
|
||||
//user soll nicht komplett gelöscht werden
|
||||
$user->email = "delete-".$user->email;
|
||||
//password wird gelöscht
|
||||
$user->password = "delete".time();
|
||||
$user->confirmed = 0;
|
||||
$user->confirmation_code = "delete".time();
|
||||
$user->confirmation_date = null;
|
||||
$user->confirmation_code_to = null;
|
||||
$user->confirmation_code_remider = 2;
|
||||
// $user->agreement = null;
|
||||
$user->active = 0;
|
||||
$user->remember_token = '';
|
||||
$user->active_date = null;
|
||||
$user->admin = 0;
|
||||
$user->deleted_at = now();
|
||||
$user->pre_deleted_at = now();
|
||||
//user soll komplett gelöscht werden
|
||||
if($complete){
|
||||
$user->email = "delete-".time()."-".rand(1000, 9999);
|
||||
if($user->account){
|
||||
$user->account->delete();
|
||||
}
|
||||
$user->pre_deleted_at = null;
|
||||
}
|
||||
|
||||
$user->save();
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
public static function reactiveUserResetChilds($user_id, $info = ''){
|
||||
|
||||
$user = User::find($user_id);
|
||||
if(!$user){
|
||||
\Log::channel('cleanup')->error('reactiveUserResetChilds find no user by user_id:'.$user_id);
|
||||
return 0;
|
||||
}
|
||||
$data = [
|
||||
'user_id' => $user->id,
|
||||
'email' => $user->email,
|
||||
'm_account' => $user->account ? $user->account->m_account : '',
|
||||
'm_first_name' => $user->account ? $user->account->m_first_name : '',
|
||||
'm_last_name' => $user->account ? $user->account->m_last_name : '',
|
||||
];
|
||||
\Log::channel('cleanup')->info('reactiveUserResetChilds '.$info.' : '.json_encode($data));
|
||||
|
||||
self::reactiveUser($user);
|
||||
self::resetChildsToSponsor($user->id);
|
||||
}
|
||||
|
||||
public static function deactiveUserNewSponsorChilds($user_id, $info = ''){
|
||||
|
||||
$user = User::find($user_id);
|
||||
if(!$user){
|
||||
\Log::channel('cleanup')->error('deactiveUserNewSponsorChilds find no user by user_id:'.$user_id);
|
||||
return 0;
|
||||
}
|
||||
$data = [
|
||||
'user_id' => $user->id,
|
||||
'email' => $user->email,
|
||||
'm_account' => $user->account ? $user->account->m_account : '',
|
||||
'm_first_name' => $user->account ? $user->account->m_first_name : '',
|
||||
'm_last_name' => $user->account ? $user->account->m_last_name : '',
|
||||
];
|
||||
|
||||
$active_sponsor = self::findNextActiveSponsor($user->m_sponsor);
|
||||
if($active_sponsor){
|
||||
self::setNewSponsorToChilds($user->id, $active_sponsor->id);
|
||||
}else{
|
||||
\Log::channel('cleanup')->error('cleanUpInActiveUser find no active_sponsor by inactive_user:'.$user->id);
|
||||
}
|
||||
\Log::channel('cleanup')->info('deactiveUserNewSponsorChilds '.$info.' : '.json_encode($data));
|
||||
self::deactiveUser($user);
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
449
dev/app-bak/Services/Util.php
Normal file
449
dev/app-bak/Services/Util.php
Normal file
|
|
@ -0,0 +1,449 @@
|
|||
<?php
|
||||
|
||||
namespace App\Services;
|
||||
|
||||
use App\Models\Country;
|
||||
use App\Models\ShippingCountry;
|
||||
use App\Models\UserHistory;
|
||||
use App\Models\UserShop;
|
||||
use Illuminate\Support\Str;
|
||||
use Request;
|
||||
use Yard;
|
||||
|
||||
class Util
|
||||
{
|
||||
|
||||
private static $postRoute = 'base.';
|
||||
|
||||
public static function getToken()
|
||||
{
|
||||
return hash_hmac('sha256', Str::random(40), config('app.key'));
|
||||
}
|
||||
|
||||
public static function uuidToken()
|
||||
{
|
||||
$uuid = (string) Str::uuid();
|
||||
$e_uuid = explode("-", $uuid);
|
||||
if (isset($e_uuid[0]) && $e_uuid[1]) {
|
||||
return $e_uuid[0] . "-" . $e_uuid[1];
|
||||
}
|
||||
return $uuid;
|
||||
}
|
||||
|
||||
public static function formatDate()
|
||||
{
|
||||
if (\App::getLocale() === "en") {
|
||||
return 'yyyy-mm-dd';
|
||||
}
|
||||
return 'dd.mm.yyyy';
|
||||
}
|
||||
|
||||
public static function formatDateDB()
|
||||
{
|
||||
if (\App::getLocale() === "en") {
|
||||
return 'Y-m-d';
|
||||
}
|
||||
return 'd.m.Y';
|
||||
}
|
||||
|
||||
public static function formatDateTimeDB()
|
||||
{
|
||||
if (\App::getLocale() === "en") {
|
||||
return 'Y-m-d - H:i';
|
||||
}
|
||||
return 'd.m.Y - H:i';
|
||||
}
|
||||
|
||||
public static function _format_number($value)
|
||||
{
|
||||
return preg_replace("/[^0-9,-]/", "", $value);
|
||||
}
|
||||
|
||||
public static function _thousands_separator()
|
||||
{
|
||||
return \App::getLocale() === "en" ? ',' : '.';
|
||||
}
|
||||
|
||||
public static function _decimal_separator()
|
||||
{
|
||||
return \App::getLocale() === "en" ? '.' : ',';
|
||||
}
|
||||
|
||||
|
||||
public static function maxStrLength($str, $length = 40)
|
||||
{
|
||||
|
||||
if (strlen($str) > $length) {
|
||||
$str = substr($str, 0, $length);
|
||||
//$str = substr($str, 0, strrpos($str, " "));
|
||||
$str = $str . " ...";
|
||||
}
|
||||
return $str;
|
||||
}
|
||||
|
||||
|
||||
public static function reFormatNumber($value)
|
||||
{
|
||||
return (float) str_replace(',', '.', self::_format_number($value));
|
||||
}
|
||||
|
||||
public static function formatNumber($value, $dec = 2)
|
||||
{
|
||||
$value = floatval(str_replace(',', '', $value));
|
||||
return number_format($value, $dec, self::_decimal_separator(), self::_thousands_separator());
|
||||
}
|
||||
public static function cleanIntegerFromString($value)
|
||||
{
|
||||
// Entferne alle nicht-numerischen Zeichen außer Minus
|
||||
$cleanStr = preg_replace("/[^0-9-]/", "", $value);
|
||||
|
||||
// Konvertiere zu Integer und entferne führende Nullen
|
||||
$number = (int)$cleanStr;
|
||||
|
||||
return $number;
|
||||
}
|
||||
public static function cleanNumberFormat($num = 0, $dec = 2, $fullzero = false)
|
||||
{
|
||||
|
||||
if ($fullzero && $num == 0) {
|
||||
return number_format($num, $dec, self::_decimal_separator(), self::_thousands_separator());
|
||||
}
|
||||
return rtrim(rtrim(number_format($num, $dec, self::_decimal_separator(), self::_thousands_separator()), '0'), self::_decimal_separator());
|
||||
}
|
||||
|
||||
public static function utf8ize($mixed)
|
||||
{
|
||||
if (is_array($mixed)) {
|
||||
foreach ($mixed as $key => $value) {
|
||||
$mixed[$key] = self::utf8ize($value);
|
||||
}
|
||||
} elseif (is_string($mixed)) {
|
||||
return mb_convert_encoding($mixed, "UTF-8", "UTF-8");
|
||||
}
|
||||
return $mixed;
|
||||
}
|
||||
|
||||
|
||||
public static function getPostRoute()
|
||||
{
|
||||
return self::$postRoute;
|
||||
}
|
||||
public static function setPostRoute($postRoute)
|
||||
{
|
||||
self::$postRoute = $postRoute;
|
||||
}
|
||||
|
||||
public static function getUserShop()
|
||||
{
|
||||
$shop = session('user_shop');
|
||||
if (empty($shop) || !is_object($shop)) {
|
||||
return null;
|
||||
}
|
||||
return $shop;
|
||||
}
|
||||
|
||||
public static function getDefaultUserShop()
|
||||
{
|
||||
$user = \App\User::find(6);
|
||||
if ($user && $user->shop) {
|
||||
return $user->shop;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
public static function getAuthUser()
|
||||
{
|
||||
if (\Session::has('auth_user')) {
|
||||
if ($auth_user = \Session::get('auth_user')) {
|
||||
return $auth_user;
|
||||
}
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
|
||||
public static function getUserShopIdentifier()
|
||||
{
|
||||
if (\Session::has('user_shop_identifier')) {
|
||||
if ($user_shop_identifier = \Session::get('user_shop_identifier')) {
|
||||
return $user_shop_identifier;
|
||||
}
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
public static function getInstanceStatus()
|
||||
{
|
||||
$identifier = self::getUserShopIdentifier();
|
||||
if ($identifier && \Session::has('user_shop_payment') && \Session::get('user_shop_payment') === 6) {
|
||||
return OrderPaymentService::getInstanceStatus($identifier);
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
public static function setInstanceStatus($status, $lower = true)
|
||||
{
|
||||
$identifier = self::getUserShopIdentifier();
|
||||
if ($identifier && \Session::has('user_shop_payment') && \Session::get('user_shop_payment') === 6) {
|
||||
OrderPaymentService::updateInstanceStatus($identifier, $status, $lower);
|
||||
}
|
||||
}
|
||||
|
||||
public static function setInstanceStatusByPayment($shopping_payment, $status, $lower = true)
|
||||
{
|
||||
if ($shopping_payment->identifier) {
|
||||
OrderPaymentService::updateInstanceStatus($shopping_payment->identifier, $status, $lower);
|
||||
}
|
||||
}
|
||||
|
||||
public static function getShoppingInstance()
|
||||
{
|
||||
if (\Session::has('shopping_instance')) {
|
||||
return \Session::get('shopping_instance');
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
public static function getUserHistory()
|
||||
{
|
||||
$auth_user = self::getAuthUser();
|
||||
$user_shop_identifier = self::getUserShopIdentifier();
|
||||
if ($user_shop_identifier && $auth_user) {
|
||||
return UserHistory::whereUserId($auth_user->id)->whereIdentifier($user_shop_identifier)->get()->last();
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
public static function setUserHistoryValue($values = [])
|
||||
{
|
||||
if ($user_history = self::getUserHistory()) {
|
||||
foreach ($values as $key => $val) {
|
||||
$user_history->{$key} = $val;
|
||||
}
|
||||
$user_history->save();
|
||||
}
|
||||
}
|
||||
|
||||
public static function getUserHistoryValue($key)
|
||||
{
|
||||
if ($user_history = self::getUserHistory()) {
|
||||
return $user_history->{$key};
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
public static function getUserShoppingMode()
|
||||
{
|
||||
if ($auth_user = self::getAuthUser()) {
|
||||
if ($auth_user->isTestMode()) {
|
||||
return 'test';
|
||||
}
|
||||
}
|
||||
return config('app.mode');
|
||||
}
|
||||
public static function addRoute($p = [])
|
||||
{
|
||||
$b = [];
|
||||
if (\Session::has('user_shop')) {
|
||||
if ($user_shop = \Session::get('user_shop')) {
|
||||
$b = ['subdomain' => $user_shop->slug];
|
||||
}
|
||||
}
|
||||
return array_merge($p, $b);
|
||||
}
|
||||
|
||||
public static function checkUserLandIsNot($user)
|
||||
{
|
||||
|
||||
if (isset($user->account->country_id)) {
|
||||
//ch schweiz is out
|
||||
if ($user->account->country_id === 6) {
|
||||
return false;
|
||||
}
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
public static function getCustomerUserShopDomain()
|
||||
{
|
||||
if (\Auth::guard('customers')->check()) {
|
||||
if (\Auth::guard('customers')->user()->user_shop_domain) {
|
||||
return \Auth::guard('customers')->user()->user_shop_domain;
|
||||
}
|
||||
}
|
||||
return self::getMyMivitaShopUrl();
|
||||
}
|
||||
|
||||
public static function getMyMivitaShopUrl($add_url = "")
|
||||
{
|
||||
if (\Session::has('user_shop_domain')) {
|
||||
$url = \Session::get('user_shop_domain') . $add_url;
|
||||
if (!str_starts_with($url, 'http')) {
|
||||
$url = 'https://' . ltrim($url, '/');
|
||||
}
|
||||
return $url;
|
||||
}
|
||||
//alois sein shop
|
||||
$user = \App\User::find(6);
|
||||
if ($user && $user->shop) {
|
||||
return config('app.protocol') . $user->shop->slug . "." . config('app.domain') . config('app.tld_care') . $add_url;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
public static function getMyMivitaPortalUrl($protocol = true)
|
||||
{
|
||||
$pro = $protocol ? config('app.protocol') : "";
|
||||
return $pro . config('app.pre_url_portal') . config('app.domain') . config('app.tld_care');
|
||||
}
|
||||
public static function getMyMivitaUrl($protocol = true)
|
||||
{
|
||||
$pro = $protocol ? config('app.protocol') : "";
|
||||
return $pro . config('app.pre_url_crm') . config('app.domain') . config('app.tld_care');
|
||||
}
|
||||
|
||||
public static function getUserPaymentFor($instance = 'shopping')
|
||||
{
|
||||
if (Yard::instance($instance)->getYardExtra('user_shop_payment')) {
|
||||
return Yard::instance($instance)->getYardExtra('user_shop_payment');
|
||||
}
|
||||
if (\Session::has('user_shop_payment')) {
|
||||
return \Session::get('user_shop_payment');
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
public static function getUserShopBackUrl($reference = "")
|
||||
{
|
||||
|
||||
if (\Session::has('user_shop')) {
|
||||
if (\Session::has('user_shop_domain')) {
|
||||
return \Session::get('user_shop_domain');
|
||||
}
|
||||
if ($user_shop = \Session::get('user_shop')) {
|
||||
return config('app.protocol') . $user_shop->slug . "." . config('app.domain') . config('app.tld_care') . "/back/to/shop/" . $reference;
|
||||
}
|
||||
}
|
||||
return config('app.protocol') . config('app.domain') . config('app.tld_care');
|
||||
}
|
||||
|
||||
public static function getUserCardBackUrl($uri, $instance = 'shopping')
|
||||
{
|
||||
|
||||
if (\Session::has('user_shop')) {
|
||||
if (\Session::has('user_shop_domain')) {
|
||||
if (\Session::has('back_link')) {
|
||||
return \Session::get('back_link');
|
||||
}
|
||||
if (self::getUserPaymentFor($instance) === 3) {
|
||||
return \Session::get('user_shop_domain') . "/user/membership";
|
||||
}
|
||||
if (self::getUserPaymentFor($instance) === 2) {
|
||||
return \Session::get('user_shop_domain') . "/user/orders";
|
||||
}
|
||||
return \Session::get('user_shop_domain');
|
||||
}
|
||||
if ($user_shop = \Session::get('user_shop')) {
|
||||
return config('app.protocol') . $user_shop->slug . "." . config('app.domain') . config('app.tld_care') . $uri;
|
||||
}
|
||||
}
|
||||
return config('app.protocol') . config('app.domain') . config('app.tld_care');
|
||||
}
|
||||
|
||||
public static function isMivitaShop()
|
||||
{
|
||||
if (Request::getHost() === 'checkout.' . config('app.domain') . config('app.tld_care')) {
|
||||
if ($user_shop = \Session::get('user_shop')) {
|
||||
if ($user_shop->slug === 'aloevera' || $user_shop->slug === 'naturcosmetic') {
|
||||
return true;
|
||||
}
|
||||
}
|
||||
}
|
||||
if (Request::getHost() === 'naturcosmetic.' . config('app.domain') . config('app.tld_care')) {
|
||||
return true;
|
||||
}
|
||||
return \Config::get('app.url') === config('app.domain') . config('app.tld_shop');
|
||||
}
|
||||
|
||||
public static function isTestSystem($dev = false)
|
||||
{
|
||||
if (\Config::get('app.tld_care') === '.test' || \Config::get('app.tld_shop') === '.lshop') {
|
||||
if ($dev && config('app.debug') !== true) {
|
||||
return false;
|
||||
}
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
public static function formatBytes($size, $precision = 2)
|
||||
{
|
||||
if ($size > 0) {
|
||||
$size = (int) $size;
|
||||
$base = log($size) / log(1024);
|
||||
$suffixes = array(' bytes', ' KB', ' MB', ' GB', ' TB');
|
||||
|
||||
return round(pow(1024, $base - floor($base)), $precision) . $suffixes[floor($base)];
|
||||
} else {
|
||||
return $size;
|
||||
}
|
||||
}
|
||||
|
||||
public static function sanitize($string, $force_lowercase = true, $anal = false, $substr = false)
|
||||
{
|
||||
$strip = array(
|
||||
"~",
|
||||
"`",
|
||||
"!",
|
||||
"@",
|
||||
"#",
|
||||
"$",
|
||||
"%",
|
||||
"^",
|
||||
"&",
|
||||
"*",
|
||||
"(",
|
||||
")",
|
||||
"_",
|
||||
"=",
|
||||
"+",
|
||||
"[",
|
||||
"{",
|
||||
"]",
|
||||
"}",
|
||||
"\\",
|
||||
"|",
|
||||
";",
|
||||
":",
|
||||
"\"",
|
||||
"'",
|
||||
"‘",
|
||||
"’",
|
||||
"“",
|
||||
"”",
|
||||
"–",
|
||||
"—",
|
||||
"—",
|
||||
"–",
|
||||
",",
|
||||
"<",
|
||||
".",
|
||||
">",
|
||||
"/",
|
||||
"?"
|
||||
);
|
||||
$clean = trim(str_replace($strip, "", strip_tags($string)));
|
||||
$clean = preg_replace('/\s+/', "_", $clean);
|
||||
$clean = ($anal) ? preg_replace("/[^a-zA-Z0-9]/", "", $clean) : $clean;
|
||||
|
||||
if ($substr) {
|
||||
$clean = (strlen($clean) > 20) ? substr($clean, -20) : $clean;
|
||||
}
|
||||
return ($force_lowercase) ?
|
||||
(function_exists('mb_strtolower')) ?
|
||||
mb_strtolower($clean, 'UTF-8') :
|
||||
strtolower($clean) :
|
||||
$clean;
|
||||
}
|
||||
}
|
||||
688
dev/app-bak/Services/Yard.php
Normal file
688
dev/app-bak/Services/Yard.php
Normal file
|
|
@ -0,0 +1,688 @@
|
|||
<?php
|
||||
namespace App\Services;
|
||||
|
||||
use App\Services\Shop;
|
||||
use App\Models\Country;
|
||||
use App\Models\Product;
|
||||
use App\Models\ShippingCountry;
|
||||
use \Gloudemans\Shoppingcart\Cart;
|
||||
use Illuminate\Support\Collection;
|
||||
use Gloudemans\Shoppingcart\CartItem;
|
||||
use Illuminate\Session\SessionManager;
|
||||
use Illuminate\Contracts\Events\Dispatcher;
|
||||
use Gloudemans\Shoppingcart\Contracts\Buyable;
|
||||
|
||||
class Yard extends Cart
|
||||
{
|
||||
private $shipping_price = 0;
|
||||
private $shipping_price_net = 0;
|
||||
private $shipping_tax_rate = 0;
|
||||
private $shipping_tax = 0;
|
||||
private $shipping_country_id = 0; //default de
|
||||
private $shipping_is_for;
|
||||
private $num_comp;
|
||||
private $user_tax_free;
|
||||
private $shipping_free;
|
||||
private $user_reverse_charge;
|
||||
private $user_country_id;
|
||||
private $user_country;
|
||||
private $shopping_data = [];
|
||||
private $initShippingExtras = false;
|
||||
|
||||
|
||||
public function __construct(SessionManager $session, Dispatcher $events)
|
||||
{
|
||||
parent::__construct($session, $events);
|
||||
|
||||
}
|
||||
|
||||
public function instance($instance = null)
|
||||
{
|
||||
parent::instance($instance);
|
||||
if(!$this->initShippingExtras){
|
||||
$this->initShippingExtras = true; //erst true, sonst wird es immer wieder aufgerufen
|
||||
$this->makeShippingExtras($instance);
|
||||
}
|
||||
|
||||
return $this;
|
||||
}
|
||||
|
||||
private function makeShippingExtras($instance){
|
||||
|
||||
if($this->getYardExtra('shipping_price')){
|
||||
$this->shipping_price = (float) ($this->getYardExtra('shipping_price'));
|
||||
}
|
||||
if($this->getYardExtra('shipping_price_net')){
|
||||
$this->shipping_price_net = (float) ($this->getYardExtra('shipping_price_net'));
|
||||
}
|
||||
if($this->getYardExtra('shipping_tax_rate')){
|
||||
$this->shipping_tax_rate = (float) ($this->getYardExtra('shipping_tax_rate'));
|
||||
}
|
||||
if($this->getYardExtra('shipping_tax')){
|
||||
$this->shipping_tax = (float) ($this->getYardExtra('shipping_tax'));
|
||||
}
|
||||
if($this->getYardExtra('shipping_country_id')){
|
||||
$this->shipping_country_id = $this->getYardExtra('shipping_country_id');
|
||||
}
|
||||
if($this->getYardExtra('shipping_is_for')){
|
||||
$this->shipping_is_for = $this->getYardExtra('shipping_is_for');
|
||||
}
|
||||
if($this->getYardExtra('num_comp')){
|
||||
$this->num_comp = $this->getYardExtra('num_comp');
|
||||
}
|
||||
if($this->getYardExtra('user_tax_free')){
|
||||
$this->user_tax_free = $this->getYardExtra('user_tax_free');
|
||||
}
|
||||
if($this->getYardExtra('shipping_free')){
|
||||
$this->shipping_free = $this->getYardExtra('shipping_free');
|
||||
}
|
||||
if($this->getYardExtra('user_reverse_charge')){
|
||||
$this->user_reverse_charge = $this->getYardExtra('user_reverse_charge');
|
||||
}
|
||||
if($this->getYardExtra('user_country_id')){
|
||||
$this->user_country_id = $this->getYardExtra('user_country_id');
|
||||
}
|
||||
if($this->getYardExtra('user_country')){
|
||||
$this->user_country = $this->getYardExtra('user_country');
|
||||
}
|
||||
|
||||
if(gettype($this->shipping_country_id) !== 'object' && $this->shipping_country_id == 0){
|
||||
$shippingCountry = ShippingCountry::first();
|
||||
if($shippingCountry){
|
||||
$this->shipping_country_id = $shippingCountry->id;
|
||||
}
|
||||
}
|
||||
if($this->shipping_price == 0){
|
||||
self::instance($instance)->setShippingCountryWithPrice($this->shipping_country_id, $this->shipping_is_for);
|
||||
}
|
||||
}
|
||||
|
||||
public function getTaxRate()
|
||||
{
|
||||
return config('cart.tax');
|
||||
}
|
||||
|
||||
public function putYardExtra($key, $value){
|
||||
$content = $this->getYContent();
|
||||
$content->put($key, $value);
|
||||
$this->putShippingExtras($content);
|
||||
//$this->ysession->put($this->yinstance, $content);
|
||||
}
|
||||
|
||||
public function getYardExtra($key){
|
||||
$content = $this->getYContent();
|
||||
if ($content->has($key)){
|
||||
return $content->get($key);
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
public function getYContent()
|
||||
{
|
||||
return $this->getShippingExtras();
|
||||
/* if (is_null($this->ysession->get($this->yinstance))) {
|
||||
return new Collection([]);
|
||||
}
|
||||
return $this->ysession->get($this->yinstance);*/
|
||||
}
|
||||
|
||||
public function getShippingCountryName(){
|
||||
|
||||
$shippingCountry = ShippingCountry::find($this->shipping_country_id);
|
||||
if($shippingCountry && $shippingCountry->country){
|
||||
return $shippingCountry->country->getLocated();
|
||||
}
|
||||
return "";
|
||||
}
|
||||
public function getShippingCountryCountryId()
|
||||
{
|
||||
$shippingCountry = ShippingCountry::find($this->shipping_country_id);
|
||||
if($shippingCountry && $shippingCountry->country){
|
||||
return $shippingCountry->country->id;
|
||||
}
|
||||
return 1; //default DE
|
||||
}
|
||||
|
||||
public function getShippingCountryId()
|
||||
{
|
||||
return $this->shipping_country_id;
|
||||
}
|
||||
|
||||
|
||||
public function getShippingPrice()
|
||||
{
|
||||
return $this->shipping_price;
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
public function reCalculateShippingPrice(){
|
||||
$this->calculateShippingPrice();
|
||||
}
|
||||
|
||||
public function setShippingCountryWithPrice($shipping_country_id, $shipping_is_for = 'ot-member')
|
||||
{
|
||||
$this->shipping_country_id = $shipping_country_id;
|
||||
$this->putYardExtra('shipping_country_id', $shipping_country_id);
|
||||
|
||||
$this->shipping_is_for = $shipping_is_for;
|
||||
$this->putYardExtra('shipping_is_for', $shipping_is_for);
|
||||
|
||||
$this->calculateShippingPrice();
|
||||
|
||||
}
|
||||
|
||||
public function setUserPriceInfos($user_price_infos = [])
|
||||
{
|
||||
$this->shipping_free = isset($user_price_infos['shipping_free']) ? $user_price_infos['shipping_free'] : false;
|
||||
$this->putYardExtra('shipping_free', $this->shipping_free);
|
||||
|
||||
$this->user_tax_free = $user_price_infos['user_tax_free'];
|
||||
$this->putYardExtra('user_tax_free', $this->user_tax_free);
|
||||
|
||||
$this->user_reverse_charge = $user_price_infos['user_reverse_charge'];
|
||||
$this->putYardExtra('user_reverse_charge', $this->user_reverse_charge);
|
||||
|
||||
$this->user_country_id = $user_price_infos['user_country_id'];
|
||||
$this->putYardExtra('user_country_id', $this->user_country_id);
|
||||
|
||||
$this->user_country = Country::findOrFail($user_price_infos['user_country_id']);
|
||||
$this->putYardExtra('user_country', $this->user_country);
|
||||
|
||||
}
|
||||
|
||||
public function getUserPriceInfos(){
|
||||
return [
|
||||
'user_tax_free' =>$this->user_tax_free,
|
||||
'user_reverse_charge' =>$this->user_reverse_charge,
|
||||
'user_country_id' =>$this->user_country_id,
|
||||
'shipping_free' => $this->shipping_free,
|
||||
];
|
||||
}
|
||||
|
||||
public function getUserCountryId()
|
||||
{
|
||||
return $this->user_country_id;
|
||||
}
|
||||
|
||||
public function getUserCountry()
|
||||
{
|
||||
return $this->user_country;
|
||||
}
|
||||
|
||||
public function getUserTaxFree()
|
||||
{
|
||||
return $this->user_tax_free ? true : false;
|
||||
}
|
||||
|
||||
public function getShippingFree()
|
||||
{
|
||||
return $this->shipping_free;
|
||||
}
|
||||
|
||||
public function getShippingFreeMissingValue()
|
||||
{
|
||||
if($this->shipping_free && $this->total(2, '.', '') < $this->shipping_free){
|
||||
return $this->shipping_free - $this->total(2, '.', '');
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
||||
private function calculateShippingPrice(){
|
||||
|
||||
$shippingCountry = ShippingCountry::find($this->shipping_country_id);
|
||||
if(!$shippingCountry){
|
||||
return;
|
||||
}
|
||||
$shipping = $shippingCountry->shipping;
|
||||
$shipping_price = $shipping->shipping_prices->first();
|
||||
if(!$shipping_price){
|
||||
return;
|
||||
}
|
||||
if($this->weight() == 0){
|
||||
$shipping_price->price = 0;
|
||||
$shipping_price->price_comp = 0;
|
||||
}else{
|
||||
if($this->shipping_free && $this->total(2, '.', '') >= $this->shipping_free){
|
||||
if($this->weightByFreeShipping() == 0){
|
||||
$shipping_price->price = 0;
|
||||
$shipping_price->price_comp = 0;
|
||||
}else{
|
||||
$shipping_price = $this->shippingPriceByWeight($shipping->shipping_prices, $this->weightByFreeShipping());
|
||||
}
|
||||
|
||||
}else{
|
||||
$shipping_price = $this->shippingPriceByWeight($shipping->shipping_prices, $this->weight());
|
||||
//first by price
|
||||
//$shipping_price = $this->shippingPriceByTotal($shipping->shipping_prices, $this->total(2, '.', ''));
|
||||
//sec by weight
|
||||
//if(!$shipping_price){
|
||||
//}
|
||||
}
|
||||
//default
|
||||
if(!$shipping_price){
|
||||
$shipping_price = $shipping->shipping_prices->first();
|
||||
}
|
||||
}
|
||||
if($shipping_price){
|
||||
$price = $shipping_price->price;
|
||||
$this->num_comp = 0; //compensation is checked in Settings
|
||||
if(Shop::isCompProducts($this->shipping_is_for)){
|
||||
$price = $shipping_price->price_comp;
|
||||
$this->num_comp = $shipping_price->num_comp;
|
||||
|
||||
}
|
||||
$this->shipping_price = $price;
|
||||
$this->shipping_tax_rate = $shipping_price->tax_rate;
|
||||
$this->shipping_price_net = round($price / ((100+$shipping_price->tax_rate) / 100), 2);
|
||||
$this->shipping_tax = round($price / (100+$shipping_price->tax_rate) * 100, 2);
|
||||
|
||||
$this->putYardExtra('num_comp', $this->num_comp);
|
||||
$this->putYardExtra('shipping_price', $this->shipping_price);
|
||||
$this->putYardExtra('shipping_tax_rate', $this->shipping_tax_rate);
|
||||
$this->putYardExtra('shipping_tax', $this->shipping_tax);
|
||||
$this->putYardExtra('shipping_price_net', $this->shipping_price_net);
|
||||
}
|
||||
}
|
||||
|
||||
private function shippingPriceByTotal($prices, $total){
|
||||
foreach ($prices as $price){
|
||||
if($price->total_from > 0 && $price->total_to > 0){
|
||||
if($total >= $price->total_from && $total <= $price->total_to){
|
||||
return $price;
|
||||
}
|
||||
}
|
||||
}
|
||||
return false;
|
||||
}
|
||||
private function shippingPriceByWeight($prices, $weight){
|
||||
foreach ($prices as $price){
|
||||
if($price->weight_from > 0 && $price->weight_to > 0){
|
||||
if($weight >= $price->weight_from && $weight <= $price->weight_to){
|
||||
return $price;
|
||||
}
|
||||
}
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param null $decimals
|
||||
* @param null $decimalPoint
|
||||
* @param null $thousandSeperator
|
||||
* @return string
|
||||
*/
|
||||
public function shipping($decimals = null, $decimalPoint = null, $thousandSeperator = null)
|
||||
{
|
||||
return $this->numberFormat($this->shipping_price, $decimals, $decimalPoint, $thousandSeperator);
|
||||
}
|
||||
|
||||
public function shippingNet($decimals = null, $decimalPoint = null, $thousandSeperator = null)
|
||||
{
|
||||
return $this->numberFormat($this->shipping_price_net, $decimals, $decimalPoint, $thousandSeperator);
|
||||
}
|
||||
//
|
||||
private function shippingTax($decimals = null, $decimalPoint = null, $thousandSeperator = null)
|
||||
{
|
||||
return $this->numberFormat($this->shipping_tax, $decimals, $decimalPoint, $thousandSeperator);
|
||||
|
||||
}
|
||||
|
||||
/* private function subShipping($decimals = null, $decimalPoint = null, $thousandSeperator = null){
|
||||
$subShipping = $this->shipping_price_net
|
||||
return $this->numberFormat($subShipping, $decimals, $decimalPoint, $thousandSeperator);
|
||||
}*/
|
||||
//netto
|
||||
public function subtotalWithShipping($decimals = null, $decimalPoint = null, $thousandSeperator = null)
|
||||
{
|
||||
$subtotal = (float) $this->shipping_price_net + $this->subtotal(2, '.', '');
|
||||
return $this->numberFormat($subtotal, $decimals, $decimalPoint, $thousandSeperator);
|
||||
}
|
||||
|
||||
|
||||
public function taxWithShipping($decimals = null, $decimalPoint = null, $thousandSeperator = null)
|
||||
{
|
||||
if($this->user_tax_free){
|
||||
return $this->numberFormat(0, $decimals, $decimalPoint, $thousandSeperator);
|
||||
}
|
||||
$total = $this->totalWithShipping(2, '.', '');
|
||||
// $totalTax = (float) $this->tax(2, '.', '') + $this->shipping_tax;
|
||||
$totalTax = $this->subtotalWithShipping(2, '.', '');
|
||||
return $this->numberFormat(($total - $totalTax), $decimals, $decimalPoint, $thousandSeperator);
|
||||
}
|
||||
|
||||
|
||||
public function totalWithShipping($decimals = null, $decimalPoint = null, $thousandSeperator = null)
|
||||
{
|
||||
if($this->user_tax_free){
|
||||
$total = (float) ($this->subtotal(2, '.', '')) + $this->shipping_price_net;
|
||||
}else{
|
||||
$total = (float) ($this->total(2, '.', '')) + $this->shipping_price;
|
||||
}
|
||||
|
||||
return $this->numberFormat($total, $decimals, $decimalPoint, $thousandSeperator);
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the total price of the items in the cart.
|
||||
*
|
||||
* @param int $decimals
|
||||
* @param string $decimalPoint
|
||||
* @param string $thousandSeperator
|
||||
* @return string
|
||||
*/
|
||||
public function weight($decimals = null, $decimalPoint = null, $thousandSeperator = null)
|
||||
{
|
||||
$content = $this->getContent();
|
||||
$total = $content->reduce(function ($total, CartItem $cartItem) {
|
||||
return $total + ($cartItem->options->weight ? ($cartItem->options->weight*$cartItem->qty) : 0);
|
||||
}, 0);
|
||||
|
||||
return $total;
|
||||
}
|
||||
|
||||
public function weightByFreeShipping($decimals = null, $decimalPoint = null, $thousandSeperator = null)
|
||||
{
|
||||
$content = $this->getContent();
|
||||
$total = $content->reduce(function ($total, CartItem $cartItem) {
|
||||
if($cartItem->options->no_free_shipping){
|
||||
return $total + ($cartItem->options->weight ? ($cartItem->options->weight*$cartItem->qty) : 0);
|
||||
}
|
||||
return $total;
|
||||
}, 0);
|
||||
return $total;
|
||||
}
|
||||
|
||||
public function points()
|
||||
{
|
||||
$content = $this->getContent();
|
||||
$total = $content->reduce(function ($total, CartItem $cartItem) {
|
||||
return $total + ($cartItem->options->points ? ($cartItem->options->points * $cartItem->qty) : 0);
|
||||
}, 0);
|
||||
|
||||
return $total;
|
||||
}
|
||||
|
||||
public function compCount()
|
||||
{
|
||||
$content = $this->getContent();
|
||||
|
||||
$count = parent::count();
|
||||
$comp_count = $content->reduce(function ($comp_count, CartItem $cartItem) {
|
||||
return $cartItem->options->comp ? $comp_count + 1 : $comp_count;
|
||||
}, 0);
|
||||
return $count-$comp_count;
|
||||
}
|
||||
/**
|
||||
* Get the total price of the items in the cart.
|
||||
*
|
||||
* @param int $decimals
|
||||
* @param string $decimalPoint
|
||||
* @param string $thousandSeperator
|
||||
* @return string
|
||||
*/
|
||||
public function total($decimals = NULL, $decimalPoint = NULL, $thousandSeperator = NULL, $withFees = true)
|
||||
{
|
||||
$content = $this->getContent();
|
||||
$total = $content->reduce(function ($total, CartItem $cartItem) {
|
||||
return $total + ($cartItem->qty * $cartItem->price);
|
||||
}, 0);
|
||||
|
||||
return $this->numberFormat($total, $decimals, $decimalPoint, $thousandSeperator);
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the total tax of the items in the cart.
|
||||
*
|
||||
* @param int $decimals
|
||||
* @param string $decimalPoint
|
||||
* @param string $thousandSeperator
|
||||
* @return float
|
||||
*/
|
||||
public function tax($decimals = NULL, $decimalPoint = NULL, $thousandSeperator = NULL, $withFees = true)
|
||||
{
|
||||
$content = $this->getContent();
|
||||
|
||||
$tax = $content->reduce(function ($tax, CartItem $cartItem) {
|
||||
$priceTax = $cartItem->price / (100 + $cartItem->taxRate) * $cartItem->taxRate;
|
||||
return $tax + ($cartItem->qty * $priceTax);
|
||||
}, 0);
|
||||
|
||||
return $this->numberFormat($tax, $decimals, $decimalPoint, $thousandSeperator);
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the subtotal (total - tax) of the items in the cart.
|
||||
*
|
||||
* @param int $decimals
|
||||
* @param string $decimalPoint
|
||||
* @param string $thousandSeperator
|
||||
* @return float
|
||||
*/
|
||||
public function subtotal($decimals = null, $decimalPoint = null, $thousandSeperator = null)
|
||||
{
|
||||
$content = $this->getContent();
|
||||
|
||||
$subTotal = $content->reduce(function ($subTotal, CartItem $cartItem) {
|
||||
$price_net = $cartItem->price / ((100 + $cartItem->taxRate) / 100);
|
||||
return $subTotal + ($cartItem->qty * $price_net);
|
||||
}, 0);
|
||||
|
||||
return $this->numberFormat($subTotal, $decimals, $decimalPoint, $thousandSeperator);
|
||||
}
|
||||
|
||||
|
||||
public function getCartItemByProduct($product_id, $set_price='with'){
|
||||
if($product = Product::find($product_id)) {
|
||||
$image = "";
|
||||
if ($product->images->count()) {
|
||||
$image = $product->images->first()->slug;
|
||||
}
|
||||
$price = $product->price;
|
||||
if($set_price === 'with'){
|
||||
$cartItem = $this->getCartItem($product->id, $product->getLang('name'), 1, $price, ['image' => $image, 'slug' => $product->slug, 'weight' => $product->weight, 'points' => $product->points, 'no_commission' => $product->no_commission, 'show_on' => $product->show_on]);
|
||||
$price = $product->getPriceWith(false, true, $this->getUserCountry());
|
||||
}
|
||||
if($set_price === 'withTaxFree'){
|
||||
$cartItem = $this->getCartItem($product->id, $product->getLang('name'), 1, $price, ['image' => $image, 'slug' => $product->slug, 'weight' => $product->weight, 'points' => $product->points, 'no_commission' => $product->no_commission, 'no_free_shipping' => $product->no_free_shipping, 'show_on' => $product->show_on]);
|
||||
$price = $product->getPriceWith($this->getUserTaxFree(), false, $this->getUserCountry());
|
||||
}
|
||||
$content = $this->getContent();
|
||||
|
||||
if ($content->has($cartItem->rowId)){
|
||||
return $content->get($cartItem->rowId);
|
||||
}
|
||||
return $cartItem;
|
||||
}
|
||||
return null;
|
||||
|
||||
}
|
||||
|
||||
|
||||
public function getCartItem($id, $name = null, $qty = null, $price = null, array $options = []){
|
||||
if ($id instanceof Buyable) {
|
||||
$cartItem = CartItem::fromBuyable($id, $qty ?: []);
|
||||
} elseif (is_array($id)) {
|
||||
$cartItem = CartItem::fromArray($id);
|
||||
} else {
|
||||
$cartItem = CartItem::fromAttributes($id, $name, $price, $options);
|
||||
}
|
||||
return $cartItem;
|
||||
}
|
||||
|
||||
public function destroy()
|
||||
{
|
||||
// $this->ysession->remove($this->yinstance);
|
||||
parent::destroy();
|
||||
|
||||
}
|
||||
|
||||
public function rowPriceNet(CartItem $row, $decimals = null, $decimalPoint = null, $thousandSeperator = null){
|
||||
$price = round($row->price / ((100 + $row->taxRate) /100), 4);
|
||||
return $this->numberFormat($price, $decimals, $decimalPoint, $thousandSeperator);
|
||||
}
|
||||
|
||||
public function rowSubtotalNet(CartItem $row, $decimals = null, $decimalPoint = null, $thousandSeperator = null){
|
||||
$price = round($row->price / ((100 + $row->taxRate) /100), 4);
|
||||
return $this->numberFormat(($price * $row->qty), $decimals, $decimalPoint, $thousandSeperator);
|
||||
}
|
||||
|
||||
public function isPriceCurrency()
|
||||
{
|
||||
return ($this->user_country && $this->user_country->currency) ? true : false;
|
||||
}
|
||||
|
||||
public function getPriceCurrencyUnit()
|
||||
{
|
||||
return ($this->user_country && $this->user_country->currency) ? $this->user_country->currency_unit : false;
|
||||
}
|
||||
|
||||
public function convertCurrency($value = 0, $decimals = null, $decimalPoint = null, $thousandSeperator = null){
|
||||
if($this->isPriceCurrency()){
|
||||
$faktor = isset($this->user_country->currency_faktor) ? $this->user_country->currency_faktor : 1;
|
||||
$value = Util::reFormatNumber($value);
|
||||
return $this->numberFormat($value, $decimals, $decimalPoint, $thousandSeperator);
|
||||
}
|
||||
return '';
|
||||
|
||||
}
|
||||
public function getCurrencyByKey($key = false, CartItem $row = null, $decimals = null, $decimalPoint = null, $thousandSeperator = null){
|
||||
|
||||
if($this->isPriceCurrency()){
|
||||
$rNumber = 0;
|
||||
$faktor = isset($this->user_country->currency_faktor) ? $this->user_country->currency_faktor : 1;
|
||||
switch ($key) {
|
||||
case 'rowPriceNetCurrency':
|
||||
if($row){
|
||||
$price = round($row->price / ((100 + $row->taxRate) /100), 4);
|
||||
$rNumber = $price * $faktor;
|
||||
}
|
||||
break;
|
||||
case 'rowSubtotalCurrency':
|
||||
if($row){
|
||||
$price = round($row->price / ((100 + $row->taxRate) /100), 4);
|
||||
$rNumber = $price * $faktor * $row->qty;
|
||||
}
|
||||
break;
|
||||
case 'subtotal':
|
||||
$rNumber = (float) ($this->subtotal(2, '.', '')) * $faktor;
|
||||
break;
|
||||
case 'price':
|
||||
$rNumber = (float) $row->price * $faktor;
|
||||
break;
|
||||
case 'shippingNet':
|
||||
$rNumber = (float) ($this->shippingNet(2, '.', '')) * $faktor;
|
||||
break;
|
||||
case 'subtotalWithShipping':
|
||||
$rNumber = (float) ($this->subtotalWithShipping(2, '.', '')) * $faktor;
|
||||
break;
|
||||
case 'taxWithShipping':
|
||||
$rNumber = (float) ($this->taxWithShipping(2, '.', '')) * $faktor;
|
||||
break;
|
||||
case 'totalWithShipping':
|
||||
$rNumber = (float) ($this->totalWithShipping(2, '.', '')) * $faktor;
|
||||
break;
|
||||
case 'total':
|
||||
$rNumber = (float) ($this->total(2, '.', '')) * $faktor;
|
||||
break;
|
||||
case 'shipping':
|
||||
$rNumber = (float) ($this->shipping(2, '.', '')) * $faktor;
|
||||
break;
|
||||
}
|
||||
return $this->numberFormat($rNumber, $decimals, $decimalPoint, $thousandSeperator);
|
||||
|
||||
}
|
||||
return '';
|
||||
}
|
||||
|
||||
public function getNumComp(){
|
||||
return $this->num_comp;
|
||||
}
|
||||
|
||||
public function getCompProductBy($comp, $product_id=false){
|
||||
foreach ($this->content() as $row) {
|
||||
if($row->options->comp == $comp) {
|
||||
return $row->options->product_id;
|
||||
}
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
public function getContentByOrder(){
|
||||
$ret = [];
|
||||
$comp = [];
|
||||
foreach ($this->content() as $row) {
|
||||
if($row->options->comp){
|
||||
$comp[100+$row->options->comp] = $row;
|
||||
}else{
|
||||
$ret[] = $row;
|
||||
}
|
||||
}
|
||||
ksort($comp);
|
||||
$ret = array_merge($ret, $comp);
|
||||
return $ret;
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the Formated number
|
||||
*
|
||||
* @param $value
|
||||
* @param $decimals
|
||||
* @param $decimalPoint
|
||||
* @param $thousandSeperator
|
||||
* @return string
|
||||
*/
|
||||
protected function numberFormat($value, $decimals, $decimalPoint, $thousandSeperator)
|
||||
{
|
||||
if(is_null($decimals)){
|
||||
$decimals = is_null(config('cart.format.decimals')) ? 2 : config('cart.format.decimals');
|
||||
}
|
||||
if(is_null($decimalPoint)){
|
||||
$decimalPoint = is_null(config('cart.format.decimal_point')) ? '.' : config('cart.format.decimal_point');
|
||||
}
|
||||
if(is_null($thousandSeperator)){
|
||||
$thousandSeperator = is_null(config('cart.format.thousand_seperator')) ? ',' : config('cart.format.thousand_seperator');
|
||||
}
|
||||
|
||||
return number_format($value, $decimals, $decimalPoint, $thousandSeperator);
|
||||
}
|
||||
|
||||
|
||||
public function myStore($identifier, array $eventOptions = [])
|
||||
{
|
||||
|
||||
// Remove any existing identifiers
|
||||
// Although possibly first or update could work in future
|
||||
$this
|
||||
->getConnection()
|
||||
->table($this->getTableName())
|
||||
->where('identifier', $identifier)
|
||||
->delete();
|
||||
|
||||
// Insert into the database with the new cart
|
||||
$content = $this->getContent();
|
||||
$this->getConnection()->table($this->getTableName())->insert([
|
||||
'identifier' => $identifier,
|
||||
'instance' => $this->currentInstance(),
|
||||
'content' => serialize($content)
|
||||
]);
|
||||
$eventOptions = array_merge([
|
||||
'cartInstance' => $this->currentInstance(),
|
||||
], $eventOptions);
|
||||
|
||||
// $this->events->dispatch('cart.stored', $eventOptions);
|
||||
}
|
||||
|
||||
/**
|
||||
* Restore the cart with the given identifier.
|
||||
*
|
||||
* @param mixed $identifier
|
||||
* @return void
|
||||
*/
|
||||
|
||||
|
||||
|
||||
}
|
||||
94
dev/app-bak/Services/dbip/MyDBIP.php
Normal file
94
dev/app-bak/Services/dbip/MyDBIP.php
Normal file
|
|
@ -0,0 +1,94 @@
|
|||
<?php
|
||||
|
||||
/**
|
||||
*
|
||||
* DB-IP.com database query and management class
|
||||
*
|
||||
* Copyright (C) 2022 db-ip.com
|
||||
*
|
||||
* This library is free software; you can redistribute it and/or
|
||||
* modify it under the terms of the GNU Lesser General Public
|
||||
* License as published by the Free Software Foundation; either
|
||||
* version 2.1 of the License, or (at your option) any later version.
|
||||
*
|
||||
* This library is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
||||
* Lesser General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU Lesser General Public
|
||||
* License along with this library; if not, write to the Free Software
|
||||
* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
|
||||
*
|
||||
*/
|
||||
|
||||
namespace App\Services\dbip;
|
||||
|
||||
use PDO;
|
||||
use Exception;
|
||||
use PDOException;
|
||||
use App\Models\DbipLookup;
|
||||
use App\Models\DbipLookup2;
|
||||
use App\Models\DbipLookup3;
|
||||
use Illuminate\Support\Facades\Storage;
|
||||
|
||||
|
||||
class DBIPException extends Exception {
|
||||
|
||||
}
|
||||
|
||||
class MyDBIP {
|
||||
|
||||
const VERSION = 4;
|
||||
|
||||
|
||||
static public function lookup($addr) {
|
||||
if ($ret = self::doLookup(self::addrType($addr), inet_pton($addr))) {
|
||||
return $ret;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
static public function doLookup($addrType, $addrStart) {
|
||||
|
||||
$res = DbipLookup::where('addr_type', $addrType)->where('ip_start', '<=', $addrStart)->orderBy('ip_start', 'desc')->first();
|
||||
$c1 = isset($res->country) ? $res->country : null;
|
||||
|
||||
$res = DbipLookup2::where('addr_type', $addrType)->where('ip_start', '<=', $addrStart)->orderBy('ip_start', 'desc')->first();
|
||||
$c2 = isset($res->country) ? $res->country : null;
|
||||
|
||||
if($c1 == $c2){
|
||||
return $c1;
|
||||
}
|
||||
|
||||
$res = DbipLookup3::where('addr_type', $addrType)->where('ip_start', '<=', $addrStart)->orderBy('ip_start', 'desc')->first();
|
||||
if(isset($res->country)){
|
||||
return $res->country;
|
||||
}
|
||||
|
||||
//look in api
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
static private function addrType($addr) {
|
||||
if (ip2long($addr) !== false) {
|
||||
return "ipv4";
|
||||
} else if (preg_match('/^[0-9a-fA-F:]+$/', $addr) && @inet_pton($addr)) {
|
||||
return "ipv6";
|
||||
}
|
||||
throw new DBIPException("unknown address type for {$addr}");
|
||||
}
|
||||
|
||||
static public function insert($addr, $country) {
|
||||
|
||||
$lookup = new DbipLookup3();
|
||||
$lookup->addr_type = self::addrType($addr);
|
||||
$lookup->ip_start = inet_pton($addr);
|
||||
$lookup->ip_end = inet_pton($addr);
|
||||
$lookup->country = strtoupper($country);
|
||||
$lookup->save();
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
211
dev/app-bak/Services/dbip/dbip-convert.php
Executable file
211
dev/app-bak/Services/dbip/dbip-convert.php
Executable file
|
|
@ -0,0 +1,211 @@
|
|||
#!/usr/bin/env php
|
||||
<?php
|
||||
|
||||
/**
|
||||
*
|
||||
* DB-IP.com CSV database format conversion tool
|
||||
*
|
||||
* Copyright (C) 2020 db-ip.com
|
||||
*
|
||||
* This library is free software; you can redistribute it and/or
|
||||
* modify it under the terms of the GNU Lesser General Public
|
||||
* License as published by the Free Software Foundation; either
|
||||
* version 2.1 of the License, or (at your option) any later version.
|
||||
*
|
||||
* This library is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
||||
* Lesser General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU Lesser General Public
|
||||
* License along with this library; if not, write to the Free Software
|
||||
* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
|
||||
*
|
||||
*/
|
||||
|
||||
$outputFormats = [
|
||||
"range" => function(array $csvData, $of, string $firstIpBin, string $lastIpBin): void {
|
||||
writeCSV($of, $csvData);
|
||||
},
|
||||
"cidr" => function(array $csvData, $of, string $firstIpBin, string $lastIpBin): void {
|
||||
array_shift($csvData);
|
||||
foreach (rangeToCIDR($firstIpBin, $lastIpBin) as $cidrNet) {
|
||||
$csvData[0] = $cidrNet;
|
||||
writeCSV($of, $csvData);
|
||||
}
|
||||
},
|
||||
"long" => function(array $csvData, $of, string $firstIpBin, string $lastIpBin): void {
|
||||
if (($firstIpLong = ip2long($csvData[0])) === false) {
|
||||
throw new Exception("invalid IP address for long conversion : {$csvData[0]}");
|
||||
} else if (($lastIpLong = ip2long($csvData[1])) === false) {
|
||||
throw new Exception("invalid IP address for long conversion : {$csvData[1]}");
|
||||
}
|
||||
$csvData[0] = $firstIpLong;
|
||||
$csvData[1] = $lastIpLong;
|
||||
writeCSV($of, $csvData);
|
||||
},
|
||||
];
|
||||
|
||||
function writeCSV($of, $csvData) {
|
||||
fputcsv($of, $csvData);
|
||||
}
|
||||
|
||||
function vEcho(string $s): void {
|
||||
if (!$GLOBALS["verbose"]) {
|
||||
return;
|
||||
}
|
||||
echo $s;
|
||||
}
|
||||
|
||||
function findLargestNetwork(string $ipStartBin): int {
|
||||
for ($i = strlen($ipStartBin); $i--; $i >= 0) {
|
||||
$byte = ord($ipStartBin[$i]);
|
||||
for ($j = 7; $j >= 0; $j--) {
|
||||
if ($byte & (0xff >> $j)) {
|
||||
return ($i << 3) + $j + 1;
|
||||
}
|
||||
}
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
function getLastAddress(string $ipStartBin, int $cidrBits): string {
|
||||
$ret = $ipStartBin;
|
||||
for ($i = strlen($ipStartBin); $i--; $i >= 0) {
|
||||
$firstBit = ($i << 3) + 1;
|
||||
$lastBit = ($i + 1) << 3;
|
||||
if ($cidrBits > $lastBit) {
|
||||
continue;
|
||||
} else if ($cidrBits < $firstBit) {
|
||||
$ret[$i] = "\xff";
|
||||
} else {
|
||||
$ret[$i] = chr(ord($ret[$i]) | (0xff >> ($cidrBits - $firstBit + 1)));
|
||||
}
|
||||
}
|
||||
return $ret;
|
||||
}
|
||||
|
||||
function getNextAddress(string $ipStartBin): string {
|
||||
$ret = $ipStartBin;
|
||||
for ($i = strlen($ipStartBin); $i--; $i >= 0) {
|
||||
for ($j = 7; $j >= 0; $j--) {
|
||||
$byte = ord($ret[$i]);
|
||||
$mask = 1 << (7 - $j);
|
||||
if ($byte & $mask) {
|
||||
$ret[$i] = chr($byte & ~$mask);
|
||||
} else {
|
||||
$ret[$i] = chr($byte | $mask);
|
||||
return $ret;
|
||||
}
|
||||
}
|
||||
}
|
||||
throw new Exception("no next address for " . inet_ntop($ipStartBin));
|
||||
}
|
||||
|
||||
function rangeToCIDR(string $ipStartBin, string $ipEndBin): array {
|
||||
if (strcmp($ipStartBin, $ipEndBin) > 0) {
|
||||
throw new Exception("wrong ip address order");
|
||||
}
|
||||
$cidrNets = [];
|
||||
$cidrBits = findLargestNetwork($ipStartBin);
|
||||
do {
|
||||
$lastAddrBin = getLastAddress($ipStartBin, $cidrBits);
|
||||
if (($cmp = strcmp($lastAddrBin, $ipEndBin)) <= 0) {
|
||||
$cidrNets[] = inet_ntop($ipStartBin) . "/" . $cidrBits;
|
||||
if ($cmp === 0) {
|
||||
return $cidrNets;
|
||||
}
|
||||
$ipStartBin = getNextAddress($lastAddrBin);
|
||||
$cidrBits = findLargestNetwork($ipStartBin);
|
||||
} else {
|
||||
$cidrBits++;
|
||||
}
|
||||
} while (true);
|
||||
}
|
||||
|
||||
try {
|
||||
|
||||
$exitCode = 0;
|
||||
$opts = getopt("i:o:f:qhw46");
|
||||
$verbose = !isset($opts["q"]);
|
||||
|
||||
if (!$opts || isset($opts["h"]) || !isset($opts["i"]) || !isset($opts["o"]) || !isset($opts["f"]) || (isset($opts["4"]) && isset($opts["6"]))) {
|
||||
echo "usage: {$argv[0]} -i <inputFileName.csv> -o <outputFileName.csv> -f <outputFormat> [-4|-6] [-w] [-q]\n";
|
||||
echo " -i input CSV file\n";
|
||||
echo " -o output file name\n";
|
||||
echo " -f output format (" . implode("|", array_keys($outputFormats)) . ")\n";
|
||||
echo " -4 output ipv4 networks only\n";
|
||||
echo " -6 output ipv6 networks only\n";
|
||||
echo " -w overwrite output file if it already exists\n";
|
||||
echo " -q be quiet\n";
|
||||
exit(1);
|
||||
}
|
||||
|
||||
$inputFile = $opts["i"];
|
||||
if (!file_exists($inputFile)) {
|
||||
throw new Exception("cannot find input file: {$inputFile}");
|
||||
} else if (!is_readable($inputFile)) {
|
||||
throw new Exception("cannot read input file: {$inputFile}");
|
||||
}
|
||||
if (substr($inputFile, -3) === ".gz") {
|
||||
$inputFile = "compress.zlib://" . $inputFile;
|
||||
}
|
||||
if (!$if = fopen($inputFile, "r")) {
|
||||
throw new Exception("cannot open input file: {$inputFile}");
|
||||
}
|
||||
|
||||
$outputFile = $opts["o"];
|
||||
if (file_exists($outputFile) && !isset($opts["w"])) {
|
||||
throw new Exception("output file {$outputFile} already exists, use -w to force overwrite");
|
||||
}
|
||||
if (substr($outputFile, -3) === ".gz") {
|
||||
$outputFile = "compress.zlib://" . $outputFile;
|
||||
}
|
||||
if (!$of = fopen($outputFile, "w")) {
|
||||
throw new Exception("cannot open output file: {$outPutFile}");
|
||||
}
|
||||
|
||||
if (!isset($outputFormats[$opts["f"]])) {
|
||||
throw new Exception("invalid output format {$opts['f']}");
|
||||
}
|
||||
$outputFormatter = $outputFormats[$opts["f"]];
|
||||
|
||||
$i = 0;
|
||||
while ($r = fgetcsv($if, 8192)) {
|
||||
$i++;
|
||||
[ $firstIp, $lastIp ] = $r;
|
||||
try {
|
||||
if (!$firstIpBin = inet_pton($firstIp)) {
|
||||
throw new Exception("invalid first IP '{$firstIp}' in CSV record");
|
||||
} else if (!$lastIpBin = inet_pton($lastIp)) {
|
||||
throw new Exception("invalid last IP '{$lastIp}' in CSV record");
|
||||
} else if (($addrLen = strlen($firstIpBin)) !== strlen($lastIpBin)) {
|
||||
throw new Exception("first and last IP address family mismatch ({$firstIp} / {$lastIp})");
|
||||
}
|
||||
if (isset($opts["4"]) && ($addrLen !== 4)) {
|
||||
continue;
|
||||
} else if (isset($opts["6"]) && ($addrLen !== 16)) {
|
||||
continue;
|
||||
}
|
||||
$outputFormatter($r, $of, $firstIpBin, $lastIpBin);
|
||||
} catch (Exception $e) {
|
||||
throw new Exception("line {$i}: {$e->getMessage()}");
|
||||
}
|
||||
}
|
||||
fclose($if);
|
||||
fclose($of);
|
||||
|
||||
vEcho("Wrote {$outputFile}\n");
|
||||
|
||||
} catch (Exception $e) {
|
||||
if ($stdErr = @fopen("php://stderr", "w")) {
|
||||
fwrite($stdErr, "ERROR: {$e->getMessage()}\n");
|
||||
fclose($stdErr);
|
||||
} else {
|
||||
echo "ERROR: {$e->getMessage()}\n";
|
||||
}
|
||||
$exitCode = 1;
|
||||
}
|
||||
if ($exitCode) {
|
||||
exit($exitCode);
|
||||
}
|
||||
10
dev/app-bak/Services/dbip/dbip-update.ini.sample
Normal file
10
dev/app-bak/Services/dbip/dbip-update.ini.sample
Normal file
|
|
@ -0,0 +1,10 @@
|
|||
[account]
|
||||
; Your account key is available in your customer section at https://db-ip.com/account/
|
||||
accountKey = INSERT_YOUR_ACCOUNT_KEY_HERE
|
||||
|
||||
[database]
|
||||
; This is the PDO Data Source Name for your database instance, see http://php.net/manual/pdo.construct.php
|
||||
dataSourceName = "mysql:host=localhost;dbname=myapp"
|
||||
; dbUser and dbPassword are the database account credentials
|
||||
dbUser = myapp
|
||||
dbPassword = myapp123
|
||||
327
dev/app-bak/Services/dbip/dbip-update.php
Executable file
327
dev/app-bak/Services/dbip/dbip-update.php
Executable file
|
|
@ -0,0 +1,327 @@
|
|||
#!/usr/bin/env php
|
||||
<?php
|
||||
|
||||
/**
|
||||
*
|
||||
* DB-IP.com database update tool
|
||||
*
|
||||
* Copyright (C) 2021 db-ip.com
|
||||
*
|
||||
* This library is free software; you can redistribute it and/or
|
||||
* modify it under the terms of the GNU Lesser General Public
|
||||
* License as published by the Free Software Foundation; either
|
||||
* version 2.1 of the License, or (at your option) any later version.
|
||||
*
|
||||
* This library is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
||||
* Lesser General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU Lesser General Public
|
||||
* License along with this library; if not, write to the Free Software
|
||||
* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
|
||||
*
|
||||
*/
|
||||
|
||||
require "dbip.class.php";
|
||||
|
||||
const API_BASE = "https://db-ip.com/account";
|
||||
const DEFAULT_CONF = "dbip-update.ini";
|
||||
|
||||
function apiRequest($path, $key) {
|
||||
$url = API_BASE . "/" . $key . "/db" . $path;
|
||||
if (($jsonData = file_get_contents($url)) === false) {
|
||||
throw new Exception("cannot fetch API result from {$url}");
|
||||
} else if (!isset($jsonData) || !$jsonData || (($resp = json_decode($jsonData)) === false)) {
|
||||
throw new Exception("cannot decode API result from {$url}");
|
||||
} else if (isset($resp->error)) {
|
||||
throw new Exception("API error: {$resp->error}");
|
||||
}
|
||||
return $resp;
|
||||
}
|
||||
|
||||
function vEcho($s) {
|
||||
if (!$GLOBALS["verbose"]) {
|
||||
return false;
|
||||
}
|
||||
echo $s;
|
||||
}
|
||||
|
||||
try {
|
||||
|
||||
$exitCode = 0;
|
||||
$opts = getopt("k:d:f:o:zZqlnwb:u:p:t:c:D");
|
||||
$verbose = !isset($opts["q"]);
|
||||
|
||||
if (isset($opts["c"])) {
|
||||
if (!file_exists($opts["c"]) || !is_readable($opts["c"])) {
|
||||
throw new Exception("cannot read configuration file {$opts['c']}");
|
||||
}
|
||||
$confName = $opts["c"];
|
||||
} else if (file_exists(__DIR__ . DIRECTORY_SEPARATOR . DEFAULT_CONF) && is_readable(__DIR__ . DIRECTORY_SEPARATOR . DEFAULT_CONF)) {
|
||||
$confName = __DIR__ . DIRECTORY_SEPARATOR . DEFAULT_CONF;
|
||||
}
|
||||
|
||||
if (isset($confName)) {
|
||||
if (($conf = parse_ini_file($confName)) === false) {
|
||||
throw new Exception("cannot parse configuration file {$confName}");
|
||||
}
|
||||
$confMap = [
|
||||
"accountKey" => "k",
|
||||
"dbType" => "d",
|
||||
"format" => "f",
|
||||
"outputDir" => "o",
|
||||
"outputFileName" => "o",
|
||||
"dataSourceName" => "b",
|
||||
"dbUser" => "u",
|
||||
"dbPassword" => "p",
|
||||
"dbTableName" => "t",
|
||||
];
|
||||
foreach ($conf as $name => $value) {
|
||||
if (!isset($confMap[$name])) {
|
||||
throw new Exception("invalid configuration parameter {$name}");
|
||||
} else if (!isset($opts[$confMap[$name]])) {
|
||||
$opts[$confMap[$name]] = $value;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (!isset($opts["k"]) || !$opts["k"]) {
|
||||
echo "usage: {$argv[0]} -k <accountKey> [-l] [-d <dbType>] [-f <format>] [-o <outputDir|outputFileName>] [-b <dataSourceName> [-u <dbUser>] [-p <dbPassword] [-t <dbTableName>] [-D]] [-c <configFile>] [-n] [-z|-Z] [-w] [-q]\n";
|
||||
echo " -l list available items and exit\n";
|
||||
echo " -n request new items only\n";
|
||||
echo " -z fetch uncompressed file (default for mmdb format)\n";
|
||||
echo " -Z fetch compressed file (default for csv format)\n";
|
||||
echo " -w overwrite destination file if it already exists\n";
|
||||
echo " -b PDO DSN for database update (ie. \"mysql:host=localhost;dbname=dbip\")\n";
|
||||
echo " -u database username (default 'root')\n";
|
||||
echo " -p database password (default '')\n";
|
||||
echo " -t name of database table (default 'dbip_lookup')\n";
|
||||
echo " -D do not use a temporary table (table specified by -t must be empty)\n";
|
||||
echo " -q be quiet\n";
|
||||
exit(1);
|
||||
}
|
||||
$apiKey = $opts["k"];
|
||||
|
||||
if (!isset($opts["d"])) {
|
||||
$dbList = apiRequest("/", $apiKey);
|
||||
if (count((array)$dbList) > 1) {
|
||||
vEcho("Use -d to select a database type :\n");
|
||||
foreach ($dbList as $dbType => $dbInfo) {
|
||||
echo $dbType . "\n";
|
||||
}
|
||||
exit();
|
||||
} else {
|
||||
foreach ($dbList as $dbType => $dbInfo) {
|
||||
break;
|
||||
}
|
||||
}
|
||||
} else {
|
||||
$dbType = $opts["d"];
|
||||
}
|
||||
|
||||
if (isset($opts["b"])) {
|
||||
if (isset($opts["o"])) {
|
||||
throw new Exception("Arguments -b and -o cannot be used in the same command line");
|
||||
}
|
||||
$dbUser = isset($opts["u"]) ? $opts["u"] : "root";
|
||||
$dbPassword = isset($opts["p"]) ? $opts["p"] : "";
|
||||
$dbTable = isset($opts["t"]) ? $opts["t"] : "dbip_lookup";
|
||||
$format = "csv";
|
||||
try {
|
||||
$dsn = $opts["b"];
|
||||
if (preg_match('/^mysql:/', $dsn)) {
|
||||
if (!preg_match('/charset=/', $dsn)) {
|
||||
$dsn .= ";charset=utf8mb4";
|
||||
}
|
||||
$dbQuoteChar = '`'; // backquote for MySQL
|
||||
} else {
|
||||
$dbQuoteChar = '"'; // double quote for ANSI SQL
|
||||
}
|
||||
$db = new PDO($dsn, $dbUser, $dbPassword);
|
||||
$db->setAttribute(PDO::ATTR_ERRMODE, PDO::ERRMODE_EXCEPTION);
|
||||
$db->setAttribute(PDO::ATTR_EMULATE_PREPARES, false);
|
||||
$dbUseTempTable = !isset($opts["D"]);
|
||||
} catch (PDOException $e) {
|
||||
throw new Exception("Cannot connect to database: {$e->getMessage()}");
|
||||
}
|
||||
} else {
|
||||
if (!isset($opts["f"])) {
|
||||
$filesList = apiRequest("/{$dbType}", $apiKey);
|
||||
vEcho("Use -f to specify a format for your {$dbType} subscription :\n");
|
||||
foreach ($filesList as $format => $fileInfo) {
|
||||
echo $format . "\n";
|
||||
}
|
||||
exit();
|
||||
}
|
||||
$format = $opts["f"];
|
||||
}
|
||||
$onlyNew = isset($opts["n"]);
|
||||
|
||||
try {
|
||||
$queryString = $onlyNew ? "?new=1" : "";
|
||||
$fileInfo = apiRequest("/{$dbType}/{$format}{$queryString}", $apiKey);
|
||||
if ($onlyNew && !$fileInfo) {
|
||||
vEcho("there are no new downloads available\n");
|
||||
exit(0);
|
||||
}
|
||||
} catch (Exception $e) {
|
||||
throw new Exception("cannot access download info : {$e->getMessage()}");
|
||||
}
|
||||
|
||||
if (isset($opts["l"])) {
|
||||
if (!isset($fileInfo)) {
|
||||
vEcho("no download file match\n");
|
||||
exit();
|
||||
}
|
||||
foreach ($fileInfo as $name => $value) {
|
||||
echo "{$name}: {$value}\n";
|
||||
}
|
||||
exit();
|
||||
}
|
||||
|
||||
if (isset($opts["z"])) {
|
||||
$uncompress = true;
|
||||
} else if (isset($opts["Z"]) || ($format === "csv")) {
|
||||
$uncompress = false;
|
||||
} else {
|
||||
$uncompress = true;
|
||||
}
|
||||
|
||||
$outputFile = "." . DIRECTORY_SEPARATOR . $fileInfo->name;
|
||||
if (isset($opts["o"])) {
|
||||
if (is_dir($opts["o"])) {
|
||||
$outputFile = $opts["o"] . DIRECTORY_SEPARATOR . $fileInfo->name;
|
||||
} else {
|
||||
$outputFile = $opts["o"];
|
||||
}
|
||||
}
|
||||
$sourcePrefix = $uncompress ? "compress.zlib://" : "";
|
||||
if ($uncompress && preg_match('/\.gz$/i', $outputFile)) {
|
||||
$outputFile = preg_replace('/\.gz$/i', '', $outputFile);
|
||||
}
|
||||
$outputTempFile = $outputFile . ".update-tmp";
|
||||
|
||||
if (file_exists($outputTempFile) && !unlink($outputTempFile)) {
|
||||
throw new Exception("cannot delete temporary file {$outputTempFile}");
|
||||
} else if (!isset($db) && file_exists($outputFile) && !isset($opts["w"])) {
|
||||
throw new Exception("destination file {$outputFile} already exists, use -w to force overwrite");
|
||||
}
|
||||
|
||||
vEcho("Starting update for {$dbType} ({$fileInfo->date})\n");
|
||||
if (!copy($sourcePrefix . $fileInfo->url, $outputTempFile, stream_context_create([], [ "notification" => function($notificationCode, $severity, $message, $messageCode, $bytesTransferred, $bytesMax) {
|
||||
static $totBytes, $prevPct = false;
|
||||
if ($bytesMax) {
|
||||
$totBytes = $bytesMax;
|
||||
}
|
||||
if ($bytesTransferred) {
|
||||
if (isset($totBytes) && $totBytes) {
|
||||
$pct = number_format(($bytesTransferred / $totBytes) * 100, 1);
|
||||
}
|
||||
if ($pct !== $prevPct) {
|
||||
vEcho("\rDownloading: " . number_format($bytesTransferred / 1024) . " KB" . (isset($pct) ? " ({$pct}%)" : ""));
|
||||
$prevPct = $pct;
|
||||
}
|
||||
}
|
||||
}]))) {
|
||||
throw new Exception("unable to download file to {$outputTempFile}");
|
||||
}
|
||||
vEcho("\rDownload completed: " . number_format(filesize($outputTempFile) / 1024, 1) . " KB\n");
|
||||
|
||||
$checkPrefix = $uncompress ? "" : "compress.zlib://";
|
||||
if (isset($fileInfo->md5sum) || isset($fileInfo->sha1sum)) {
|
||||
vEcho("Verify signature: ");
|
||||
if (isset($fileInfo->md5sum)) {
|
||||
$md5sum = md5_file($checkPrefix . $outputTempFile);
|
||||
if ($md5sum !== $fileInfo->md5sum) {
|
||||
vEcho("MISMATCH {$md5sum} != {$fileInfo->md5sum}\n");
|
||||
throw new Exception("MD5 signature verification failed, file is probably corrupt or altered");
|
||||
}
|
||||
vEcho("[MD5] ");
|
||||
}
|
||||
if (isset($fileInfo->sha1sum)) {
|
||||
$sha1sum = sha1_file($checkPrefix . $outputTempFile);
|
||||
if ($sha1sum !== $fileInfo->sha1sum) {
|
||||
vEcho("MISMATCH {$sha1sum} != {$fileInfo->sha1sum}\n");
|
||||
throw new Exception("SHA1 signature verification failed, file is probably corrupt or altered");
|
||||
}
|
||||
vEcho("[SHA1] ");
|
||||
}
|
||||
vEcho("passed\n");
|
||||
}
|
||||
|
||||
if (isset($db)) {
|
||||
$dbip = new DBIP($db, $dbQuoteChar);
|
||||
$relId = $dbType;
|
||||
if ($fileInfo->version) {
|
||||
$relId .= "-v{$fileInfo->version}";
|
||||
}
|
||||
switch ($relId) {
|
||||
case "ip-to-country-lite": $importType = DBIP::TYPE_COUNTRY_LITE; break;
|
||||
case "ip-to-city-lite": $importType = DBIP::TYPE_CITY_LITE; break;
|
||||
case "ip-to-country-v4": $importType = DBIP::TYPE_COUNTRY_V4; break;
|
||||
case "ip-to-location-v4": $importType = DBIP::TYPE_LOCATION_V4; break;
|
||||
case "ip-to-isp-v4": $importType = DBIP::TYPE_ISP_V4; break;
|
||||
case "ip-to-location-isp-v4":
|
||||
case "ip-to-full-v4": $importType = DBIP::TYPE_FULL_V4; break;
|
||||
case "ip-to-country-v3": $importType = DBIP::TYPE_COUNTRY_V3; break;
|
||||
case "ip-to-location-v3": $importType = DBIP::TYPE_LOCATION_V3; break;
|
||||
case "ip-to-isp-v3": $importType = DBIP::TYPE_ISP_V3; break;
|
||||
case "ip-to-location-isp-v3":
|
||||
case "ip-to-full-v3": $importType = DBIP::TYPE_FULL_V3; break;
|
||||
case "ip-to-location-v2": $importType = DBIP::TYPE_LOCATION_V2; break;
|
||||
case "ip-to-isp-v2": $importType = DBIP::TYPE_ISP_V2; break;
|
||||
case "ip-to-location-isp-v2":
|
||||
case "ip-to-full-v2": $importType = DBIP::TYPE_FULL_V2; break;
|
||||
default: throw new Exception("unsupported database type");
|
||||
}
|
||||
if ($dbUseTempTable) {
|
||||
$tempTable = "dbip_update_" . time();
|
||||
$db->exec("drop table if exists {$dbQuoteChar}{$tempTable}{$dbQuoteChar}");
|
||||
$db->exec("create table {$dbQuoteChar}{$tempTable}{$dbQuoteChar} like {$dbQuoteChar}{$dbTable}{$dbQuoteChar}");
|
||||
} else {
|
||||
$tempTable = $dbTable;
|
||||
}
|
||||
$dbip->importFromCsv($outputTempFile, $importType, $tempTable, function($numRows) use ($fileInfo) {
|
||||
if ($numRows % 1000) {
|
||||
return false;
|
||||
}
|
||||
if (isset($fileInfo->rows) && $fileInfo->rows) {
|
||||
$pct = number_format(($numRows / $fileInfo->rows) * 100, 1);
|
||||
}
|
||||
vEcho("\rImporting: " . number_format($numRows) . " rows" . (isset($pct) ? " ({$pct}%)" : ""));
|
||||
});
|
||||
$numRows = (int)$db->query("select count(1) cnt from {$dbQuoteChar}{$tempTable}{$dbQuoteChar}")->fetchObject()->cnt;
|
||||
if ($dbUseTempTable) {
|
||||
$db->exec("drop table if exists {$dbQuoteChar}{$tempTable}_old{$dbQuoteChar}");
|
||||
$db->exec("rename table {$dbQuoteChar}{$dbTable}{$dbQuoteChar} to {$dbQuoteChar}{$tempTable}_old{$dbQuoteChar}, {$dbQuoteChar}{$tempTable}{$dbQuoteChar} to {$dbQuoteChar}{$dbTable}{$dbQuoteChar}");
|
||||
$db->exec("drop table {$dbQuoteChar}{$tempTable}_old{$dbQuoteChar}");
|
||||
}
|
||||
vEcho("\rDatabase updated: " . number_format($numRows) . " rows imported\n");
|
||||
} else {
|
||||
if (!rename($outputTempFile, $outputFile)) {
|
||||
throw new Exception("cannot rename temporary file {$outputTempFile} to {$outputFile}");
|
||||
}
|
||||
vEcho("Wrote {$outputFile}\n");
|
||||
}
|
||||
|
||||
} catch (Exception $e) {
|
||||
if ($stdErr = @fopen("php://stderr", "w")) {
|
||||
fwrite($stdErr, "ERROR: {$e->getMessage()}\n");
|
||||
fclose($stdErr);
|
||||
} else {
|
||||
echo "ERROR: {$e->getMessage()}\n";
|
||||
}
|
||||
$exitCode = 1;
|
||||
} finally {
|
||||
if (isset($outputTempFile) && file_exists($outputTempFile)) {
|
||||
unlink($outputTempFile);
|
||||
}
|
||||
if (isset($db) && isset($tempTable) && $dbUseTempTable) {
|
||||
$db->exec("drop table if exists {$dbQuoteChar}{$tempTable}{$dbQuoteChar}");
|
||||
$db->exec("drop table if exists {$dbQuoteChar}{$tempTable}_old{$dbQuoteChar}");
|
||||
}
|
||||
}
|
||||
if ($exitCode) {
|
||||
exit($exitCode);
|
||||
}
|
||||
346
dev/app-bak/Services/dbip/dbip.class.php
Executable file
346
dev/app-bak/Services/dbip/dbip.class.php
Executable file
|
|
@ -0,0 +1,346 @@
|
|||
<?php
|
||||
|
||||
/**
|
||||
*
|
||||
* DB-IP.com database query and management class
|
||||
*
|
||||
* Copyright (C) 2022 db-ip.com
|
||||
*
|
||||
* This library is free software; you can redistribute it and/or
|
||||
* modify it under the terms of the GNU Lesser General Public
|
||||
* License as published by the Free Software Foundation; either
|
||||
* version 2.1 of the License, or (at your option) any later version.
|
||||
*
|
||||
* This library is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
||||
* Lesser General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU Lesser General Public
|
||||
* License along with this library; if not, write to the Free Software
|
||||
* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
|
||||
*
|
||||
*/
|
||||
|
||||
|
||||
|
||||
use PDO;
|
||||
use Exception;
|
||||
use PDOException;
|
||||
|
||||
|
||||
class DBIPException extends Exception {
|
||||
|
||||
}
|
||||
|
||||
class DBIP {
|
||||
|
||||
const VERSION = 4;
|
||||
|
||||
const TYPE_COUNTRY_LITE = 1;
|
||||
const TYPE_CITY_LITE = 2;
|
||||
const TYPE_COUNTRY_V4 = 3;
|
||||
const TYPE_LOCATION_V4 = 4;
|
||||
const TYPE_ISP_V4 = 5;
|
||||
const TYPE_FULL_V4 = 6;
|
||||
|
||||
const TYPE_COUNTRY_V3 = 7;
|
||||
const TYPE_LOCATION_V3 = 8;
|
||||
const TYPE_ISP_V3 = 9;
|
||||
const TYPE_FULL_V3 = 10;
|
||||
|
||||
const TYPE_LOCATION_V2 = 11;
|
||||
const TYPE_ISP_V2 = 12;
|
||||
const TYPE_FULL_V2 = 13;
|
||||
|
||||
const TYPE_COUNTRY_IPINFO = 15;
|
||||
|
||||
const TYPE_COUNTRY = self::TYPE_COUNTRY_V4;
|
||||
const TYPE_LOCATION = self::TYPE_LOCATION_V4;
|
||||
const TYPE_ISP = self::TYPE_ISP_V4;
|
||||
const TYPE_FULL = self::TYPE_FULL_V4;
|
||||
|
||||
private $db;
|
||||
protected $dbQuoteChar = "";
|
||||
|
||||
public function __construct(PDO $db, $dbQuoteChar = "") {
|
||||
$this->db = $db;
|
||||
$this->db->setAttribute(PDO::ATTR_ERRMODE, PDO::ERRMODE_EXCEPTION);
|
||||
$this->dbQuoteChar = $dbQuoteChar;
|
||||
}
|
||||
|
||||
public function importFromCsv($fileName, $type, $tableName = "dbip_lookup", $progressCallback = null) {
|
||||
switch ($type) {
|
||||
case self::TYPE_COUNTRY_LITE:
|
||||
$fields = array("ip_start", "ip_end", "country");
|
||||
$fieldsprepare = $fields;
|
||||
break;
|
||||
case self::TYPE_COUNTRY_IPINFO:
|
||||
$fields = array("ip_start", "ip_end", "country", "d1", "d2", "d3");
|
||||
$fieldsprepare = array("ip_start", "ip_end", "country");
|
||||
break;
|
||||
case self::TYPE_CITY_LITE:
|
||||
$fields = array("ip_start", "ip_end", "continent", "country", "stateprov", "city", "latitude", "longitude");
|
||||
break;
|
||||
case self::TYPE_COUNTRY_V4:
|
||||
case self::TYPE_COUNTRY_V3:
|
||||
$fields = array("ip_start", "ip_end", "continent", "country");
|
||||
break;
|
||||
case self::TYPE_LOCATION_V4:
|
||||
$fields = array("ip_start", "ip_end", "continent", "country", "stateprov_code", "stateprov", "district", "city", "zipcode", "latitude", "longitude", "geoname_id", "timezone_offset", "timezone_name", "weather_code");
|
||||
break;
|
||||
case self::TYPE_ISP_V4:
|
||||
$fields = array("ip_start", "ip_end", "continent", "country", "isp_name", "as_number", "usage_type", "connection_type", "organization_name");
|
||||
break;
|
||||
case self::TYPE_FULL_V4:
|
||||
$fields = array("ip_start", "ip_end", "continent", "country", "stateprov_code", "stateprov", "district", "city", "zipcode", "latitude", "longitude", "geoname_id", "timezone_offset", "timezone_name", "weather_code", "isp_name", "as_number", "usage_type", "connection_type", "organization_name");
|
||||
break;
|
||||
case self::TYPE_LOCATION_V3:
|
||||
$fields = array("ip_start", "ip_end", "continent", "country", "stateprov", "district", "city", "zipcode", "latitude", "longitude", "geoname_id", "timezone_offset", "timezone_name", "weather_code");
|
||||
break;
|
||||
case self::TYPE_ISP_V3:
|
||||
$fields = array("ip_start", "ip_end", "continent", "country", "isp_name", "as_number", "connection_type", "organization_name");
|
||||
break;
|
||||
case self::TYPE_FULL_V3:
|
||||
$fields = array("ip_start", "ip_end", "continent", "country", "stateprov", "district", "city", "zipcode", "latitude", "longitude", "geoname_id", "timezone_offset", "timezone_name", "weather_code", "isp_name", "as_number", "connection_type", "organization_name");
|
||||
break;
|
||||
case self::TYPE_LOCATION_V2:
|
||||
$fields = array("ip_start", "ip_end", "country", "stateprov", "district", "city", "zipcode", "latitude", "longitude", "geoname_id", "timezone_offset", "timezone_name");
|
||||
break;
|
||||
case self::TYPE_ISP_V2:
|
||||
$fields = array("ip_start", "ip_end", "country", "isp_name", "connection_type", "organization_name");
|
||||
break;
|
||||
case self::TYPE_FULL_V2:
|
||||
$fields = array("ip_start", "ip_end", "country", "stateprov", "district", "city", "zipcode", "latitude", "longitude", "geoname_id", "timezone_offset", "timezone_name", "isp_name", "connection_type", "organization_name");
|
||||
break;
|
||||
default:
|
||||
throw new DBIPException("invalid database type");
|
||||
}
|
||||
if (!file_exists($fileName)) {
|
||||
throw new DBIPException("file {$fileName} does not exists");
|
||||
}
|
||||
$q = $this->prepareImport($tableName, $fieldsprepare);
|
||||
if (preg_match('/\.gz(\..+)?$/', $fileName)) {
|
||||
$openName = "compress.zlib://" . $fileName;
|
||||
} else {
|
||||
$openName = $fileName;
|
||||
}
|
||||
$f = @fopen($openName, "r");
|
||||
if (!is_resource($f)) {
|
||||
throw new DBIPException("cannot open {$fileName} for reading");
|
||||
}
|
||||
$nrecs = 0;
|
||||
while ($r = fgetcsv($f, 1024, ",", '"', "\0")) {
|
||||
foreach ($r as $k => $v) {
|
||||
if (!isset($fields[$k])) {
|
||||
throw new DBIPException("invalid CSV record for {$r[0]}");
|
||||
}
|
||||
switch ($fields[$k]) {
|
||||
case "latitude":
|
||||
case "longitude":
|
||||
case "timezone_offset":
|
||||
$r[$k] = (float)$v;
|
||||
break;
|
||||
case "d1":
|
||||
case "d2":
|
||||
case "d3":
|
||||
unset($r[$k]);
|
||||
break;
|
||||
case "isp_name":
|
||||
case "organization_name":
|
||||
$r[$k] = mb_substr($v, 0, 128);
|
||||
break;
|
||||
case "city":
|
||||
case "district":
|
||||
case "stateprov":
|
||||
$r[$k] = mb_substr($v, 0, 80);
|
||||
break;
|
||||
case "zipcode":
|
||||
$r[$k] = mb_substr($v, 0, 20);
|
||||
break;
|
||||
case "timezone_name":
|
||||
$r[$k] = mb_substr($v, 0, 64);
|
||||
break;
|
||||
case "connection_type":
|
||||
case "stateprov_code":
|
||||
case "usage_type":
|
||||
case "geoname_id":
|
||||
case "as_number":
|
||||
if (!$r[$k]) $r[$k] = null;
|
||||
break;
|
||||
default:
|
||||
}
|
||||
}
|
||||
|
||||
try {
|
||||
/*$r[] = self::addrType($r[0]);
|
||||
$r[0] = inet_pton($r[0]);
|
||||
$r[1] = inet_pton($r[1]);*/
|
||||
|
||||
$set = [
|
||||
0 => inet_pton($r[0]),
|
||||
1 => inet_pton($r[1]),
|
||||
2 => $r[2],
|
||||
3 => self::addrType($r[0])
|
||||
];
|
||||
$this->importRow($q, $set);
|
||||
} catch (Exception $e) {
|
||||
throw new Exception("cannot import record #{$nrecs}: {$e->getMessage()}");
|
||||
}
|
||||
if ((($nrecs % 100) === 0) && is_callable($progressCallback)) {
|
||||
call_user_func($progressCallback, $nrecs);
|
||||
}
|
||||
$nrecs++;
|
||||
}
|
||||
fclose($f);
|
||||
$this->finalizeImport();
|
||||
return $nrecs;
|
||||
}
|
||||
|
||||
public function lookup($addr, $tableName = "dbip_lookup") {
|
||||
if ($ret = $this->doLookup($tableName, self::addrType($addr), inet_pton($addr))) {
|
||||
$ret->ip_start = inet_ntop($ret->ip_start);
|
||||
$ret->ip_end = inet_ntop($ret->ip_end);
|
||||
return $ret;
|
||||
} else {
|
||||
throw new DBIPException("address not found");
|
||||
}
|
||||
}
|
||||
|
||||
protected function prepareImport($tableName, array $fields) {
|
||||
try {
|
||||
if ($this->db->query("select count(*) as cnt from {$this->dbQuoteChar}{$tableName}{$this->dbQuoteChar}")->fetchObject()->cnt) {
|
||||
throw new DBIPException("table {$tableName} is not empty");
|
||||
}
|
||||
$this->db->setAttribute(PDO::ATTR_EMULATE_PREPARES, false);
|
||||
$this->db->beginTransaction();
|
||||
$q = $this->db->prepare("insert into {$this->dbQuoteChar}{$tableName}{$this->dbQuoteChar} (" . implode(",", $fields) . ",addr_type) values (" . implode(",", array_fill(0, count($fields), "?")) . ",?)");
|
||||
return $q;
|
||||
} catch (PDOException $e) {
|
||||
throw new DBIPException("database error: {$e->getMessage()}");
|
||||
}
|
||||
}
|
||||
|
||||
protected function finalizeImport() {
|
||||
try{
|
||||
$this->db->commit();
|
||||
}catch (Exception $e) {
|
||||
throw new Exception("commit import record: {$e->getMessage()}");
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
protected function importRow($res, $row) {
|
||||
return $res->execute($row);
|
||||
}
|
||||
|
||||
protected function doLookup($tableName, $addrType, $addrStart) {
|
||||
$q = $this->db->prepare("select * from {$this->dbQuoteChar}{$tableName}{$this->dbQuoteChar} where addr_type = ? and ip_start <= ? order by ip_start desc limit 1");
|
||||
$q->execute(array($addrType, $addrStart));
|
||||
return $q->fetchObject();
|
||||
}
|
||||
|
||||
static private function addrType($addr) {
|
||||
if (ip2long($addr) !== false) {
|
||||
return "ipv4";
|
||||
} else if (preg_match('/^[0-9a-fA-F:]+$/', $addr) && @inet_pton($addr)) {
|
||||
return "ipv6";
|
||||
}
|
||||
throw new DBIPException("unknown address type for {$addr}");
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
/**
|
||||
* DBIP MySQL class
|
||||
*
|
||||
* If you are using a MySQL database backend, please prefer the DBIP base class which uses the PDO mysql driver.
|
||||
* This is only meant to be used on PHP installations where PDO is disabled and the old mysql_* interface is available.
|
||||
*/
|
||||
class DBIPMySQL extends DBIP {
|
||||
|
||||
private $db;
|
||||
|
||||
public function __construct($db) {
|
||||
$this->db = $db;
|
||||
}
|
||||
|
||||
protected function prepareImport($tableName, array $fields) {
|
||||
$q = mysql_query("select count(*) as cnt from {$this->dbQuoteChar}{$tableName}{$this->dbQuoteChar}", $this->db);
|
||||
$r = mysql_fetch_object($q);
|
||||
mysql_free_result($q);
|
||||
if ($r->cnt) {
|
||||
throw new DBIPException("table {$tableName} is not empty");
|
||||
}
|
||||
return array($tableName, $fields);
|
||||
}
|
||||
|
||||
protected function finalizeImport() {
|
||||
}
|
||||
|
||||
protected function importRow($res, $row) {
|
||||
$vals = array();
|
||||
foreach ($row as $val) {
|
||||
$vals[] = "'" . mysql_real_escape_string($val) . "'";
|
||||
}
|
||||
if (!mysql_query("insert into {$this->dbQuoteChar}{$res[0]}{$this->dbQuoteChar} (" . implode(",", $res[1]) . ",addr_type) values (" . implode(",", $vals) . ")", $this->db)) {
|
||||
throw new DBIPException("database error: cannot insert row");
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
protected function doLookup($tableName, $addrType, $addrStart) {
|
||||
$q = mysql_query("select * from {$this->dbQuoteChar}{$tableName}{$this->dbQuoteChar} where addr_type = '{$addrType}' and ip_start <= '" . mysql_real_escape_string($addrStart) . "' order by ip_start desc limit 1", $this->db);
|
||||
$r = mysql_fetch_object($q);
|
||||
mysql_free_result($q);
|
||||
return $r;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
/**
|
||||
* DBIP MySQLI class
|
||||
*
|
||||
* If you are using a MySQL database backend, please prefer the DBIP base class which uses the PDO mysql driver.
|
||||
* This is only meant to be used on PHP installations where PDO is disabled and the old mysqli_* interface is available.
|
||||
*/
|
||||
class DBIPMySQLI extends DBIP {
|
||||
|
||||
private $db;
|
||||
|
||||
public function __construct($db) {
|
||||
$this->db = $db;
|
||||
}
|
||||
|
||||
protected function prepareImport($tableName, array $fields) {
|
||||
$q = mysqli_query($this->db, "select count(*) as cnt from {$this->dbQuoteChar}{$tableName}{$this->dbQuoteChar}");
|
||||
$r = mysqli_fetch_object($q);
|
||||
mysqli_free_result($q);
|
||||
if ($r->cnt) {
|
||||
throw new DBIPException("table {$tableName} is not empty");
|
||||
}
|
||||
return array($tableName, $fields);
|
||||
}
|
||||
|
||||
protected function finalizeImport() {
|
||||
}
|
||||
|
||||
protected function importRow($res, $row) {
|
||||
$vals = array();
|
||||
foreach ($row as $val) {
|
||||
$vals[] = "'" . mysqli_real_escape_string($this->db, $val) . "'";
|
||||
}
|
||||
if (!mysqli_query($this->db, "insert into {$this->dbQuoteChar}{$res[0]}{$this->dbQuoteChar} (" . implode(",", $res[1]) . ",addr_type) values (" . implode(",", $vals) . ")")) {
|
||||
throw new DBIPException("database error: cannot insert row");
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
protected function doLookup($tableName, $addrType, $addrStart) {
|
||||
$q = mysqli_query($this->db, "select * from {$this->dbQuoteChar}{$tableName}{$this->dbQuoteChar} where addr_type = '{$addrType}' and ip_start <= '" . mysqli_real_escape_string($this->db, $addrStart) . "' order by ip_start desc limit 1");
|
||||
$r = mysqli_fetch_object($q);
|
||||
mysqli_free_result($q);
|
||||
return $r;
|
||||
}
|
||||
|
||||
}
|
||||
96
dev/app-bak/Services/dbip/import.php
Executable file
96
dev/app-bak/Services/dbip/import.php
Executable file
|
|
@ -0,0 +1,96 @@
|
|||
#!/usr/bin/env php
|
||||
<?php
|
||||
|
||||
/**
|
||||
*
|
||||
* DB-IP.com database import script
|
||||
*
|
||||
* Copyright (C) 2018 db-ip.com
|
||||
*
|
||||
* This library is free software; you can redistribute it and/or
|
||||
* modify it under the terms of the GNU Lesser General Public
|
||||
* License as published by the Free Software Foundation; either
|
||||
* version 2.1 of the License, or (at your option) any later version.
|
||||
*
|
||||
* This library is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
||||
* Lesser General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU Lesser General Public
|
||||
* License along with this library; if not, write to the Free Software
|
||||
* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
|
||||
*
|
||||
*/
|
||||
|
||||
require "dbip.class.php";
|
||||
|
||||
$opts = getopt("f:d:t:b:u:p:");
|
||||
|
||||
$filename = @$opts["f"];
|
||||
$type = @$opts["d"];
|
||||
|
||||
$dbname = @$opts["b"]
|
||||
or $dbname = "mivita";
|
||||
|
||||
$table = @$opts["t"]
|
||||
or $table = "dbip_lookup_2"; //
|
||||
|
||||
$username = @$opts["u"]
|
||||
or $username = "kadmin";
|
||||
|
||||
$password = @$opts["p"]
|
||||
or $password = "KT32vQ7ix";
|
||||
|
||||
$host = "192.168.1.8";
|
||||
|
||||
//https://db-ip.com/db/download/ip-to-country-lite
|
||||
$filename = "dbip-country-lite-2024-07.csv";
|
||||
$table = "dbip_lookup";
|
||||
|
||||
//https://ipinfo.io/account/data-downloads
|
||||
$filename = "dbip-country-ipinfo-2024.csv";
|
||||
$table = "dbip_lookup_2";
|
||||
|
||||
if (!isset($type) && preg_match('/dbip-(country-lite|country-ipinfo|city-lite|country|location|isp|full)/i', $filename, $res)) {
|
||||
$type = $res[1];
|
||||
}
|
||||
|
||||
if (!isset($filename) || !isset($type)) {
|
||||
die("usage: {$argv[0]} -f <filename.csv[.gz]> [-d <country-lite|city-lite|country|location|isp|full>] [-b <database_name>] [-t <table_name>] [-u <username>] [-p <password>]\n");
|
||||
}
|
||||
|
||||
switch (strtolower($type)) {
|
||||
case "country-lite": $dbtype = DBIP::TYPE_COUNTRY_LITE; break;
|
||||
case "country-ipinfo": $dbtype = DBIP::TYPE_COUNTRY_IPINFO; break;
|
||||
case "city-lite": $dbtype = DBIP::TYPE_CITY_LITE; break;
|
||||
case "country": $dbtype = DBIP::TYPE_COUNTRY; break;
|
||||
case "location": $dbtype = DBIP::TYPE_LOCATION; break;
|
||||
case "isp": $dbtype = DBIP::TYPE_ISP; break;
|
||||
case "full": $dbtype = DBIP::TYPE_FULL; break;
|
||||
default: echo "invalid database type\n"; exit(1);
|
||||
}
|
||||
|
||||
try {
|
||||
// Connect to the database
|
||||
$db = new PDO("mysql:{$host}=localhost;dbname={$dbname};charset=utf8mb4", $username, $password);
|
||||
// Alternatively connect to MySQL using the old interface
|
||||
// Comment the PDO statement above and uncomment the mysql_ calls
|
||||
// below if your PHP installation doesn't support PDO :
|
||||
// $db = mysql_connect("localhost", $username, $password);
|
||||
// mysql_select_db($dbname, $db);
|
||||
|
||||
// Instanciate a new DBIP object with the database connection
|
||||
$dbip = new DBIP($db); //DBIPMySQLI
|
||||
// Alternatively instanciate a DBIP_MySQL object
|
||||
// Comment the new statement above and uncomment below if your PHP
|
||||
// installation doesn't support PDO :
|
||||
// $dbip = new DBIPMySQL($db);
|
||||
|
||||
$nrecs = $dbip->importFromCsv($filename, $dbtype, $table, function($progress) {
|
||||
echo "\r{$progress} ...";
|
||||
});
|
||||
echo "\rfinished importing " . number_format($nrecs) . " records\n";
|
||||
} catch (DBIPException $e) {
|
||||
echo "error: {$e->getMessage()}\n";
|
||||
}
|
||||
73
dev/app-bak/Services/dbip/lookup-example.php
Executable file
73
dev/app-bak/Services/dbip/lookup-example.php
Executable file
|
|
@ -0,0 +1,73 @@
|
|||
#!/usr/bin/env php
|
||||
<?php
|
||||
|
||||
/**
|
||||
*
|
||||
* DB-IP.com database sample query code
|
||||
*
|
||||
* Copyright (C) 2018 db-ip.com
|
||||
*
|
||||
* This library is free software; you can redistribute it and/or
|
||||
* modify it under the terms of the GNU Lesser General Public
|
||||
* License as published by the Free Software Foundation; either
|
||||
* version 2.1 of the License, or (at your option) any later version.
|
||||
*
|
||||
* This library is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
||||
* Lesser General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU Lesser General Public
|
||||
* License along with this library; if not, write to the Free Software
|
||||
* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
|
||||
*
|
||||
*/
|
||||
|
||||
// Include the DB-IP class
|
||||
require "dbip.class.php";
|
||||
|
||||
$host = "192.168.1.8";
|
||||
$dbname = "mivita";
|
||||
$username = "kadmin";
|
||||
$password = "KT32vQ7ix";
|
||||
|
||||
$table = "dbip_lookup";
|
||||
$table_2 = "dbip_lookup_2";
|
||||
|
||||
try {
|
||||
|
||||
// Check if we have a command line parameter
|
||||
if ($argc < 2) {
|
||||
die("usage: {$argv[0]} <ip_address>\n");
|
||||
}
|
||||
|
||||
// Connect to the database
|
||||
$db = new PDO("mysql:{$host}=localhost;dbname={$dbname};charset=utf8mb4", $username, $password);
|
||||
|
||||
// Alternatively connect to MySQL using the old interface
|
||||
// Comment the PDO statement above and uncomment the mysql_ calls
|
||||
// below if your PHP installation doesn't support PDO :
|
||||
// $db = mysql_connect("localhost", "root", "");
|
||||
// mysql_select_db("test", $db);
|
||||
|
||||
// Instanciate a new DBIP object with the database connection
|
||||
$dbip = new DBIP($db);
|
||||
|
||||
// Alternatively instanciate a DBIP_MySQL object
|
||||
// Comment the new statement above and uncomment below if your PHP
|
||||
// installation doesn't support PDO :
|
||||
// $dbip = new DBIPMySQL($db);
|
||||
|
||||
// Lookup an IP address
|
||||
$inf = $dbip->lookup($argv[1], $table);
|
||||
// Show the associated country
|
||||
echo "t:".$table." country = " . $inf->country . "\n";
|
||||
|
||||
$inf = $dbip->lookup($argv[1], $table_2);
|
||||
// Show the associated country
|
||||
echo "t:".$table_2." country = " . $inf->country . "\n";
|
||||
|
||||
} catch (DBIPException $e) {
|
||||
echo "error: {$e->getMessage()}\n";
|
||||
exit(1);
|
||||
}
|
||||
Loading…
Add table
Add a link
Reference in a new issue