diff --git a/.env b/.env index 022d44b..9146b9c 100644 --- a/.env +++ b/.env @@ -4,6 +4,8 @@ APP_KEY=base64:w0K6RjfleoAOpuICea14JnaZ28PNc6EMzIFMQZ3MVtU= APP_DEBUG=true APP_URL=https://partner.gruene-seele.test APP_DOMAIN=partner.gruene-seele.test +APP_PROMO_URL=https://www.testemich.jetzt/ +APP_PROMO_DOMAIN=testemich.jetzt/ APP_CHECKOUT_MAIL=register@adametz.media APP_CHECKOUT_TEST_MAIL=register@adametz.media diff --git a/app/Http/Controllers/AdminPromotionController.php b/app/Http/Controllers/AdminPromotionController.php new file mode 100755 index 0000000..ae5396a --- /dev/null +++ b/app/Http/Controllers/AdminPromotionController.php @@ -0,0 +1,189 @@ +middleware('admin'); + $this->promoRepo = $promoRepo; + + } + + public function index() + { + $data = [ + 'values' => PromotionAdmin::all(), + ]; + return view('admin.promotion.index', $data); + } + + public function detail($id){ + if($id == 0 || $id === 'new'){ + $promotion = new PromotionAdmin(); + $promotion->id = 0; + + $promotion->active = true; + }else{ + $promotion = PromotionAdmin::findOrFail($id); + } + + $data = [ + 'promotion' => $promotion, + + ]; + return view('admin.promotion.detail', $data); + } + + + public function store($id) + { + $data = Request::all(); + if(isset($data['action']) && $data['action'] === 'save-promotion_product'){ + $model = $this->promoRepo->updateProduct($id, Request::all()); + } + + if(isset($data['action']) && $data['action'] === 'save-promotion'){ + $rules = array( + 'name' => 'required', + 'type' => 'required', + ); + $validator = Validator::make(Request::all(), $rules); + if ($validator->fails()) { + return redirect(route('admin_promotion_detail', [$id]))->withErrors($validator)->withInput(Request::all()); + } + $model = $this->promoRepo->update($id, Request::all()); + } + + + \Session()->flash('alert-save', true); + return redirect(route('admin_promotion_detail', [$model->id])); + } + + public function delete($id, $del = false) + { + if($del === 'promotion_admin_product'){ + $PromotionAdminProduct = PromotionAdminProduct::findOrFail($id); + $PromotionAdmin = $PromotionAdminProduct->promotion_admin; + if($PromotionAdminProduct->canDelete()){ + \Session()->flash('alert-success', "Promotion Produkt gelöscht"); + $PromotionAdminProduct->delete(); + }else{ + \Session()->flash('alert-error', "Promotion Produkt kann nicht gelöscht werden, schon in Verwendung."); + } + return redirect(route('admin_promotion_detail', [$PromotionAdmin->id])); + } + + if($del === 'admin_promotion'){ + $PromotionAdmin = PromotionAdmin::findOrFail($id); + if($PromotionAdmin->canDelete()){ + foreach($PromotionAdmin->promotion_admin_products as $promotion_admin_product){ + $promotion_admin_product->delete(); + } + $PromotionAdmin->delete(); + \Session()->flash('alert-success', "Promotion gelöscht"); + }else{ + \Session()->flash('alert-error', "Promotion kann nicht gelöscht werden, schon in Verwendung."); + } + return redirect(route('admin_promotions')); + + } + + } + + public function show($by, $id = null){ + + $data = [ + 'id' => $id, + 'by' => $by, + ]; + + if($by === 'promotion'){ + $data['promotion'] = PromotionAdmin::findOrFail($id); + } + if($by === 'all'){ + $data['promotion'] = null; + + } + return view('admin.promotion.show', $data); + } + + public function datatable($by, $id = null){ + + $query = PromotionUser::with('promotion_user_products', 'user')->select('promotion_users.*'); + if($by === 'promotion'){ + // $query->where('promotion_admin_id', $id); + } + + return \DataTables::eloquent($query) + ->addColumn('id', function (PromotionUser $PromotionUser) { + return $PromotionUser->id; //''.$PromotionUser->id.''; + }) + ->addColumn('user', function (PromotionUser $PromotionUser) { + if($PromotionUser->user){ + return $PromotionUser->user->getFullName(); + } + return ""; + }) + ->addColumn('name', function (PromotionUser $PromotionUser) { + if(strlen($PromotionUser->name) > 30){ + return substr($PromotionUser->name, 0, 30)."..."; + } + return $PromotionUser->name; + }) + ->addColumn('products_active', function (PromotionUser $PromotionUser) { + return $PromotionUser->promotion_user_products_active->count(); + }) + ->addColumn('count_open_items', function (PromotionUser $PromotionUser) { + return $PromotionUser->getCountOpenItems(); + }) + ->addColumn('count_sell_items', function (PromotionUser $PromotionUser) { + return $PromotionUser->getCountSellItems(); + }) + ->addColumn('user_promotion_cart_price', function (PromotionUser $PromotionUser) { + $back = $PromotionUser->calculateCart(); + return formatNumber($back['price'])." €"; + }) + ->addColumn('user_promotion_sell_price', function (PromotionUser $PromotionUser) { + $back = $PromotionUser->calculateSell(); + return formatNumber($back['price'])." €"; + }) + ->addColumn('user_credit', function (PromotionUser $PromotionUser) { + return formatNumber($PromotionUser->user->payment_credit)." €";; + }) + ->addColumn('active', function (PromotionUser $PromotionUser) { + return get_active_badge($PromotionUser->active); + }) + ->addColumn('pick_up', function (PromotionUser $PromotionUser) { + return get_active_badge($PromotionUser->pick_up); + }) + ->addColumn('user_delete', function (PromotionUser $PromotionUser) { + return get_active_badge(($PromotionUser->user_deleted_at != null)); + }) + + + + ->orderColumn('id', 'id $1') + ->orderColumn('name', 'name $1') + //->orderColumn('status', 'status $1') + ->orderColumn('active', 'active $1') + ->orderColumn('pick_up', 'pick_up $1') + // ->orderColumn('user_delete', 'user_delete $1') + + + ->rawColumns(['id', 'status', 'active', 'pick_up', 'user_delete']) + ->make(true); + } +} \ No newline at end of file diff --git a/app/Http/Controllers/LeadController.php b/app/Http/Controllers/LeadController.php index 6bd6507..b3a24e7 100755 --- a/app/Http/Controllers/LeadController.php +++ b/app/Http/Controllers/LeadController.php @@ -97,7 +97,7 @@ class LeadController extends Controller $user->account = new UserAccount(); } } - $next_account_id = UserAccount::max('m_account') +1; + $next_account_id = UserAccount::withTrashed()->max('m_account') +1; if($user->account->m_account === null){ $user->account->m_account = $next_account_id; } @@ -122,7 +122,7 @@ class LeadController extends Controller $data = Request::all(); $show = Request::get('show'); - + dd($data); if ($data['user_id'] === "new" || $data['user_id'] == 0) { $rules = array( 'salutation' => 'required', @@ -237,7 +237,7 @@ class LeadController extends Controller } if(!$user->account->m_account){ - $user->account->m_account = UserAccount::max('m_account') +1; + $user->account->m_account = UserAccount::withTrashed()->max('m_account') +1; $user->account->save(); } diff --git a/app/Http/Controllers/ModalController.php b/app/Http/Controllers/ModalController.php index a7e849c..af79c8b 100644 --- a/app/Http/Controllers/ModalController.php +++ b/app/Http/Controllers/ModalController.php @@ -5,6 +5,7 @@ namespace App\Http\Controllers; use App\Models\Homeparty; use App\Models\HomepartyUser; use App\Models\Product; +use App\Models\PromotionAdminProduct; use App\Models\ShoppingOrder; use App\Models\ShoppingUser; use App\Models\UserCredit; @@ -82,17 +83,18 @@ class ModalController extends Controller $ret = view("admin.modal.user-credit-status", compact('value', 'data'))->render(); } - - - /*if($data['action'] === 'homeparty-add-product') { - $homeparty = Homeparty::find($data['id']); - $homeparty_user = HomepartyUser::find($data['user_id']); - $data['homeparty'] = $homeparty; - $ret = view("user.homeparty.modal_show_products", compact( 'data', 'homeparty', 'homeparty_user'))->render(); - }*/ - - + if($data['action'] === 'save-promotion_product'){ + if($data['id'] === 'new'){ + $value = new PromotionAdminProduct(); + $value->calcu_commission = true; + $value->shipping = true; + $value->active = true; + }else{ + $value = PromotionAdminProduct::find($data['id']); + } + $ret = view("admin.modal.promotion-product", compact('value', 'data'))->render(); + } } return response()->json(['response' => $data, 'html'=>$ret, 'status'=>$status]); } diff --git a/app/Http/Controllers/SalesController.php b/app/Http/Controllers/SalesController.php index ee9c7e2..d92a6f1 100755 --- a/app/Http/Controllers/SalesController.php +++ b/app/Http/Controllers/SalesController.php @@ -2,16 +2,17 @@ namespace App\Http\Controllers; -use App\Models\PaymentTransaction; -use App\Models\Setting; -use App\Models\ShoppingOrder; -use App\Models\ShoppingPayment; -use App\Models\ShoppingUser; -use App\Models\UserShop; -use App\Repositories\InvoiceRepository; -use App\Services\CustomerPriority; -use App\Services\Payment; use Request; +use App\Models\Setting; +use App\Models\UserShop; +use App\Services\Payment; +use App\Models\ShoppingUser; +use App\Models\ShoppingOrder; +use App\Models\UserPayCredit; +use App\Models\ShoppingPayment; +use App\Models\PaymentTransaction; +use App\Services\CustomerPriority; +use App\Repositories\InvoiceRepository; class SalesController extends Controller { @@ -307,6 +308,19 @@ class SalesController extends Controller $shopping_order = ShoppingOrder::findOrFail($data['id']); $shopping_payment = ShoppingPayment::findOrFail($data['payment_id']); + if($shopping_order->shopping_order_margin->from_payment_credit > 0){ + $last_UserPayCredit = UserPayCredit::where('shopping_order_id', $shopping_order->id)->whereIn('status', [2, 4])->orderBy('id', 'DESC')->first(); + //Status Keine Zahlung, Guthaben zurückführen, wenn status 2 / deduction from payment + if($data['txaction'] === 'non' && $last_UserPayCredit->status === 2){ + Payment::handelUserPayCredits($shopping_order, 'return'); + } + //Status Zahlung, voher gab es eine Storno, Guthaben abziehen wenn status 4 / return from order + if($last_UserPayCredit->status === 4 && ($data['txaction'] === 'open' || $data['txaction'] === 'paid')){ + Payment::handelUserPayCredits($shopping_order, 'deduction'); + } + + + } $payt = PaymentTransaction::create([ 'shopping_payment_id' => $shopping_payment->id, 'request' => 'transaction', @@ -327,6 +341,7 @@ class SalesController extends Controller if($payt->status === 'vor' && $payt->txaction === 'paid'){ $send_link = Payment::paymentStatusPaidAction($shopping_order, true); } + $edata = [ 'mode' => $payt->mode, 'txaction' => $payt->txaction, diff --git a/app/Http/Controllers/User/CheckoutController.php b/app/Http/Controllers/User/CheckoutController.php index 1422fff..399f6e6 100755 --- a/app/Http/Controllers/User/CheckoutController.php +++ b/app/Http/Controllers/User/CheckoutController.php @@ -555,6 +555,8 @@ class CheckoutController extends Controller if($shopping_payment){ + Payment::handelUserPayCredits($shopping_order, 'deduction'); + if($payt->status === 'vor'){ $shopping_payment->txaction = 'open'; $shopping_order->txaction = 'open'; diff --git a/app/Http/Controllers/User/OrderController.php b/app/Http/Controllers/User/OrderController.php index 216ebe9..e244fbe 100755 --- a/app/Http/Controllers/User/OrderController.php +++ b/app/Http/Controllers/User/OrderController.php @@ -367,10 +367,10 @@ class OrderController extends Controller return ""; }) ->addColumn('price_net', function (Product $product) { - return $product->getFormattedPriceWith(true, true). "€"; + return $product->getFormattedPriceWith(true, false). "€"; }) ->addColumn('price_gross', function (Product $product) { - return $product->getFormattedPriceWith(false, true). "€"; + return $product->getFormattedPriceWith(false, false). "€"; }) ->addColumn('price_vk_gross', function (Product $product) { return $product->getFormattedPriceWith(false, false). "€"; diff --git a/app/Http/Controllers/User/PromotionController.php b/app/Http/Controllers/User/PromotionController.php new file mode 100644 index 0000000..6bc64ea --- /dev/null +++ b/app/Http/Controllers/User/PromotionController.php @@ -0,0 +1,147 @@ +middleware('active.account'); + $this->promoRepo = $promoRepo; + + } + + public function index() + { + $data = [ + 'values' => PromotionUser::where('user_id', Auth::user()->id)->whereNull('user_deleted_at')->get(), + ]; + return view('user.promotion.index', $data); + } + + public function detail($id){ + + + $user_promotion = PromotionUser::findOrFail($id); + if($user_promotion->user_id != Auth::user()->id){ + abort(404); + } + $data = [ + 'checkPaymentCredit' => $user_promotion->checkPaymentCredit(), + 'user_promotion_cart' => PromotionUser::preCalculateCart($user_promotion, 'user_promotion'), + 'user_promotion' => $user_promotion, + ]; + return view('user.promotion.detail', $data); + } + + public function store($id) + { + $data = Request::all(); + + if(isset($data['action']) && $data['action'] === 'new-user-promotion'){ + $model = $this->promoRepo->create(Request::all()); + \Session()->flash('alert-save', true); + } + + if(isset($data['action']) && $data['action'] === 'save-user-promotion'){ + $rules = array( + 'name' => 'required', + 'user_promotion_url' => ' required|alpha_dash|profanity|unique:promotion_users,url,'.\Auth::user()->id.'|min:4|max:20', + ); + $validator = Validator::make(Request::all(), $rules); + if ($validator->fails()) { + return redirect(route('user_promotion_detail', [$id]))->withErrors($validator)->withInput(Request::all()); + } + $model = $this->promoRepo->update($id, Request::all()); + + } + \Session()->flash('alert-save', true); + return redirect(route('user_promotion_detail', [$model->id])); + } + + public function delete($id, $del = false) + { + + if($del === 'user_promotion'){ + $PromotionUser = PromotionUser::findOrFail($id); + if($PromotionUser->canDelete()){ + $PromotionUser->user_deleted_at = now(); + $PromotionUser->save(); + \Session()->flash('alert-success', "Promotion gelöscht"); + }else{ + \Session()->flash('alert-error', "Promotion kann nicht gelöscht werden, schon in Verwendung."); + } + return redirect(route('user_promotions')); + + } + } + + public function load(){ + $data = Request::all(); + + if(Request::ajax()) { + if(isset($data['action']) && $data['action'] === 'validate_url'){ + $rules = array( + //'user_promotion_url' => ' required|alpha_dash|profanity|unique:user_shops,name|min:4|max:20|full_word_check', + 'user_promotion_url' => ' required|alpha_dash|profanity|unique:promotion_users,url,'.\Auth::user()->id.'|min:4|max:20', + ); + /*Validator::extend('full_word_check', function ($attribute, $value, $parameters, $validator) { + if(in_array($value, config('profanity.full_word_check'))){ + return false; + } + return true; + });*/ + $validator = Validator::make(Request::all(), $rules); + + if ($validator->fails()) { + //$messages = $validator->messages(); + return Response::json(array( + 'success' => false, + 'errors' => $validator->getMessageBag()->toArray() + + )); + } + //$slug = SlugService::createSlug(UserShop::class, 'slug', Request::get('user_promotion_url')); + $name = Util::sanitize(Request::get('user_promotion_url'), true, false, true, true); + + return Response::json(array( + 'success' => true, + 'preview_user_promotion_url' => config('app.promo_url').$name, + )); + } + if(isset($data['action']) && $data['action'] === 'updateCart'){ + + $fill = [ + 'user_promotion_cart' => ['price' => 0, 'price_net' => 0], + ]; + + if(isset($data['products'])){ + $fill['user_promotion_cart'] = PromotionUser::preCalculateCart($data['products'], 'products'); + $fill['checkPaymentCredit'] = PromotionUser::preCheckPaymentCredit($fill['user_promotion_cart']); + + } + /*if(isset($data['user_promotion_id']) && $user_promotion = PromotionUser::find($data['user_promotion_id'])){ + }*/ + $html_cart = view("user.promotion.cart", $fill)->render(); + return response()->json(['response' => true, 'data'=>$data, 'html_cart'=>$html_cart]); + } + return response()->json(['success' => false, 'data'=>$data]); + } + } + + + +} \ No newline at end of file diff --git a/app/Http/Controllers/WizardController.php b/app/Http/Controllers/WizardController.php index 0c7989a..2bbcefe 100755 --- a/app/Http/Controllers/WizardController.php +++ b/app/Http/Controllers/WizardController.php @@ -221,6 +221,10 @@ class WizardController extends Controller } $data = Request::all(); $data['same_as_billing'] = Request::get('same_as_billing') == NULL ? 0 : 1; + $data['birthday_day'] = isset($data['birthday_day']) ? $data['birthday_day'] : 1; + $data['birthday_month'] = isset($data['birthday_month']) ? $data['birthday_month'] : 1; + $data['birthday_year'] = isset($data['birthday_year']) ? $data['birthday_year'] : 1970; + $data['birthday'] = $data['birthday_day'].".".$data['birthday_month'].".".$data['birthday_year']; $user->account->fill($data)->save(); $user->wizard = 2; $user->save(); diff --git a/app/Models/Product.php b/app/Models/Product.php index 01fb1f0..0c38c87 100644 --- a/app/Models/Product.php +++ b/app/Models/Product.php @@ -117,6 +117,13 @@ use Illuminate\Database\Eloquent\SoftDeletes; * @method static \Illuminate\Database\Eloquent\Builder|Product wherePartnerCommission($value) * @method static \Illuminate\Database\Eloquent\Builder|Product whereSingleCommission($value) * @method static \Illuminate\Database\Eloquent\Builder|Product whereValueCommission($value) + * @property bool|null $shipping_addon + * @property bool|null $max_buy + * @property int|null $max_buy_num + * @property-read \Illuminate\Database\Eloquent\Collection|\App\Models\ProductBuy[] $product_buys + * @property-read int|null $product_buys_count + * @method static \Illuminate\Database\Eloquent\Builder|Product whereMaxBuy($value) + * @method static \Illuminate\Database\Eloquent\Builder|Product whereMaxBuyNum($value) */ class Product extends Model { @@ -340,10 +347,13 @@ class Product extends Model /*price by user Factor*/ private function calcPriceUserFactor($price){ + /* + Nicht in benutzung, die margin errechnet sich im Warenkorb, wegen der Staffelprovision if(\Auth::user() && \Auth::user()->user_level){ $margin = ((\Auth::user()->user_level->margin -100)*-1) / 100; $price = $price * $margin; } + */ return $price; } /*price net*/ diff --git a/app/Models/PromotionAdmin.php b/app/Models/PromotionAdmin.php new file mode 100644 index 0000000..eba953b --- /dev/null +++ b/app/Models/PromotionAdmin.php @@ -0,0 +1,181 @@ + 'float', + 'max_items' => 'int', + 'active' => 'bool', + 'type' => 'int', + 'shop' => 'bool', + + + ]; + + protected $dates = [ + 'from', + 'to' + ]; + + protected $fillable = [ + 'type', + 'name', + 'description', + 'from', + 'to', + 'shop', + 'max_bugdet', + 'max_items', + 'active' + ]; + + public $promotionType = [ + 1 => 'verschenken', + 2 => 'Nachlass (not built in!)', + 3 => 'Gewinnspiel (not built in!)', + ]; + + public function products() + { + return $this->belongsToMany(Product::class, 'promotion_admin_products') + ->withPivot('id', 'own_price', 'price', 'tax', 'price_old', 'calcu_commission', 'max_items', 'used_items', 'shipping', 'active') + ->withTimestamps(); + } + + + public function promotion_admin_products() + { + return $this->hasMany(PromotionAdminProduct::class); + } + + public function promotion_admin_products_active() + { + return $this->hasMany(PromotionAdminProduct::class)->where('active', 1); + } + + public function promotion_user_products() + { + return $this->hasMany(PromotionUserProduct::class); + } + + public function promotion_users() + { + return $this->hasMany(PromotionUser::class); + } + + public function getPromotionType(){ + if(isset($this->promotionType[$this->type])){ + return $this->promotionType[$this->type]; + } + } + + public function getFromAttribute($value) + { + if(!$value){ return ""; } + return Carbon::parse($value)->format(\Util::formatDateDB()); + } + + public function getFromRaw(){ + return isset($this->attributes['from']) ? $this->attributes['from'] : NULL; + } + + public function setFromAttribute( $value ) { + $this->attributes['from'] = isset($value) ? (new Carbon($value))->format('Y-m-d') : NULL; + } + + public function getToAttribute($value) + { + if(!$value){ return ""; } + return Carbon::parse($value)->format(\Util::formatDateDB()); + } + + public function getToRaw(){ + return isset($this->attributes['to']) ? $this->attributes['to'] : NULL; + } + + public function setToAttribute( $value ) { + $this->attributes['to'] = isset($value) ? (new Carbon($value))->format('Y-m-d') : NULL; + } + + + public function setMaxBugdetAttribute( $value ) { + + $this->attributes['max_bugdet'] = $value ? Util::reFormatNumber($value) : null; + } + + public function getFormattedMaxBugdet() + { + return isset($this->attributes['max_bugdet']) ? Util::formatNumber($this->attributes['max_bugdet']) : ""; + } + + + public function canDelete(){ + + if($this->promotion_users->count() === 0 && $this->promotion_user_products->count() === 0){ + return true; + } + return false; + } + + + public static function getActiveAdminPromotionsAsArray(){ + $query = PromotionAdmin::where('active', true) + ->where(function ($query) { + $query->where('from', '<', Carbon::now()) + ->orWhereNull('from'); + }) + ->where(function ($query) { + $query->where('to', '>=', Carbon::now()) + ->orWhereNull('to'); + }); + return $query->pluck('name', 'id')->toArray(); + } +} diff --git a/app/Models/PromotionAdminProduct.php b/app/Models/PromotionAdminProduct.php new file mode 100644 index 0000000..d8f4108 --- /dev/null +++ b/app/Models/PromotionAdminProduct.php @@ -0,0 +1,194 @@ + 'int', + 'product_id' => 'int', + 'own_price' => 'bool', + 'price' => 'float', + 'tax' => 'float', + 'price_old' => 'float', + 'calcu_commission' => 'bool', + 'max_items' => 'int', + 'used_items' => 'int', + 'shipping' => 'bool', + 'active' => 'bool' + ]; + + protected $fillable = [ + 'promotion_admin_id', + 'product_id', + 'own_price', + 'price', + 'tax', + 'price_old', + 'calcu_commission', + 'max_items', + 'used_items', + 'shipping', + 'active' + ]; + + public function product() + { + return $this->belongsTo(Product::class); + } + + public function promotion_admin() + { + return $this->belongsTo(PromotionAdmin::class); + } + + public function promotion_user_products() + { + return $this->hasMany(PromotionUserProduct::class); + } + + public function setPriceAttribute( $value ) { + + $this->attributes['price'] = $value ? Util::reFormatNumber($value) : null; + } + + public function getFormattedPrice() + { + return isset($this->attributes['price']) ? Util::formatNumber($this->attributes['price']) : ""; + } + + public function getRealPrice() + { + if($this->own_price && $this->price){ + return $this->price; + } + if($this->product && $this->product->price){ + return $this->product->price; + } + return 0; + } + + public function getFormattedRealPrice() + { + return Util::formatNumber($this->getRealPrice()); + } + + /*price calcu Marign single_commission Factor*/ + private function calcPriceCommissionFactor($price){ + //einzelrabatt aus produkt + $margin = 100; + if(isset($this->product) && $this->product->single_commission){ + $margin = $this->product->value_commission; + }else{ + //rabatt aus user level + $user = Auth::user(); + if($user && $user->user_level && $user->user_level->user_level_margins){ + if($user_level_margin = $user->user_level->user_level_margins_re->first()){ + $margin = $user_level_margin->trading_margin; + } + } + } + $margin = (100 - $margin) / 100; + $price = $price * $margin; + return $price; + } + /*price net*/ + private function calcPriceNet($price){ + $tax = isset($this->product->tax) ? $this->product->tax : 0; + $tax_rate = ($tax + 100) / 100; + return $price / $tax_rate; + } + //price calu with + public function getPriceWith(Bool $net = true){ + $price = $this->getRealPrice(); + $price = $net ? $this->calcPriceNet($price) : $price; + $price = $this->calcu_commission ? $this->calcPriceCommissionFactor($price) : $price; + return round($price, 2); + } + /*out*/ + public function getFormattedPriceWith(Bool $net = true) + { + return Util::formatNumber($this->getPriceWith($net)); + } + + public function canDelete(){ + if($this->promotion_user_products->count() === 0){ + return true; + } + return false; + + } + + public function getPromotionUserProducts($user_promotion, $key = false) + { + $user_promotion_product = $user_promotion->hasPromotionUserProducts($this->id); + if($user_promotion_product){ + if(!$key){ + return $user_promotion_product; + } + if(isset($user_promotion_product->{$key})){ + return $user_promotion_product->{$key}; + }else{ + return 0; + } + } + return 0; + //return $this->hasMany(PromotionUserProduct::class)->where('promotion_admin_product_id', $promotion_admin_product->id)->first(); + } + + + +} diff --git a/app/Models/PromotionUser.php b/app/Models/PromotionUser.php new file mode 100644 index 0000000..7657fc5 --- /dev/null +++ b/app/Models/PromotionUser.php @@ -0,0 +1,222 @@ + 'int', + 'user_id' => 'int', + 'pick_up' => 'bool', + 'used_budget_total' => 'float', + 'sell_items_total' => 'int', + 'active' => 'bool' + ]; + + protected $dates = [ + 'user_deleted_at' + ]; + + protected $fillable = [ + 'promotion_admin_id', + 'user_id', + 'name', + 'description', + 'url', + 'pick_up', + 'used_budget_total', + 'sell_items_total', + 'active', + 'user_deleted_at' + ]; + + public function promotion_admin() + { + return $this->belongsTo(PromotionAdmin::class); + } + + public function user() + { + return $this->belongsTo(\App\User::class); + } + + public function products() + { + return $this->belongsToMany(Product::class, 'promotion_user_products') + ->withPivot('id', 'promotion_admin_id', 'promotion_admin_product_id', 'open_items', 'sell_items', 'used_budget_total', 'active') + ->withTimestamps(); + } + + public function promotion_user_products() + { + return $this->hasMany(PromotionUserProduct::class); + } + + public function promotion_user_products_active() + { + return $this->hasMany(PromotionUserProduct::class)->where('active', 1); + } + + + public function getUrlPreview() + { + return $this->url ? config('app.promo_url').$this->url : ""; + } + + public function canDelete(){ + return true; + } + + public function hasPromotionUserProducts($promotion_admin_product_id) + { + return $this->hasMany(PromotionUserProduct::class)->where('promotion_admin_product_id', $promotion_admin_product_id)->first(); + } + public function calculateSell(){ + $price = 0; + $price_net = 0; + //used_budget_total + //von den user produkte, inkl. der nicht aktiven! + //ToDo der Preis vom verkauf muss eingesetzt werden, wird gespeichert beim Sale + if($this->promotion_user_products){ + foreach($this->promotion_user_products as $promotion_user_product){ + $qty = $promotion_user_product->sell_items; + $price += $promotion_user_product->promotion_admin_product->getPriceWith(false) * intval($qty); + $price_net += $promotion_user_product->promotion_admin_product->getPriceWith(true) * intval($qty); + + } + } + return ['price' => $price, 'price_net' => $price_net]; + } + + public function calculateCart(){ + $price = 0; + $price_net = 0; + if(isset($this->promotion_admin->promotion_admin_products_active)){ + foreach($this->promotion_admin->promotion_admin_products_active as $promotion_admin_product){ + if($promotion_user_product = $this->hasPromotionUserProducts($promotion_admin_product->id)){ + if($promotion_user_product->active){ + $qty = $promotion_user_product->open_items; + $price += $promotion_admin_product->getPriceWith(false) * intval($qty); + $price_net += $promotion_admin_product->getPriceWith(true) * intval($qty); + } + } + } + } + return ['price' => $price, 'price_net' => $price_net]; + } + + public function getCountOpenItems(){ + //hier die aktiven + return $this->promotion_user_products_active->sum('open_items'); + } + + public function getCountSellItems(){ + //hier alle zusammenziehen + return $this->promotion_user_products->sum('sell_items'); + } + + public function checkPaymentCredit() + { + if($this->promotion_user_products_active->count() > 0 && $this->getCountOpenItems() > 0){ + $payment_credit = \Auth::user()->payment_credit; + if($payment_credit <= 0){ + return "empty"; + } + + $prices = $this->calculateCart(); + if(isset($prices['price']) && $prices['price'] > 0){ + if($payment_credit >= $prices['price']){ + return "okay"; + } + } + return 'not'; + } + return false; + } + public static function preCheckPaymentCredit($values){ + if($values['count_items'] > 0 && $values['sum_items'] > 0){ + $payment_credit = \Auth::user()->payment_credit; + if($payment_credit <= 0){ + return "empty"; + } + if(isset($values['price']) && $values['price'] > 0){ + if($payment_credit >= $values['price']){ + return "okay"; + } + } + return 'not'; + } + return false; + } + + + public static function preCalculateCart($value, $by = ''){ + $price = 0; + $price_net = 0; + $count_items = 0; + $sum_items = 0; + if($by === 'products'){ + foreach($value as $product){ + if(isset($product['product_id']) && isset($product['qty'])){ + if($promotion_admin_product = PromotionAdminProduct::find($product['product_id'])){ + $count_items ++; + $sum_items += intval($product['qty']); + $price += $promotion_admin_product->getPriceWith(false) * intval($product['qty']); + $price_net += $promotion_admin_product->getPriceWith(true) * intval($product['qty']); + } + } + } + } + if($by === 'user_promotion'){ + return $value->calculateCart(); + } + return ['price' => $price, 'price_net' => $price_net, 'count_items' => $count_items, 'sum_items' => $sum_items]; + + } +} diff --git a/app/Models/PromotionUserProduct.php b/app/Models/PromotionUserProduct.php new file mode 100644 index 0000000..2ca44b3 --- /dev/null +++ b/app/Models/PromotionUserProduct.php @@ -0,0 +1,92 @@ + 'int', + 'promotion_user_id' => 'int', + 'promotion_admin_product_id' => 'int', + 'product_id' => 'int', + 'open_items' => 'int', + 'sell_items' => 'int', + 'used_budget_total' => 'float', + 'active' => 'bool' + ]; + + protected $fillable = [ + 'promotion_admin_id', + 'promotion_user_id', + 'promotion_admin_product_id', + 'product_id', + 'open_items', + 'sell_items', + 'used_budget_total', + 'active' + ]; + + public function product() + { + return $this->belongsTo(Product::class); + } + + public function promotion_admin() + { + return $this->belongsTo(PromotionAdmin::class); + } + + public function promotion_admin_product() + { + return $this->belongsTo(PromotionAdminProduct::class); + } + + public function promotion_user() + { + return $this->belongsTo(PromotionUser::class); + } +} diff --git a/app/Models/UserPayCredit.php b/app/Models/UserPayCredit.php index 8b3467e..7e1c5b9 100644 --- a/app/Models/UserPayCredit.php +++ b/app/Models/UserPayCredit.php @@ -47,6 +47,7 @@ class UserPayCredit extends Model 1 => 'add from payment', 2 => 'deduction from payment', 3 => 'manually added credit', + 4 => 'return from order', ]; protected $table = 'user_pay_credits'; diff --git a/app/Repositories/AdminPromotionRepository.php b/app/Repositories/AdminPromotionRepository.php new file mode 100644 index 0000000..b57670a --- /dev/null +++ b/app/Repositories/AdminPromotionRepository.php @@ -0,0 +1,62 @@ +model = $model; + } + + public function update($id, $data) + { + + $data['active'] = isset($data['active']) ? 1 : 0; + $data['shop'] = isset($data['shop']) ? 1 : 0; + + if($id == 0 || $id === 'new'){ + $this->model = PromotionAdmin::create($data); + } + else{ + $this->model = $this->getById($id); + $this->model->fill($data); + $this->model->save(); + } + + return $this->model; + } + public function updateProduct($id, $data){ + $this->model = $this->getById($id); + + $data['own_price'] = isset($data['own_price']) ? 1 : 0; + $data['calcu_commission'] = isset($data['calcu_commission']) ? 1 : 0; + $data['shipping'] = isset($data['shipping']) ? 1 : 0; + $data['active'] = isset($data['active']) ? 1 : 0; + + if($data['id'] === 'new'){ + $data['promotion_admin_id'] = $this->model->id; + $product = PromotionAdminProduct::create($data); + } + else{ + $product = PromotionAdminProduct::findOrFail($data['id']); + $product->fill($data); + $product->save(); + } + + + + return $this->model; + } + + public function create($data){ + + return true; + } + + +} \ No newline at end of file diff --git a/app/Repositories/UserPromotionRepository.php b/app/Repositories/UserPromotionRepository.php new file mode 100644 index 0000000..3c66545 --- /dev/null +++ b/app/Repositories/UserPromotionRepository.php @@ -0,0 +1,81 @@ +model = $model; + } + + public function update($id, $data) + { + + $data['active'] = isset($data['active']) ? 1 : 0; + $data['pick_up'] = isset($data['pick_up']) ? 1 : 0; + $data['url'] = Util::sanitize($data['user_promotion_url'], true, false, true, true); + + $this->model = $this->getById($id); + $this->model->fill($data); + $this->model->save(); + + $this->updateProducts($id, $data); + return $this->model; + } + + public function updateProducts($id, $data){ + + $this->model = $this->getById($id); + if(isset($data['products_qty'])){ + foreach($data['products_qty'] as $pa_id => $qty){ + $PromotionAdminProduct = PromotionAdminProduct::findOrFail($pa_id); + $PromotionUserProduct = $PromotionAdminProduct->getPromotionUserProducts($this->model); + + if(isset($data['products_user'][$pa_id]) && $data['products_user'][$pa_id] > 0 && $PromotionUserProduct){ + $PromotionUserProduct->fill([ + 'open_items' => intval($qty), + 'active' => isset($data['products_active'][$pa_id]) ? 1 : 0, + ]); + $PromotionUserProduct->save(); + }else{ + $user_product = PromotionUserProduct::create([ + 'promotion_admin_id' => $PromotionAdminProduct->promotion_admin_id, + 'promotion_user_id' => $this->model->id, + 'promotion_admin_product_id' => $PromotionAdminProduct->id, + 'product_id' => $PromotionAdminProduct->product_id, + 'open_items' => intval($qty), + 'active' => isset($data['products_active'][$pa_id]) ? 1 : 0, + + ]); + } + } + } + + return $this->model; + } + + public function create($data){ + + if(isset($data['promotion_admin_id'])){ + $PromotionAdmin = PromotionAdmin::findOrFail($data['promotion_admin_id']); + $this->model = PromotionUser::create([ + 'promotion_admin_id' => $PromotionAdmin->id, + 'user_id' => Auth::user()->id, + ]); + return $this->model; + } + return false; + + } + + +} \ No newline at end of file diff --git a/app/Services/Payment.php b/app/Services/Payment.php index 1a240e7..58e8521 100644 --- a/app/Services/Payment.php +++ b/app/Services/Payment.php @@ -197,22 +197,35 @@ class Payment } } + + //if the order has action + if($shopping_order->shopping_user->is_from === 'user_order'){ + //is margin -> set paid + $shopping_order->shopping_order_margin->paid = true; + $shopping_order->shopping_order_margin->save(); + } + } - //if the order has action - if($shopping_order->shopping_user->is_from === 'user_order'){ - //is margin -> set paid - $shopping_order->shopping_order_margin->paid = true; - $shopping_order->shopping_order_margin->save(); - //is payment credit, reduce + return $send_link; + } + + //remove form credit, every sale fnc / vor / etc from CheckoutController + //when stone, put it back SalesController + public static function handelUserPayCredits(ShoppingOrder $shopping_order, $do){ + //is payment credit, reduce Sae + if($do === 'deduction'){ if($shopping_order->shopping_order_margin->from_payment_credit > 0){ $credit = $shopping_order->shopping_order_margin->from_payment_credit * -1; self::addUserPayCredits($shopping_order->auth_user, $credit, 2, 'user_order_deduction', $shopping_order->id); } - } - - - return $send_link; + if($do === 'return'){ + if($shopping_order->shopping_order_margin->from_payment_credit > 0){ + $credit = $shopping_order->shopping_order_margin->from_payment_credit; + self::addUserPayCredits($shopping_order->auth_user, $credit, 4, 'user_order_return', $shopping_order->id); + } + } + } public static function paymentStatusSendMail(ShoppingOrder $shopping_order, $shopping_payment, $data){ diff --git a/app/Services/Util.php b/app/Services/Util.php index 28c8f08..0ee3bb9 100644 --- a/app/Services/Util.php +++ b/app/Services/Util.php @@ -66,6 +66,10 @@ class Util return number_format($value, $dec, ',', '.'); } + public static function formatPlural($count, $singular, $plural){ + return ($count === 1) ? $singular : $singular.$plural; + } + public static function utf8ize( $mixed ) { if (is_array($mixed)) { foreach ($mixed as $key => $value) { @@ -218,15 +222,27 @@ class Util } return url($uri); } - public static function sanitize($string, $force_lowercase = true, $anal = false, $substr = false) + public static function sanitize($string, $force_lowercase = true, $anal = false, $substr = false, $anCon = false) { - $strip = array("~", "`", "!", "@", "#", "$", "%", "^", "&", "*", "(", ")", "_", "=", "+", "[", "{", "]", + $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 ; + $clean = ($anal) ? preg_replace("/[^a-zA-Z0-9]/", "", $clean) : $clean; + if($anCon){ + $ers = array( + 'Ä' => 'Ae', + 'Ö' => 'Oe', + 'Ü' => 'Ue', + 'ä' => 'ae', + 'ö' => 'oe', + 'ü' => 'ue', + 'ß' => 'ss' + ); + $clean = strtr($clean,$ers); + } if($substr){ $clean = (strlen($clean) > 20) ? substr($clean,-20) : $clean; diff --git a/app/helpers.php b/app/helpers.php index 3c56239..b1dc23e 100644 --- a/app/helpers.php +++ b/app/helpers.php @@ -75,4 +75,11 @@ if (! function_exists('reFormatNumber')) { } } +if (! function_exists('formatPlural')) { + function formatPlural($count, $singular, $plural) + { + return Util::formatPlural($count, $singular, $plural); + } +} + diff --git a/config/app.php b/config/app.php index d079810..f1a6c9f 100644 --- a/config/app.php +++ b/config/app.php @@ -55,6 +55,11 @@ return [ 'url' => env('APP_URL', 'https://partner.gruene-seele.bio'), 'domain' => env('APP_DOMAIN', 'partner.gruene-seele.bio'), + + 'promo_url' => env('APP_PROMO_URL', 'https://www.testemich.jetzt/'), + 'promo_domain' => env('APP_PROMO_DOMAIN', 'testemich.jetzt/'), + + 'checkout_mail' => env('APP_CHECKOUT_MAIL', 'kevin.adametz@me.com'), 'checkout_test_mail' => env('APP_CHECKOUT_TEST_MAIL', 'kevin.adametz@me.com'), 'info_mail' => env('APP_INFO_MAIL', 'kevin.adametz@me.com'), diff --git a/database/migrations/2021_10_11_135225_create_promotion_admins_table.php b/database/migrations/2021_10_11_135225_create_promotion_admins_table.php new file mode 100644 index 0000000..f41ad72 --- /dev/null +++ b/database/migrations/2021_10_11_135225_create_promotion_admins_table.php @@ -0,0 +1,47 @@ +increments('id'); + + $table->unsignedTinyInteger('type')->default(1); + + $table->string('name', 255); + $table->text('description')->nullable(); + + $table->date('from')->nullable(); + $table->date('to')->nullable(); + + $table->decimal('max_bugdet', 13, 2)->nullable(); + $table->unsignedSmallInteger('max_items')->nullable(); + + $table->boolean('shop')->default(false); + + $table->boolean('active')->default(false); + + $table->timestamps(); + }); + } + + /** + * Reverse the migrations. + * + * @return void + */ + public function down() + { + Schema::dropIfExists('promotion_admins'); + } +} diff --git a/database/migrations/2021_10_11_135229_create_promotion_admin_products_table.php b/database/migrations/2021_10_11_135229_create_promotion_admin_products_table.php new file mode 100644 index 0000000..f9f59d9 --- /dev/null +++ b/database/migrations/2021_10_11_135229_create_promotion_admin_products_table.php @@ -0,0 +1,57 @@ +increments('id'); + $table->unsignedInteger('promotion_admin_id')->index(); + $table->unsignedInteger('product_id')->index(); + + $table->boolean('own_price')->default(false); + $table->decimal('price', 8, 2)->nullable(); + $table->decimal('tax', 5, 2)->nullable(); + $table->decimal('price_old', 8, 2)->nullable(); //streichpreis + + $table->boolean('calcu_commission')->default(true); + + $table->unsignedSmallInteger('max_items')->nullable(); + $table->unsignedSmallInteger('used_items')->nullable(); + + $table->boolean('shipping')->default(true); + + $table->boolean('active')->default(false); + + $table->foreign('promotion_admin_id') + ->references('id') + ->on('promotion_admins'); + + $table->foreign('product_id') + ->references('id') + ->on('products'); + + + $table->timestamps(); + }); + } + + /** + * Reverse the migrations. + * + * @return void + */ + public function down() + { + Schema::dropIfExists('promotion_admin_products'); + } +} diff --git a/database/migrations/2021_10_11_135231_create_promotion_users_table.php b/database/migrations/2021_10_11_135231_create_promotion_users_table.php new file mode 100644 index 0000000..6e6eeb4 --- /dev/null +++ b/database/migrations/2021_10_11_135231_create_promotion_users_table.php @@ -0,0 +1,56 @@ +increments('id'); + $table->unsignedInteger('promotion_admin_id')->index(); + $table->unsignedInteger('user_id'); + + $table->string('name', 255); + $table->text('description')->nullable(); + $table->string('url', 255)->nullable(); + + $table->boolean('pick_up')->default(true); + + $table->decimal('used_budget_total', 13, 2)->nullable(); + $table->unsignedSmallInteger('sell_items_total')->nullable(); + + $table->boolean('active')->default(false); + + $table->timestamp('user_deleted_at')->nullable(); + + $table->timestamps(); + + $table->foreign('promotion_admin_id') + ->references('id') + ->on('promotion_admins'); + + $table->foreign('user_id') + ->references('id') + ->on('users'); + }); + } + + /** + * Reverse the migrations. + * + * @return void + */ + public function down() + { + Schema::dropIfExists('promotion_users'); + } +} diff --git a/database/migrations/2021_10_11_135233_create_promotion_user_products_table.php b/database/migrations/2021_10_11_135233_create_promotion_user_products_table.php new file mode 100644 index 0000000..42a88a5 --- /dev/null +++ b/database/migrations/2021_10_11_135233_create_promotion_user_products_table.php @@ -0,0 +1,62 @@ +increments('id'); + + $table->unsignedInteger('promotion_admin_id')->index(); + $table->unsignedInteger('promotion_user_id')->index(); + + $table->unsignedInteger('promotion_admin_product_id')->index(); + $table->unsignedInteger('product_id')->index(); + + $table->unsignedSmallInteger('open_items')->nullable(); + $table->unsignedSmallInteger('sell_items')->nullable(); + + $table->decimal('used_budget_total', 13, 2)->nullable(); + + $table->boolean('active')->default(false); + + $table->foreign('promotion_admin_id') + ->references('id') + ->on('promotion_admins'); + + $table->foreign('promotion_user_id') + ->references('id') + ->on('promotion_users'); + + $table->foreign('promotion_admin_product_id') + ->references('id') + ->on('promotion_admin_products'); + + $table->foreign('product_id') + ->references('id') + ->on('products'); + + + $table->timestamps(); + }); + } + + /** + * Reverse the migrations. + * + * @return void + */ + public function down() + { + Schema::dropIfExists('promotion_user_products'); + } +} diff --git a/public/css/application.css b/public/css/application.css index aa7890e..1746c66 100644 --- a/public/css/application.css +++ b/public/css/application.css @@ -81,4 +81,8 @@ a[aria-expanded='true'] > .fa-caret-expand:before { .spinner { display: none; +} + +.table-striped tbody tr:nth-of-type(odd) { + background-color: rgba(38, 64, 95, 0.04); } \ No newline at end of file diff --git a/public/js/iq-promotion-cart.js b/public/js/iq-promotion-cart.js new file mode 100644 index 0000000..cf9bf45 --- /dev/null +++ b/public/js/iq-promotion-cart.js @@ -0,0 +1,120 @@ + +var IqPromotionCart = { + table: "#datatables-promotion-list", + btn_add: '.add-product-promotion', + btn_remove: '.remove-product-promotion', + input_event: '.input-event-promotion-onchange', + check_event: '.check-event-promotion-onchange', + url: null, + action: null, + cart_holder: '#holder_html_view_cart', + + init: function () { + var _self = this; + _self.url = $(_self.table).data('url'); + _self.action = $(_self.table).data('action'); + _self.initElements(); + return _self; + }, + initElements: function (){ + var _self = this; + $(_self.table).find(_self.btn_add).on('click', function(){ + _self.add_product($(this)) + }); + $(_self.table).find(_self.btn_remove).on('click', function(){ + _self.remove_product($(this)) + }); + $(_self.table).find(_self.input_event).off('change').on('change', function(){ + _self.update_input_table($(this)); + }); + $(_self.table).find(_self.check_event).off('change').on('change', function(){ + _self.update_input_table($(this)); + }); + }, + + add_product: function (_obj){ + var _self = this; + var input = $(_self.table).find('input#product_qty_'+_obj.data('product-id')); + var qty = parseInt(input.val()) + 1; + qty = _self.checkNumber(qty); + input.val(qty); + _self.update_cart(); + }, + remove_product: function (_obj){ + var _self = this; + var input = $(_self.table).find('input#product_qty_'+_obj.data('product-id')); + var qty = parseInt(input.val()) - 1; + if(qty < 0){ + qty = 0; + } + input.val(qty); + _self.update_cart(); + }, + update_input_table: function (_obj){ + var _self = this; + var qty = parseInt(_obj.val()); + qty = _self.checkNumber(qty); + _obj.val(qty); + _self.update_cart(); + }, + checkNumber : function(number){ + if(number < 0 || isNaN(number)){ + return 0; + } + if(number >= 100){ + return 100; + } + return number; + }, + update_cart: function (){ + var _self = this; + var data = {}; + var tempData = []; + $(_self.table).find(_self.input_event).each(function(){ + //push, is checked + if($(_self.table).find('#product_check_'+$(this).data('product-id')).is(':checked')){ + tempData.push({product_id: $(this).data('product-id'), qty: $(this).val()}); + } + }); + data.action = $(_self.table).data('action'); + data.user_promotion_id = $(_self.table).data('user_promotion_id'); + data.products = tempData; + _self.performRequest(data) + .done(_self.refreshItemsAndView); + }, + + refreshItemsAndView: function (data){ + var _self = IqPromotionCart; + //console.log(data.html_cart); + $(_self.cart_holder).html(data.html_cart); + }, + performRequest : function(data) { + var _self = this; + var url = _self.url, + contentType = 'application/x-www-form-urlencoded; charset=UTF-8'; + // console.log(data); + // console.log(url); + return $.ajax({ + url: url, + data: data, + type: "POST", + dataType: "json", + cache: false, + contentType: contentType, + encode: true, + headers: { + 'X-CSRF-TOKEN': $('meta[name="csrf-token"]').attr('content') + } + }) + .done(function (data) { + // console.log('performRequest'); + // console.log(data); + }).fail(function (jqXHR, textStatus, errorThrown) { + console.log(jqXHR); + console.log(jqXHR.responseText); + console.log(textStatus); + console.log(errorThrown); + console.log("Sorry, there was a problem!"); + }); + } +}; \ No newline at end of file diff --git a/resources/lang/de/navigation.php b/resources/lang/de/navigation.php index 601cf6b..cf40510 100755 --- a/resources/lang/de/navigation.php +++ b/resources/lang/de/navigation.php @@ -45,5 +45,8 @@ return [ 'invoice' => 'Rechnungen', 'revenue' => 'Umsätze', 'paycredit' => 'Einkaufsguthaben', - 'commissions' => 'Provisionen' + 'commissions' => 'Provisionen', + 'promotion' => 'Promotion', + 'my_promotions' => 'Meine Promotions' + ]; diff --git a/resources/lang/de/payment.php b/resources/lang/de/payment.php index 2ce0969..4120e51 100755 --- a/resources/lang/de/payment.php +++ b/resources/lang/de/payment.php @@ -22,4 +22,5 @@ return [ ], 'payment_for_account' => 'Aufladung durch Mitgliedschaft', 'user_order_deduction' => 'Abzug durch Bestellung', + 'user_order_return' => 'Rückführung durch Storno', ]; \ No newline at end of file diff --git a/resources/lang/de/validation.php b/resources/lang/de/validation.php index 4bcdc85..bc985cd 100755 --- a/resources/lang/de/validation.php +++ b/resources/lang/de/validation.php @@ -212,6 +212,7 @@ return [ 'sales_partnership' => 'Vertriebspartnerschaft', 'sales_partnership_message' => 'Vertriebspartnerschaft Hinweis', 'tax_number' => 'Steuernummer', - 'tax_identification_number' => 'USt-ID Nummer' + 'tax_identification_number' => 'USt-ID Nummer', + 'user_promotion_url' => "Promotion Domain" ], ]; diff --git a/resources/views/admin/modal/promotion-product.blade.php b/resources/views/admin/modal/promotion-product.blade.php new file mode 100644 index 0000000..7069c1e --- /dev/null +++ b/resources/views/admin/modal/promotion-product.blade.php @@ -0,0 +1,72 @@ +{!! Form::open(['url' => route('admin_promotion_detail', [$data['promotion_id']]), 'class' => 'modal-content form-prevent-multiple-submits', 'enctype' => 'multipart/form-data']) !!} + + + +{!! Form::close() !!} + + diff --git a/resources/views/admin/modal/promotion-products.blade.php b/resources/views/admin/modal/promotion-products.blade.php new file mode 100644 index 0000000..9f2edd0 --- /dev/null +++ b/resources/views/admin/modal/promotion-products.blade.php @@ -0,0 +1,45 @@ +{!! Form::open(['url' => route('admin_payments_credit'), 'class' => 'modal-content form-prevent-multiple-submits', 'enctype' => 'multipart/form-data']) !!} + + + +{!! Form::close() !!} + + diff --git a/resources/views/admin/promotion/detail.blade.php b/resources/views/admin/promotion/detail.blade.php new file mode 100644 index 0000000..8acf815 --- /dev/null +++ b/resources/views/admin/promotion/detail.blade.php @@ -0,0 +1,46 @@ +@extends('layouts.layout-2') + +@section('content') + + @if ($errors->any()) +
+
+
+
    + @foreach ($errors->all() as $error) +
  • {{ $error }}
  • + @endforeach +
+
+
+
+ @endif + +

+ {{ __('Create/Edit Promotion') }} +

+ + {!! Form::open(['url' => route('admin_promotion_detail', $promotion->id), 'class' => 'form-horizontal']) !!} + + +
+   + {{ __('back') }} +
+ + @include('admin.promotion.form') + +
+   + {{ __('back') }} +
+ + {!! Form::close() !!} + + + +@endsection diff --git a/resources/views/admin/promotion/form.blade.php b/resources/views/admin/promotion/form.blade.php new file mode 100644 index 0000000..1488ab0 --- /dev/null +++ b/resources/views/admin/promotion/form.blade.php @@ -0,0 +1,150 @@ + +
+ +
+ {{ __('Promotion') }} +
+
+ +
+ + + {{ Form::text('name', $promotion->name, array('placeholder'=>__('Name'), 'class'=>'form-control', 'id'=>'name', 'required')) }} +
+ +
+ +
+ + {{ Form::select('type', $promotion->promotionType, $promotion->type, array('data-live-search'=>'false', 'class'=>'selectpicker', 'id'=>'type') ) }} +
+
+
+
+ + +
+
+
+
+ + {{ Form::textarea('description', $promotion->description , array('placeholder'=>__('Interne Notiz'), 'class'=>'form-control', 'rows'=>2, 'id'=>'description')) }} +
+
+ +
+ +
+ + {{ Form::text('max_bugdet', $promotion->getFormattedMaxBugdet(), array('placeholder'=>__('Budget in Euro / Brutto'), 'class'=>'form-control', 'id'=>'max_bugdet')) }} +
+ +
+ + {{ Form::text('max_items', $promotion->max_items, array('placeholder'=>__('Einheiten in Stück'), 'class'=>'form-control', 'id'=>'max_items')) }} +
+
+
+ Ist das Budget oder Einheiten erreicht, wird auf der Microseite keine Promotion mehr angezeigt. +
+
+
+
+ + {!! Form::text('from', $promotion->from, ['class'=>'form-control datepicker-base']) !!} +
+ +
+ + {!! Form::text('to', $promotion->to, ['class'=>'form-control datepicker-base']) !!} +
+ + +
+
+ Ist das ab oder bis Datum gesetzt wird die Promotion nur innerhalb dieses Zeitraumns angezeigt. +
+ + +
+
+
+ + +
+
+ {{ __('Produkte') }} +
+ @if($promotion->id > 0) + +
+ + +
+
+
+ + + + + + + + + + + + + + + + + + + @foreach($promotion->promotion_admin_products as $promotion_admin_products) + + + + + + + + + + + + + + @endforeach + +
 {{__('Bild')}}{{__('Produkt')}}{{__('Versandkosten') }}{{__('Provision') }}{{__('Neuer Preis')}}{{__('Preis B.') }}{{__('max. P.') }}{{__('verkauft P.') }}{{__('active') }}
+ + + @if(count($promotion_admin_products->product->images)) + + @endif + {{ $promotion_admin_products->product->name }}{!! get_active_badge($promotion_admin_products->calcu_commission) !!}{!! get_active_badge($promotion_admin_products->shipping) !!}{!! get_active_badge($promotion_admin_products->own_price) !!}{{ $promotion_admin_products->getFormattedRealPrice() }} €{{ $promotion_admin_products->max_items }}{{ $promotion_admin_products->used_items }}{!! get_active_badge($promotion_admin_products->active) !!}
+
+
+ @endif +
+ + + diff --git a/resources/views/admin/promotion/index.blade.php b/resources/views/admin/promotion/index.blade.php new file mode 100644 index 0000000..656b744 --- /dev/null +++ b/resources/views/admin/promotion/index.blade.php @@ -0,0 +1,90 @@ +@extends('layouts.layout-2') + +@section('content') +

+
{{ __('navigation.promotion') }} / {{ __('navigation.overview') }}
+   Neue Promotion anlegen +

+ +
+
+ + @foreach($values as $value) +
+
+
+ {{$value->name}} +
+ @if($value->canDelete()) +
+ + + +
+ @endif +
+
+
+
+
+ {{$value->description}} +
+
+
+
+
+
Typ
+
{{$value->getPromotionType()}}
+
+
+
Produkte
+
{{$value->promotion_admin_products->count()}}
+
+
+
max Budget
+
{{ $value->getFormattedMaxBugdet() }}
+
+
+
max Produkte
+
{{$value->max_items}}
+
+
+
Datum von
+
{{ $value->from }}
+
+
+
Datum bis
+
{{ $value->to }}
+
+
+
Aktiv
+
{!! get_active_badge($value->active) !!}
+
+
+
+ +
+ +
+ @endforeach +
+
+
+ Alle User Promotions ansehen +
+
+ +@endsection \ No newline at end of file diff --git a/resources/views/admin/promotion/show.blade.php b/resources/views/admin/promotion/show.blade.php new file mode 100644 index 0000000..eaeb827 --- /dev/null +++ b/resources/views/admin/promotion/show.blade.php @@ -0,0 +1,76 @@ +@extends('layouts.layout-2') + +@section('content') + +

+ {{ __('navigation.promotion') }} / + @if($by === 'promotion') + {{ $promotion->name }} User Promotions + @endif + @if($by === 'all') + Alle User Promotions + @endif +

+ +
+ {{ __('back') }} +
+ +
+
+
+
+ + + + + + + + + + + + + + + + + + +
#{{__('User')}}{{__('Name')}}{{__('aktive Produkte')}}{{__('geplant Produkte')}}{{__('geordert Produkte')}}{{__('Potentielle Kosten')}}{{__('User Guthaben')}}{{__('Kosten bisher')}}{{__('aktiv')}}{{__('Abholung')}}{{__('Gelöscht')}}
+
+
+
+
+ +@endsection \ No newline at end of file diff --git a/resources/views/layouts/includes/layout-sidenav.blade.php b/resources/views/layouts/includes/layout-sidenav.blade.php index 55a9648..b270a26 100644 --- a/resources/views/layouts/includes/layout-sidenav.blade.php +++ b/resources/views/layouts/includes/layout-sidenav.blade.php @@ -39,7 +39,6 @@ - @if(Auth::user()->isActiveAccount())
  • @@ -85,6 +84,23 @@
  • @endif + {{-- TODO Remove isAdmin --}} + @if(Auth::user()->isActiveAccount() && Auth::user()->isAdmin()) +
  • + + +
    {{ __('navigation.my_promotions') }}
    +
    +
    Admin
    +
    +
    + +
  • + @endif @endif @if(Auth::user()->isAdmin()) @@ -153,6 +169,19 @@ +
  • + + +
    {{ __('navigation.promotion') }}
    +
    + +
  • + + {{--
  • diff --git a/resources/views/user/membership/index.blade.php b/resources/views/user/membership/index.blade.php index 46702b9..19e7b90 100644 --- a/resources/views/user/membership/index.blade.php +++ b/resources/views/user/membership/index.blade.php @@ -23,7 +23,7 @@ @if($user->isRenewalAccount())
    -
    Deine Mitglidschaft wurde am {{ $user->nextRenewalAccount() }} verlängert.
    +
    Deine Mitgliedschaft wurde am {{ $user->nextRenewalAccount() }} verlängert.
    @if($userHistoryPaymentOrder && $userHistoryPaymentOrder->status > 2)
    Eine Zahlung wurde ausgeführt. Status: {{ trans('payment.status.'.$userHistoryPaymentOrder->getStatusType())}}
    @@ -102,7 +102,7 @@
    {{__('Mitgliedschaft')}} {{__('anpassen')}}
    -
    Du kannst Deine Mitglidschaft bis zur nächsten Vertragsverlängerung, am {{ $user->nextRenewalAccount() }}, ändern.
    +
    Du kannst Deine Mitgliedschaft bis zur nächsten Vertragsverlängerung, am {{ $user->nextRenewalAccount() }}, ändern.

    Die restlichen Laufzeiten bleiben erhalten, erst mit der Verlängerung wird das geänderte Paket aktiv.

    @include('user.membership._change')
    @@ -117,7 +117,7 @@
    {{__('Mitgliedschaft')}} {{__('anpassen')}}
    -
    Du kannst Deine Mitglidschaftsrolle bis zur nächsten Vertragsverlängerung ({{ $user->nextRenewalAccount() }}), ändern. +
    Du kannst Deine Mitgliedschaftsrolle bis zur nächsten Vertragsverlängerung ({{ $user->nextRenewalAccount() }}), ändern.
    Erst nach der Verlängerug ist die neue Rolle aktiv.
    @include('user.membership._change_level') diff --git a/resources/views/user/promotion/cart.blade.php b/resources/views/user/promotion/cart.blade.php new file mode 100644 index 0000000..57f0d61 --- /dev/null +++ b/resources/views/user/promotion/cart.blade.php @@ -0,0 +1,17 @@ +
    + Potentielle Kosten für diese Promotion: + {{ formatNumber($user_promotion_cart['price_net']) }} € netto / {{ formatNumber($user_promotion_cart['price']) }} € inkl. MwSt. +
    +

    Text ...

    + +@if(isset($checkPaymentCredit)) + @if($checkPaymentCredit === 'empty') +
    Du hast kein Guthaben aus Deinem Konto auf, lade Dein Konto auf, bis dahin ist die Promotion gestoppt.
    + @endif + @if($checkPaymentCredit === 'okay') +
    Dein Guthaben ist für diese Promotion
    + @endif + @if($checkPaymentCredit === 'not') +
    Dein Guthaben ist nicht ausreichend für diese Promotion, lade Dein Konto auf, bis dahin ist die Promotion gestoppt.
    + @endif +@endif \ No newline at end of file diff --git a/resources/views/user/promotion/detail.blade.php b/resources/views/user/promotion/detail.blade.php new file mode 100644 index 0000000..ffb6086 --- /dev/null +++ b/resources/views/user/promotion/detail.blade.php @@ -0,0 +1,47 @@ +@extends('layouts.layout-2') + +@section('content') + + @if ($errors->any()) +
    +
    +
    +
      + @foreach ($errors->all() as $error) +
    • {{ $error }}
    • + @endforeach +
    +
    +
    +
    + @endif + +

    +
    {{ __('navigation.my_promotions') }} / {{ __('bearbeiten') }}
    +

    + + {!! Form::open(['url' => route('user_promotion_detail', $user_promotion->id), 'class' => 'form-horizontal', 'id'=>"user-promotion-form-validations"]) !!} + +
    + + @include('user.promotion.form') + +
    +   + {{ __('back') }} +
    + + {!! Form::close() !!} + + + + + +@endsection diff --git a/resources/views/user/promotion/form.blade.php b/resources/views/user/promotion/form.blade.php new file mode 100644 index 0000000..da32a29 --- /dev/null +++ b/resources/views/user/promotion/form.blade.php @@ -0,0 +1,341 @@ + +
    +
    + {{ __('Promotion') }} +
    +
    +
    +
    + + + {{ Form::text('name', $user_promotion->name, ['placeholder' => __('Promotion Name'), 'class' => 'form-control', 'id' => 'name', 'required' => true]) }} + @if ($errors->has('name')) + + {{ $errors->first('name') }} + + @endif +
    +
    + + {{ Form::textarea('description', $user_promotion->description, ['placeholder' => __('Kurzbeschreibung'), 'class' => 'form-control', 'rows' => 2, 'id' => 'description']) }} +
    +
    + +

    Text...

    +
    +
    +
    + +
    + www.testemicht.jetzt/   +
    +
    + {{ Form::text('user_promotion_url', $user_promotion->url, ['placeholder' => 'z.B. "thomas" oder "dani21" o.ä.', 'class' => 'form-control' . ($errors->has('user_promotion_url') ? ' is-invalid' : ''), 'id' => 'user_promotion_url', 'required' => true]) }} +
    + @if ($errors->has('user_promotion_url')) + + {{ $errors->first('user_promotion_url') }} + + @endif +
    +
    +
    + + +
    +
    +
    + + {{ Form::text('preview_user_promotion_url', $user_promotion->getUrlPreview(), ['placeholder' => __('Vorschau Shop-Internet Adresse'), 'class' => 'form-control', 'id' => 'preview_user_promotion_url', 'readonly']) }} +
    + +
    + +
    +
    +
    + +
    +
    + + + +
    +
    +
    +

    Text ...

    +
    + Aktuelles Guthaben: {{ Auth::user()->getFormattedPaymentCredit() }} € + (Guthaben aufladen unter: Bestellungen aufgeben -> Produkt + Guthaben aufladen) +
    + + +
    + + + + + + + + + + + + + + @foreach ($user_promotion->promotion_admin->promotion_admin_products_active as $promotion_admin_product) + + + + + + + + + + @endforeach + +
    Aktiv{{ __('Anzahl') }}{{ __('Produkt') }}{{ __('Mein Preis netto') }}{{ __('Mein Preis brutto') }}{{ __('geordert') }}
    + + +
    +
    + + + + + + + + +
    +
    +
    +
    + @if ($promotion_admin_product->product) + @if ($promotion_admin_product->product->images) + @if ($image = $promotion_admin_product->product->images->first()) + + @endif + @endif +
    + {{ $promotion_admin_product->product->name }} + #{{ $promotion_admin_product->product->number }} + + Inhalt: + {{ $promotion_admin_product->product->contents }}
    + Gewicht: + {{ $promotion_admin_product->product->weight }} g
    +
    + +
    +
    + @endif +
    +
    + {{ $promotion_admin_product->getFormattedPriceWith(true) }} € + + {{ $promotion_admin_product->getFormattedPriceWith(false) }} € + + {{ $promotion_admin_product->getPromotionUserProducts($user_promotion, 'sell_items') }} +
    +
    +
    +
    +
    + @include('user.promotion.cart', ['user_promotion_cart'=> $user_promotion_cart, 'checkPaymentCredit' => $checkPaymentCredit] ) +
    +
    + + + + +@section('scripts') + +@endsection \ No newline at end of file diff --git a/resources/views/user/promotion/index.blade.php b/resources/views/user/promotion/index.blade.php new file mode 100644 index 0000000..439949a --- /dev/null +++ b/resources/views/user/promotion/index.blade.php @@ -0,0 +1,199 @@ +@extends('layouts.layout-2') + +@section('content') +

    +
    {{ __('navigation.my_promotions') }} / {{ __('navigation.overview') }}
    + +

    + +

    Text ...

    + +
    +
    + +
    +
    +
    +

    Text ...

    +
    +
    +
    + + +
    +
    + + @foreach($values as $value) + +
    +
    + + @if($value->canDelete()) +
    + + + +
    + @endif +
    +
    +
    +
    +
    + {{$value->description}} +
    +
    +
    +
    +
    +
    Promotion Produkte
    +
    {{$value->promotion_admin->promotion_admin_products_active->count()}} + {{ formatPlural($value->promotion_admin->promotion_admin_products_active->count(), 'Sorte', 'n') }} +
    +
    + +
    +
    aktive Produkte
    +
    {{$value->promotion_user_products_active->count()}} + {{ formatPlural($value->promotion_user_products_active->count(), 'Sorte', 'n') }} +
    +
    + +
    +
    geplant Produkte
    +
    {{$value->getCountOpenItems()}} Stk.
    +
    + +
    +
    geordert Produkte
    +
    {{$value->getCountSellItems()}} Stk.
    +
    + + +
    +
    +
    +
    Promotion aktiv
    +
    {!! get_active_badge($value->active) !!}
    +
    + +
    +
    persönliche Abholung
    +
    {!! get_active_badge($value->pick_up) !!}
    + +
    +
    +
    Potentielle Kosten
    + @php($user_promotion_cart = $value->calculateCart()) +
    {{ formatNumber($user_promotion_cart['price']) }} € brutto
    +
    +
    +
    Kosten bisher
    + @php($user_promotion_sell = $value->calculateSell()) +
    {{ formatNumber($user_promotion_sell['price']) }} € brutto
    +
    + +
    +
    +
    +
    +
    +
    + +
    + + + + +
    +
    +
    + +
    + +
    +
    +
    + @php($checkPaymentCredit = $value->checkPaymentCredit()) + @if($checkPaymentCredit === 'empty') +
    Du hast kein Guthaben aus Deinem Konto auf, lade Dein Konto auf, bis dahin ist die Promotion gestoppt.
    + @endif + @if($checkPaymentCredit === 'okay') +
    Dein Guthaben ist für diese Promotion
    + @endif + @if($checkPaymentCredit === 'not') +
    Dein Guthaben ist nicht ausreichend für diese Promotion, lade Dein Konto auf, bis dahin ist die Promotion gestoppt.
    + @endif +
    + +
    + +
    + @endforeach +
    +
    + + + + + + + +@endsection \ No newline at end of file diff --git a/routes/web.php b/routes/web.php index fb735ab..7140d44 100644 --- a/routes/web.php +++ b/routes/web.php @@ -21,6 +21,7 @@ Route::get('/logout', function(){ return Redirect::to('login'); })->name('logout'); +/* Route::get('storage/images/{from}/{slug}', function($from = null, $slug = null) { if ($from == 'shop'){ $image = \App\Models\UserShop::where('filename', $slug)->first(); @@ -31,6 +32,7 @@ Route::get('storage/images/{from}/{slug}', function($from = null, $slug = null) } })->name('storage_images'); +*/ Route::get('/product/image/{slug}', function($slug = null) { @@ -195,6 +197,12 @@ Route::group(['middleware' => ['auth:user']], function() { Route::post('/user/checkout_store/{identifier?}', 'User\CheckoutController@store')->name('user_checkout_store'); Route::get('/user/checkout_final/{payid}/{reference}/{identifier?}', 'User\CheckoutController@final')->name('user_checkout_final'); + Route::get('/user/promotions', 'User\PromotionController@index')->name('user_promotions'); + Route::get('/user/promotion/detail/{id}', 'User\PromotionController@detail')->name('user_promotion_detail'); + Route::post('/user/promotion/detail/{id}', 'User\PromotionController@store')->name('user_promotion_detail'); + Route::post('/user/promotion/load', 'User\PromotionController@load')->name('user_promotion_load'); + Route::get('/user/promotion/delete/{id}/{del?}', 'User\PromotionController@delete')->name('user_promotion_delete'); + }); Route::group(['middleware' => ['admin']], function() @@ -307,8 +315,12 @@ Route::group(['middleware' => ['admin']], function() Route::post('/admin/payments/invoice', 'PaymentInvoiceController@index')->name('admin_payments_invoice'); Route::get('/admin/payments/invoice/datatable', 'PaymentInvoiceController@datatable')->name('admin_payments_invoice_datatable'); - - + Route::get('/admin/promotions', 'AdminPromotionController@index')->name('admin_promotions'); + Route::get('/admin/promotion/detail/{id}', 'AdminPromotionController@detail')->name('admin_promotion_detail'); + Route::post('/admin/promotion/detail/{id}', 'AdminPromotionController@store')->name('admin_promotion_detail'); + Route::get('/admin/promotion/delete/{id}/{del?}', 'AdminPromotionController@delete')->name('admin_promotion_delete'); + Route::get('/admin/promotion/show/{by}/{id?}', 'AdminPromotionController@show')->name('admin_promotion_show'); + Route::get('/admin/promotion/datatable/{by}/{id?}', 'AdminPromotionController@datatable')->name('admin_promotion_datatable'); });