604 lines
22 KiB
PHP
604 lines
22 KiB
PHP
<?
|
|
namespace shop;
|
|
|
|
use common\Image;
|
|
use core\db\structure\Column as C;
|
|
use core\db\structure\eColumnType;
|
|
use Mpdf\Tag\P;
|
|
use shop\core\structure\shopModuleTable;
|
|
use shop\coupon\structure\eShopCouponType;
|
|
use shop\item\Growth;
|
|
use shop\item\structure\eShopItemPriceType;
|
|
use shop\property\Value;
|
|
use ui\form\structure\eInputType;
|
|
use ui\Form;
|
|
use ui\input\Input;
|
|
use core\lang\structure\LangVariable as V;
|
|
use shop\cart\structure\shopCartLang as Vars;
|
|
use shop\cart\Item as ShopItem;
|
|
use shop\item\value as ItemValue;
|
|
use shop\item\price\Component as PriceComponent;
|
|
use shop\Component;
|
|
use shop\item\price\variant as PriceVariant;
|
|
|
|
|
|
class Cart extends shopModuleTable {
|
|
static $self;
|
|
static $table_name = 'shopCart';
|
|
static $controller = 'shop.cart';
|
|
|
|
static $ID = 'id';
|
|
static $PORTAL = 'portal';
|
|
static $PROFILE = 'profile';
|
|
static $KEY = 'key';
|
|
static $HASH = 'hash';
|
|
static $ORDER = 'order';
|
|
static $COUPON_NAME = 'coupon_name';
|
|
static $COUPON_VALUE = 'coupon_value';
|
|
static $COUPON_TYPE = 'coupon_type';
|
|
|
|
|
|
|
|
static $ACCOUNT = 'account';
|
|
static $CREATED = 'created';
|
|
static $UPDATED = 'updated';
|
|
|
|
|
|
static function getTitle(){return V::get(Vars::$MODULE_NAME);}
|
|
static function getSystemLangValues():array{ return Vars::getArray(); }
|
|
public function _update(\Where $w, array $values) {
|
|
$values[self::$UPDATED] = time();
|
|
return parent::_update($w, $values);
|
|
}
|
|
public static function installUniques() {
|
|
//parent::installUniques(); // TODO: Change the autogenerated stub
|
|
\DB::addIndex(self::$table_name,self::$PORTAL);
|
|
\DB::addIndex(self::$table_name,self::$KEY);
|
|
\DB::addIndex(self::$table_name,self::$HASH);
|
|
\DB::addIndex(self::$table_name,self::$ORDER);
|
|
}
|
|
|
|
static function setShopItemCount($cid,$count){
|
|
$count = floatval($count);
|
|
$r = ShopItem::updateById($cid,[ShopItem::$COUNT=>$count]);
|
|
$citem = ShopItem::getByID(intval($cid));
|
|
$cart = Cart::getByID($citem[ShopItem::$CART]);
|
|
if($order_id = intval($cart[Cart::$ORDER])){
|
|
Order::remath($order_id);
|
|
}
|
|
}
|
|
|
|
static function setShopItemPrice($cid,$price){
|
|
$price = floatval($price);
|
|
$r = ShopItem::updateById($cid,[ShopItem::$PRICE=>$price]);
|
|
$citem = ShopItem::getByID(intval($cid));
|
|
$cart = Cart::getByID($citem[ShopItem::$CART]);
|
|
if($order_id = intval($cart[Cart::$ORDER])){
|
|
Order::remath($order_id);
|
|
}
|
|
}
|
|
|
|
static function removeShopItem($cid){
|
|
$citem = ShopItem::getByID(intval($cid));
|
|
$cart = Cart::getByID($citem[ShopItem::$CART]);
|
|
ShopItem::deleteByID($cid);
|
|
if($order_id = intval($cart[Cart::$ORDER])){
|
|
Order::remath($order_id);
|
|
}
|
|
}
|
|
|
|
static function changeComponentCount($cid,$count){
|
|
$count = floatval($count);
|
|
$res = self::changeCartItem($cid,['component_count'=>$count]);
|
|
return $res;
|
|
}
|
|
static function changePriceComponent($cid,$id){
|
|
$res = [];
|
|
$id = intval($id);
|
|
$C = ShopItem::getByID($cid);
|
|
$price = PriceComponent::getByID($id);
|
|
if($price[PriceComponent::$ITEM] == $C[ShopItem::$ITEM]) {
|
|
$res = self::changeCartItem($cid, ['component_price_id' => $id]);
|
|
}
|
|
return $res;
|
|
}
|
|
static function changePropertyValue($cid,$property_id,$value_id){
|
|
$property_id = intval($property_id);
|
|
$value_id = intval($value_id);
|
|
$C = ShopItem::getByID($cid);
|
|
$props = json_decode($C[ShopItem::$PROPS],true);
|
|
if(!is_array($props)) $props = [];
|
|
if($value_id) {
|
|
$props[$property_id] = $value_id;
|
|
} else {
|
|
unset($props[$property_id]);
|
|
}
|
|
$res = self::changeCartItem($cid, ['props' => $props]);
|
|
return $res;
|
|
}
|
|
|
|
static function changeCartItem($cid,$options){
|
|
$C = ShopItem::getByID($cid);
|
|
$cart = Cart::getByID($C[ShopItem::$CART]);
|
|
$order = Order::getByID($cart[Cart::$ORDER]);
|
|
$order_id = $order[Order::$ID];
|
|
|
|
$component_count = isset($options['component_count']) ? cfloatval($options['component_count']) : $C[ShopItem::$COMPONENT_COUNT];
|
|
$component_price_id = isset($options['component_price_id']) ? intval($options['component_price_id']) : $C[ShopItem::$COMPONENT_PRICE_ID];
|
|
$props = isset($options['props']) ? $options['props'] : json_decode($C[ShopItem::$PROPS],true);
|
|
|
|
$res = Cart::addToCart(
|
|
$C[ShopItem::$CART],
|
|
$order[Order::$OID],
|
|
$C[ShopItem::$ITEM],
|
|
$C[ShopItem::$COUNT],
|
|
[
|
|
'props' => $props,
|
|
'component_count' => $component_count,
|
|
'component_price_id' => $component_price_id,
|
|
'data' => json_decode($C[ShopItem::$DATA],true),
|
|
'getData' => true,
|
|
],
|
|
$C[ShopItem::$GROWTH]
|
|
);
|
|
ShopItem::updateById($cid,$res);
|
|
Order::remath($order_id);
|
|
return $res;
|
|
}
|
|
|
|
|
|
static function addToCart($cart_id,$shop_id,$item_id,$count,$options,$growth_id=0){
|
|
$item_id = intval($item_id);
|
|
$cart_id = intval($cart_id);
|
|
$count = floatval($count);
|
|
$shop_id = intval($shop_id);
|
|
$growth_id = intval($growth_id);
|
|
$variant_id = intval($options['variant']);
|
|
|
|
$component_count = 0;
|
|
$component_total = 0;
|
|
$component_price = 0;
|
|
$cp_id = 0;
|
|
|
|
$shop = new Shop();
|
|
$shop->id_for_theme = $shop_id;
|
|
$item = Item::getByID($item_id);
|
|
$shop->_getItemPrice($item);
|
|
$price = $item[Item::$PRICE];
|
|
$initial_price = $item[Item::$PRICE];
|
|
|
|
$SALE_PERCENT = 1;
|
|
$SALE = null;
|
|
if($item['sale']){
|
|
$SALE_PERCENT = (100-$item['sale']['percent'])/100;
|
|
}
|
|
if($item['personal_sale']){
|
|
$SALE_PERCENT = (100-$item['personal_sale']['percent'])/100;
|
|
}
|
|
if($item['sale']['sale_id']){
|
|
$SALE = Sale::getByID(intval($item['sale']['sale_id']));
|
|
}
|
|
|
|
if($growth_id){
|
|
$growth = Growth::getByID($growth_id);
|
|
if($growth){
|
|
$initial_price = $growth[Growth::$PRICE];
|
|
$price = $growth[Growth::$PRICE];
|
|
}
|
|
}
|
|
if($variant_id){
|
|
$variant = PriceVariant::getByID($variant_id);
|
|
if($variant){
|
|
$initial_price = $variant[PriceVariant::$PRICE];
|
|
$price = $variant[PriceVariant::$PRICE];
|
|
}
|
|
}
|
|
|
|
switch ($item_price = $item[Item::$PRICE_TYPE]) {
|
|
case eShopItemPriceType::COMPONENT:
|
|
$component = Component::getByID(intval($item[Item::$COMPONENT]));
|
|
$component_count = floatval($options['component_count']);
|
|
$component_price = floatval($component[Component::$PRICE]);
|
|
$component_total = floatval($component[Component::$PRICE]) * $component_count;
|
|
$price = $initial_price + $component_total;
|
|
break;
|
|
|
|
case eShopItemPriceType::COMPONENT_LIST:
|
|
$cp_id = intval($options['component_price_id']);
|
|
$cp = PriceComponent::getByID($cp_id);
|
|
$component_count = $cp[PriceComponent::$COUNT];
|
|
$price = $cp[PriceComponent::$PRICE];
|
|
$initial_price = $cp[PriceComponent::$PRICE];
|
|
$component_total = $price;
|
|
$component_price = $component_total/$component_count;
|
|
break;
|
|
case eShopItemPriceType::COMPONENT_MULTI:
|
|
$initial_price = $item['price'];
|
|
$price = $item['price'];
|
|
break;
|
|
}
|
|
|
|
|
|
if($options['props']) {
|
|
$_keys = array_keys($options['props']);
|
|
$keys = [];
|
|
foreach ($_keys as $v){
|
|
if($v = intval($v)) $keys[] = $v;
|
|
}
|
|
if($keys){
|
|
$r = Property::getByIDS($keys,true);
|
|
$values = [];
|
|
foreach ($r as $v){
|
|
$prop_id = $v[Property::$ID];
|
|
$value = intval($options['props'][$prop_id]);
|
|
if($v[Property::$IS_PRICE] and $value) {
|
|
$values[] = $value;
|
|
}
|
|
}
|
|
if($values) {
|
|
$r = ItemValue::getByIDS($values,true);
|
|
$total_props_price = [
|
|
'item_value'=>0,
|
|
'item_percent'=>0,
|
|
'component_value'=>0,
|
|
'component_percent'=>0,
|
|
];
|
|
foreach ($r as $v){
|
|
$props_price = json_decode($v[ItemValue::$PRICE],true);
|
|
switch (intval($props_price['item_type'])){
|
|
case 1: $total_props_price['item_value'] += cfloatval($props_price['item_price']); break;
|
|
case 2: $total_props_price['item_percent'] += cfloatval($props_price['item_price']); break;
|
|
}
|
|
switch (intval($props_price['component_type'])){
|
|
case 1: $total_props_price['component_value'] += cfloatval($props_price['component_price']); break;
|
|
case 2: $total_props_price['component_percent'] += cfloatval($props_price['component_price']); break;
|
|
}
|
|
}
|
|
|
|
switch (intval($item[Item::$PRICE_TYPE])){
|
|
case eShopItemPriceType::COMPONENT:
|
|
//$price -= $component_total;
|
|
$component_price = $component_price + $total_props_price['component_value'] + $component_price * $total_props_price['component_percent']/100;
|
|
$price = $initial_price + $total_props_price['item_value'] + $initial_price*$total_props_price['item_percent']/100;
|
|
$component_total = $component_price*$component_count;
|
|
$price += $component_total;
|
|
break;
|
|
default:
|
|
$total_add = $total_props_price['item_value'] + $initial_price*$total_props_price['item_percent']/100;
|
|
$price = $initial_price + $total_add;
|
|
}
|
|
/**/
|
|
}
|
|
}
|
|
}
|
|
|
|
$price *= $SALE_PERCENT;
|
|
|
|
|
|
$arr = [
|
|
ShopItem::$ITEM => $item_id,
|
|
ShopItem::$COUNT => $count,
|
|
ShopItem::$CART => $cart_id,
|
|
ShopItem::$PRICE => $price,
|
|
ShopItem::$GROWTH => $growth_id,
|
|
ShopItem::$PROPS => je($options['props']),
|
|
ShopItem::$DATA => je($options['data']),
|
|
|
|
ShopItem::$PRICE_TYPE => $item_price,
|
|
ShopItem::$BASE_PRICE => $price,
|
|
ShopItem::$COMPONENT => $item[Item::$COMPONENT],
|
|
ShopItem::$COMPONENT_COUNT => $component_count,
|
|
ShopItem::$COMPONENT_TOTAL => $component_total,
|
|
ShopItem::$COMPONENT_PRICE_ID => $cp_id,
|
|
|
|
ShopItem::$SALE_ID => intval($SALE[Sale::$ID]),
|
|
ShopItem::$SALE_TYPE => intval($SALE[Sale::$TYPE]),
|
|
ShopItem::$SALE_VALUE => intval($SALE[Sale::$VALUE]),
|
|
];
|
|
if($options['getData']) return $arr;
|
|
|
|
$r = ShopItem::insert($arr);
|
|
return $r;
|
|
}
|
|
|
|
static function clearMy(){
|
|
$CART = self::getMyCartData();
|
|
if($ids = array_keys($CART['citems'])){
|
|
ShopItem::deleteByIDS($ids);
|
|
}
|
|
|
|
}
|
|
static function getMyCartData(){ return self::getData(Cart::getMyCartID()); }
|
|
|
|
|
|
static $carts = [];
|
|
static function getData($cart_id,$options=[]){
|
|
|
|
$isCached = boolval($options['cached']);
|
|
if($isCached and self::$carts[$cart_id]) return self::$carts[$cart_id];
|
|
|
|
$cart_id = intval($cart_id);
|
|
$total_sale = 0;
|
|
$total_base = 0;
|
|
$count = 0;
|
|
$citems = [];
|
|
$items = [];
|
|
$cart = Cart::getByID($cart_id);
|
|
|
|
$isGetProps = boolval($options['props']);
|
|
$needProps = [];
|
|
$needValues = [];
|
|
|
|
$r = ShopItem::select([
|
|
\Query::LEFT_JOINS => [
|
|
[Item::$table_name, ShopItem::$ITEM,Item::$ID ],
|
|
[Image::$table_name,Item::$IMAGE, Image::$ID],
|
|
[Growth::$table_name,ShopItem::$GROWTH, Growth::$ID],
|
|
],
|
|
\Query::WHERE => new \Where(
|
|
\Where::_operator(ShopItem::$CART,'=',$cart_id)
|
|
)
|
|
],false);
|
|
while($l = \DB::fetch($r)) {
|
|
$citems[$l[ShopItem::$ID]] = $l;
|
|
$items[$l[Item::$ID]] = $l;
|
|
$price = $l[ShopItem::$PRICE] * $l[ShopItem::$COUNT];
|
|
if($l[ShopItem::$SALE_ID]){
|
|
$total_sale += $price;
|
|
} else {
|
|
$total_base += $price;
|
|
}
|
|
$count += $l[ShopItem::$COUNT];
|
|
}
|
|
|
|
$old = $total_sale + $total_base;
|
|
|
|
// Проверяем, был ли применён купон
|
|
if($cart[Cart::$COUPON_NAME]) {
|
|
|
|
switch ($cart[Cart::$COUPON_TYPE]) {
|
|
case eShopCouponType::VALUE:
|
|
$total_base -= $cart[Cart::$COUPON_VALUE];
|
|
break;
|
|
case eShopCouponType::PERCENT:
|
|
default:
|
|
$total_base *= (100-cfloatval($cart[Cart::$COUPON_VALUE]))/100;
|
|
break;
|
|
}
|
|
}
|
|
|
|
$total = $total_base + $total_sale;
|
|
$res = [
|
|
'cart' => $cart,
|
|
'citems' => $citems,
|
|
'items' => $items,
|
|
'total' => $total,
|
|
'old' => $old,
|
|
'count' => $count,
|
|
];
|
|
if($isGetProps){
|
|
$ids = array_keys($items);
|
|
$res['props'] = Shop::getPropsForItems($ids);
|
|
}
|
|
|
|
self::$carts[$cart_id] = $res;
|
|
return $res;
|
|
|
|
|
|
|
|
}
|
|
|
|
static function getCookieKeyCart(){ return 'cart_'.\Site::$portal_id; }
|
|
static function isProfileInitedCart(){
|
|
return (IF_PROFILE || isset( $_COOKIE[self::getCookieKeyCart()] ));
|
|
}
|
|
static function getCookieKey(){
|
|
return 'cart_'.\Site::$portal_id;
|
|
}
|
|
|
|
static function newCartForProfile($PID){
|
|
|
|
}
|
|
|
|
|
|
static $cookie_id;
|
|
|
|
static function insertNewCart() {
|
|
$key = intval(microtime(true)*10);
|
|
$hash = self::getHash($key,\Site::$portal_id);
|
|
$r = self::insert([
|
|
self::$PORTAL => \Site::$portal_id,
|
|
self::$HASH => $hash,
|
|
self::$KEY => $key,
|
|
self::$PROFILE => PID,
|
|
]);
|
|
$r->hash = $hash;
|
|
$r->key = $key;
|
|
return $r;
|
|
}
|
|
|
|
static function getMyCartID(){
|
|
if(self::$cookie_id) return self::$cookie_id;
|
|
$res = 0;
|
|
$cart = null;
|
|
$cookie = self::getCookieKey();
|
|
if(IF_PROFILE){
|
|
$res = intval(\Profile::$data[\Profile::$CART]);
|
|
$cart = Cart::getByID($res);
|
|
} else {
|
|
// Сначала находим корзину по куке
|
|
if($hash = $_COOKIE[$cookie]) {
|
|
$_cart = self::getOneEqualByColumn(self::$HASH,$hash);
|
|
if($_cart){
|
|
if($_cart[Cart::$PROFILE]==PID) {
|
|
$cart = $_cart;
|
|
$res = $cart[self::$ID];
|
|
}
|
|
}
|
|
}
|
|
// Для приложений мы можем поискать id в запросе.
|
|
if(\Core::$IS_APP){
|
|
$hash = $_POST['_cart_hash'];
|
|
$_cart = self::getOneEqualByColumn(self::$HASH,$hash);
|
|
if($_cart){
|
|
if($_cart[Cart::$PROFILE]==PID) {
|
|
$cart = $_cart;
|
|
$res = $cart[self::$ID];
|
|
}
|
|
}
|
|
}
|
|
}
|
|
// Если корзина не найдена, то создаём новую
|
|
if(!$cart) {
|
|
//$key = time();
|
|
/*
|
|
$key = intval(microtime(true)*10);
|
|
$hash = self::getHash($key,\Site::$portal_id);
|
|
$r = self::insert([
|
|
self::$PORTAL => \Site::$portal_id,
|
|
self::$HASH => $hash,
|
|
self::$KEY => $key,
|
|
self::$PROFILE => PID,
|
|
]);
|
|
/**/
|
|
$r = self::insertNewCart();
|
|
$hash = $r->hash;
|
|
$key = $r->key;
|
|
if(IF_PROFILE){
|
|
\Profile::updateById(PID,[
|
|
\Profile::$CART => $r->id,
|
|
]);
|
|
}
|
|
\Core::setCookie($cookie,$hash);
|
|
$res = $r->id;
|
|
}
|
|
self::$cookie_id = $res;
|
|
return $res;
|
|
|
|
}
|
|
|
|
static function getHash($key,$portal_id){
|
|
return md5(SALT.SALT.$key.$portal_id.SALT);
|
|
}
|
|
|
|
static function getForm($values = [], $options = []) :array {
|
|
return [
|
|
self::getCommonFormInputs(),
|
|
[
|
|
Form::VIEW=>Form::ROW,
|
|
Form::COLS => [
|
|
[
|
|
Form::VIEW =>Form::INPUT,
|
|
Form::COL_CLASSES =>'col-12',
|
|
Form::KEY_VALUE =>self::$NAME,
|
|
Form::TYPE =>eInputType::TEXT,
|
|
Form::INPUT_OPT => [
|
|
Input::PLACEHOLDER => $c = V::get(Vars::$NAME),
|
|
Input::LABEL => $c,
|
|
],
|
|
],
|
|
]
|
|
],
|
|
self::getCommonFormSubmits($values),
|
|
];
|
|
}
|
|
|
|
static function columnInfo() : array {
|
|
return [
|
|
new C([
|
|
C::VAR_NAME =>&self::$ID,
|
|
C::TYPE =>eColumnType::INT,
|
|
C::AUTO_INCREMENT =>true,
|
|
C::PRIMARY =>true,
|
|
C::DEFAULT =>0,
|
|
C::HIDDEN =>true,
|
|
C::TH =>V::get(Vars::$ID),
|
|
]),
|
|
new C([
|
|
C::VAR_NAME => &self::$PORTAL,
|
|
C::TYPE => eColumnType::INT,
|
|
C::LENGTH => 11,
|
|
C::TH => V::get(Vars::$SHOP),
|
|
]),
|
|
new C([
|
|
C::VAR_NAME => &self::$PROFILE,
|
|
C::TYPE => eColumnType::INT,
|
|
C::LENGTH => 11,
|
|
C::TH => V::get(Vars::$PROFILE),
|
|
]),
|
|
new C([
|
|
C::VAR_NAME => &self::$ORDER,
|
|
C::TYPE => eColumnType::INT,
|
|
C::HIDDEN => true,
|
|
C::DEFAULT => 0,
|
|
]),
|
|
new C([
|
|
C::VAR_NAME => &self::$COUPON_NAME,
|
|
C::TYPE => eColumnType::TEXT,
|
|
C::DEFAULT => '',
|
|
C::HIDDEN => true,
|
|
]),
|
|
new C([
|
|
C::VAR_NAME => &self::$COUPON_VALUE,
|
|
C::TYPE => eColumnType::DOUBLE,
|
|
C::HIDDEN => true,
|
|
C::DEFAULT => 0,
|
|
]),
|
|
new C([
|
|
C::VAR_NAME => &self::$COUPON_TYPE,
|
|
C::TYPE => eColumnType::TINYINT,
|
|
C::HIDDEN => true,
|
|
C::DEFAULT => 0,
|
|
]),
|
|
|
|
new C([
|
|
C::VAR_NAME => &self::$KEY,
|
|
C::TYPE => eColumnType::BIGINT,
|
|
C::LENGTH => 11,
|
|
C::TH => V::get(Vars::$KEY),
|
|
]),
|
|
new C([
|
|
C::VAR_NAME => &self::$HASH,
|
|
C::TYPE => eColumnType::VARCHAR,
|
|
C::LENGTH => 32,
|
|
C::TH => V::get(Vars::$HASH),
|
|
]),
|
|
new C([
|
|
C::VAR_NAME => &self::$ACCOUNT,
|
|
C::TYPE => eColumnType::INT,
|
|
C::LENGTH => 11,
|
|
C::TH => V::get(Vars::$ACCOUNT),
|
|
C::DEFAULT => intval(UID),
|
|
c::HIDDEN=>true,
|
|
c::FUNC_VALUE => function($v){
|
|
if($id = $v[self::$ACCOUNT]) {
|
|
return \Account::getName( \Account::getByID($id) );
|
|
} else return '-';
|
|
},
|
|
]),
|
|
new C([
|
|
C::VAR_NAME => &self::$CREATED,
|
|
C::TYPE => eColumnType::INT,
|
|
C::LENGTH => 11,
|
|
C::TH => V::get(Vars::$CREATED),
|
|
C::DEFAULT => time(),
|
|
c::FUNC_VALUE => function($v){return self::formatDate($v[self::$CREATED]);},
|
|
c::HIDDEN=>true,
|
|
]),
|
|
new C([
|
|
C::VAR_NAME => &self::$UPDATED,
|
|
C::TYPE => eColumnType::INT,
|
|
C::DEFAULT => time(),
|
|
C::TH => V::get(Vars::$UPDATED),
|
|
c::FUNC_VALUE => function($v){return self::formatDate($v[self::$UPDATED]);},
|
|
c::HIDDEN=>true,
|
|
]),
|
|
];
|
|
}
|
|
|
|
}
|
|
new Cart();
|
|
|
|
|
|
///
|