| 1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071727374757677787980818283848586878889909192939495969798991001011021031041051061071081091101111121131141151161171181191201211221231241251261271281291301311321331341351361371381391401411421431441451461471481491501511521531541551561571581591601611621631641651661671681691701711721731741751761771781791801811821831841851861871881891901911921931941951961971981992002012022032042052062072082092102112122132142152162172182192202212222232242252262272282292302312322332342352362372382392402412422432442452462472482492502512522532542552562572582592602612622632642652662672682692702712722732742752762772782792802812822832842852862872882892902912922932942952962972982993003013023033043053063073083093103113123133143153163173183193203213223233243253263273283293303313323333343353363373383393403413423433443453463473483493503513523533543553563573583593603613623633643653663673683693703713723733743753763773783793803813823833843853863873883893903913923933943953963973983994004014024034044054064074084094104114124134144154164174184194204214224234244254264274284294304314324334344354364374384394404414424434444454464474484494504514524534544554564574584594604614624634644654664674684694704714724734744754764774784794804814824834844854864874884894904914924934944954964974984995005015025035045055065075085095105115125135145155165175185195205215225235245255265275285295305315325335345355365375385395405415425435445455465475485495505515525535545555565575585595605615625635645655665675685695705715725735745755765775785795805815825835845855865875885895905915925935945955965975985996006016026036046056066076086096106116126136146156166176186196206216226236246256266276286296306316326336346356366376386396406416426436446456466476486496506516526536546556566576586596606616626636646656666676686696706716726736746756766776786796806816826836846856866876886896906916926936946956966976986997007017027037047057067077087097107117127137147157167177187197207217227237247257267277287297307317327337347357367377387397407417427437447457467477487497507517527537547557567577587597607617627637647657667677687697707717727737747757767777787797807817827837847857867877887897907917927937947957967977987998008018028038048058068078088098108118128138148158168178188198208218228238248258268278288298308318328338348358368378388398408418428438448458468478488498508518528538548558568578588598608618628638648658668678688698708718728738748758768778788798808818828838848858868878888898908918928938948958968978988999009019029039049059069079089099109119129139149159169179189199209219229239249259269279289299309319329339349359369379389399409419429439449459469479489499509519529539549559569579589599609619629639649659669679689699709719729739749759769779789799809819829839849859869879889899909919929939949959969979989991000100110021003100410051006100710081009101010111012101310141015101610171018101910201021102210231024102510261027102810291030103110321033103410351036103710381039104010411042104310441045104610471048104910501051105210531054105510561057105810591060106110621063106410651066106710681069 | <?php/** * * PHP Pro Bid $Id$ 0T5wIQDa4dJN/CnrBV0wDQkJPdnUa87QAVpitVHnQi4= * * @link        http://www.phpprobid.com * @copyright   Copyright (c) 2017 Online Ventures Software & CodeCube SRL * @license     http://www.phpprobid.com/license Commercial License * * @version     7.10 [rev.7.10.01] *//** * fees table service class */namespace Ppb\Service;use Ppb\Db\Table\Fees as FeesTable,    Ppb\Service,    Cube\Db\Expr,    Ppb\Db\Table\Row\User,    Ppb\Db\Table\Row\Category,    Ppb\Db\Table\Row\TaxType,    Ppb\Db\Table\Row\Voucher;class Fees extends AbstractService{    /**     * default calculation type     */    const DEFAULT_CALCULATION_TYPE = 'flat';    /**     * default fee type     */    const DEFAULT_TYPE = 'default';    /**     * listing setup/sale     */    const SETUP = 'setup';    const SALE = 'sale';    const HPFEAT = 'hpfeat';    const CATFEAT = 'catfeat';    const HIGHLIGHTED = 'highlighted';    const BOLD = 'bold';    const IMAGES = 'image';    const MEDIA = 'video';    const DIGITAL_DOWNLOADS = 'download';    const ADDL_CATEGORY = 'addl_category_id';    const BUYOUT = 'buyout_price';    const RESERVE = 'reserve_price';    const MAKE_OFFER = 'enable_make_offer';    const ITEM_SWAP = 'item_swap';    const SUBTITLE = 'subtitle';    /**     * user verification     */    const USER_VERIFICATION = 'user_verification';    /**     * user signup     */    const SIGNUP = 'signup';    /**     * store subscription     */    const STORE_SUBSCRIPTION = 'store_subscription';    /**     * additional constants     */    const NB_FREE_IMAGES = 'free_images';    const NB_FREE_MEDIA = 'free_media';    const NB_FREE_DOWNLOADS = 'free_downloads';    /**     *     * fees to be applied     * overridden by child classes     *     * @var array     */    protected $_fees = array();    /**     *     * types of fees that will have tiers enabled     *     * @var array     */    protected $_feesTiers = array(        self::SETUP,        self::SALE    );    /**     *     * types of fees that cannot be set as category specific     *     * @var array     */    protected $_feesNoCategory = array(        self::SIGNUP,    );    /**     *     * constants which should not have the preferred sellers reduction applied on     *     * @var array     */    protected $_additionalConstants = array(        self::NB_FREE_IMAGES,        self::NB_FREE_MEDIA,        self::NB_FREE_DOWNLOADS,    );    /**     *     * the name of the fee, used to compare against the fees tiers array     *     * @var string     */    protected $_feeName;    /**     *     * category id to calculate the fee against     * (only if custom_fees = true)     *     * @var int     */    protected $_categoryId;    /**     *     * the amount for which the fee is to be calculated     * (applies to percentage based fees)     *     * @var float     */    protected $_amount;    /**     *     * currency that the amount (if set) is in.     * if different than the site's currency, calculate an exchange rate for percentage fees     *     * @var string     */    protected $_currency;    /**     *     * currencies table service     *     * @var \Ppb\Service\Table\Currencies     */    protected $_currencies;    /**     *     * flag to disable fees     *     * @var bool     */    protected $_disableFees = false;    /**     *     * the tax that will apply to the fees     *     * @var \Ppb\Db\Table\Row\TaxType     */    protected $_taxType;    /**     *     * voucher object that will apply to the fees     *     * @var \Ppb\Db\Table\Row\Voucher     */    protected $_voucher;    /**     *     * payment completed redirect url in array or string format     *     * @var array|string     */    protected $_redirect;    /**     *     * fee type - default fees have this field as null     * will be used for listing types that will require their own fees like wanted ads etc     *     * @var string     */    protected $_type = self::DEFAULT_TYPE;    /**     *     * transaction details     *     * @var mixed     */    protected $_transactionDetails;    /**     *     * class constructor     */    public function __construct()    {        parent::__construct();        $this->setTable(            new FeesTable());    }    /**     *     * set fees array     *     * @param array $fees     *     * @return $this     */    public function setFees($fees)    {        $this->_fees = $fees;        return $this;    }    /**     *     * get fees array or the name of a certain fee if key is specified     *     * @param string $key     *     * @return array|string     */    public function getFees($key = null)    {        if (array_key_exists($key, $this->_fees)) {            return $this->_fees[$key];        }        return $this->_fees;    }    /**     *     * get fees tiers array     *     * @return array     */    public function getFeesTiers()    {        return $this->_feesTiers;    }    /**     *     * set fees tiers array     *     * @param array $feesTiers     *     * @return $this     */    public function setFeesTiers($feesTiers)    {        $this->_feesTiers = $feesTiers;        return $this;    }    /**     *     * check if a fee has tiers     *     * @param string|null $feeName     *     * @return bool     */    public function hasTiers($feeName = null)    {        if ($feeName === null) {            $feeName = $this->_feeName;        }        return (in_array($feeName, $this->_feesTiers));    }    /**     *     * get fees with no category array     *     * @return array     */    public function getFeesNoCategory()    {        return $this->_feesNoCategory;    }    /**     *     * set fees with no category array     *     * @param array $feesNoCategory     *     * @return $this     */    public function setFeesNoCategory($feesNoCategory)    {        $this->_feesNoCategory = $feesNoCategory;        return $this;    }    /**     *     * check if a fee has no categories option     *     * @param string|null $feeName     *     * @return bool     */    public function hasNoCategory($feeName = null)    {        if ($feeName === null) {            $feeName = $this->_feeName;        }        return (in_array($feeName, $this->_feesNoCategory));    }    /**     *     * get fee name     *     * @return string     * @throws \RuntimeException     */    public function getFeeName()    {        if ($this->_feeName === null) {            throw new \RuntimeException(                "A fee name is required when querying the fees table.");        }        return $this->_feeName;    }    /**     *     * set the fee name     *     * @param string $feeName     *     * @return $this     */    public function setFeeName($feeName)    {        $this->_feeName = $feeName;        return $this;    }    /**     *     * set user data     *     * @param int|string|\Ppb\Db\Table\Row\User $user     *     * @return $this     * @throws \InvalidArgumentException     */    public function setUser($user)    {        if (is_int($user) || is_string($user)) {            $userService = new Service\Users();            $user = $userService->findBy('id', $user);        }        if (!$user instanceof User) {            throw new \InvalidArgumentException("The method requires a string, an integer or an object of type \Ppb\Db\Table\Row\User.");        }        $this->_user = $user;        return $this;    }    /**     *     * get calculation amount     *     * @return float     */    public function getAmount()    {        return $this->_amount;    }    /**     *     * set calculation amount     *     * @param float $amount     *     * @return $this     */    public function setAmount($amount)    {        $this->_amount = $amount;        return $this;    }    /**     *     * get currency for the amount for which the fee is to be calculated     *     * @return string     */    public function getCurrency()    {        return $this->_currency;    }    /**     *     * set currency for the amount for which the fee is to be calculated     *     * @param string $currency     *     * @return $this     */    public function setCurrency($currency)    {        $this->_currency = $currency;        return $this;    }    /**     *     * get category id     *     * @return int     */    public function getCategoryId()    {        return $this->_categoryId;    }    /**     *     * set fee category id, but only if custom fees are enabled     *     * @param int $categoryId     *     * @return $this     */    public function setCategoryId($categoryId)    {        if ($categoryId > 0) {            $categories = new Service\Table\Relational\Categories();            $mainCategory = $categories->getRoot($categoryId);            if ($mainCategory instanceof Category) {                $categoryId = ($mainCategory->getData('custom_fees')) ? $mainCategory->getData('id') : null;            }            else {                $categoryId = null;            }        }        $this->_categoryId = $categoryId;        return $this;    }    /**     *     * get currencies table service     *     * @return \Ppb\Service\Table\Currencies     */    public function getCurrencies()    {        if (!$this->_currencies instanceof Service\Table\Currencies) {            $this->setCurrencies(                new Service\Table\Currencies());        }        return $this->_currencies;    }    /**     *     * set currencies service     *     * @param \Ppb\Service\Table\Currencies $currencies     *     * @return $this     */    public function setCurrencies(Service\Table\Currencies $currencies)    {        $this->_currencies = $currencies;        return $this;    }    /**     *     * get fees calculation flag     *     * @return bool     */    public function isDisabledFees()    {        return $this->_disableFees;    }    /**     *     * set fees calculation flag     *     * @param bool $disableFees     *     * @return $this     */    public function disableFees($disableFees = true)    {        $this->_disableFees = (bool)$disableFees;        return $this;    }    /**     *     * set tax type object     *     * @param \Ppb\Db\Table\Row\TaxType $taxType     *     * @return $this     */    public function setTaxType(TaxType $taxType)    {        $this->_taxType = $taxType;        return $this;    }    /**     *     * get tax type object     *     * @return \Ppb\Db\Table\Row\TaxType     */    public function getTaxType()    {        if (!$this->_taxType instanceof TaxType) {            $settings = $this->getSettings();            $this->setTaxType(                new TaxType(array(                    'table' => new \Ppb\Db\Table\TaxTypes(),                    'data'  => array()                )));            if ($settings['enable_tax_fees'] && $settings['tax_fees_type']) {                $taxTypesService = new Service\Table\TaxTypes();                $taxType = $taxTypesService->findBy('id', $settings['tax_fees_type']);                if ($taxType instanceof TaxType) {                    $locationsIds = \Ppb\Utility::unserialize($taxType->getData('locations_ids'));                    $address = $this->getUser()->getAddress();                    if (isset($address['country']) && isset($address['state']) && is_array($locationsIds)) {                        if (in_array($address['country'], $locationsIds) || in_array($address['state'], $locationsIds)) {                            $this->setTaxType($taxType);                        }                    }                }            }        }        return $this->_taxType;    }    /**     *     * set voucher object     *     * @param string|\Ppb\Db\Table\Row\Voucher $voucher voucher code or voucher object     *     * @return $this     */    public function setVoucher($voucher)    {        if (!$voucher instanceof Voucher) {            $vouchersService = new Service\Vouchers();            $voucher = $vouchersService->findBy($voucher);        }        $this->_voucher = $voucher;        return $this;    }    /**     *     * get voucher object     *     * @return \Ppb\Db\Table\Row\Voucher     */    public function getVoucher()    {        return $this->_voucher;    }    /**     *     * set redirect params     *     * @param array|string $redirect     *     * @return $this     */    public function setRedirect($redirect)    {        $this->_redirect = $redirect;        return $this;    }    /**     *     * get redirect params     *     * @return array|string     */    public function getRedirect()    {        return $this->_redirect;    }    /**     *     * set listing type     *     * @param string $type     *     * @return $this     */    public function setType($type)    {        $this->_type = $type;        return $this;    }    /**     *     * get listing type     *     * @return string     */    public function getType()    {        return $this->_type;    }    /**     *     * get transaction details     *     * @return mixed     */    public function getTransactionDetails()    {        return $this->_transactionDetails;    }    /**     *     * set transaction details     *     * @param mixed $transactionDetails     *     * @return $this     */    public function setTransactionDetails($transactionDetails)    {        $this->_transactionDetails = $transactionDetails;        return $this;    }    /**     *     * get the amount of a certain fee     * calculates based on preferred seller feature     *     * @param string $name     * @param float  $amount     * @param int    $categoryId     * @param null   $currency     *     * @return float|null       return the fee amount or null if no fee applies for the selected action     */    public function getFeeAmount($name = null, $amount = null, $categoryId = null, $currency = null)    {        if ($this->isDisabledFees()) {            return null;        }        if ($name === null) {            $name = $this->getFeeName();        }        if ($amount === null) {            $amount = $this->getAmount();        }        if ($categoryId !== null) {            $this->setCategoryId($categoryId);        }        $categoryId = $this->getCategoryId();        if ($currency !== null) {            $this->setCurrency($currency);        }        $currency = $this->getCurrency();        $select = $this->_table->select(array('amount', 'calculation_type'))            ->where("name = ?", $name)            ->where("type = ?", $this->getType());        if (in_array($name, $this->_feesTiers) && $amount !== null) {            $amountConverted = $this->getCurrencies()->convertAmount($amount, $currency);            $select->where("tier_from < ?", $amountConverted)                ->where("tier_to >= ?", $amountConverted);        }        if ($categoryId !== null) {            $select->where("category_id = ?", $categoryId);        }        else {            $select->where("category_id IS NULL");        }        $row = $this->_table->fetchRow($select);        if ($row !== null) {            if ($row['calculation_type'] == 'percent') {                $amount = $row['amount'] * $amount / 100;                $amount = $this->getCurrencies()->convertAmount($amount, $currency);            }            else {                $amount = $row['amount'];            }            if (!in_array($name, $this->_additionalConstants)) {                $amount = $this->_applyPreferredSellersReduction($amount);                $amount = $this->_addTax($amount);            }            return $amount;//            return $this->_applyVoucher($amount, $settings['currency']);        }        return null;    }    /**     *     * save data in the fees table     *     * @param array $data     *     * @return $this     */    public function save(array $data)    {        $categoryId = null;        $calculationType = 'flat';        $type = 'default';        $feeName = $this->getFeeName();        if (isset($data['category_id'])) {            $categoryId = intval($data['category_id']);            unset($data['category_id']);        }        if (isset($data['calculation_type'])) {            if (!is_array($data['calculation_type'])) {                $calculationType = $data['calculation_type'];                unset($data['calculation_type']);            }        }        if (isset($data['sale_fee_payer'])) {            $settingsService = new Settings();            $settingsService->save(array(                'sale_fee_payer' => $data['sale_fee_payer'],            ));        }        if (isset($data['type'])) {            $type = $data['type'];            unset($data['type']);        }        $table = $this->getTable();        if ($this->hasTiers()) {            if (isset($data['tier_from'])) {                foreach ($data['tier_from'] as $key => $tierFrom) {                    if (!empty($data['amount'][$key])) {                        $row = $where = null;                        if (!empty($data['id'][$key])) {                            $where = $table->getAdapter()->quoteInto('id = ?', intval($data['id'][$key]));                            $row = $this->getTable()->fetchRow($where);                        }                        $array = array(                            'name'             => $feeName,                            'type'             => $type,                            'amount'           => $data['amount'][$key],                            'calculation_type' => $data['calculation_type'][$key],                            'category_id'      => (!empty($categoryId)) ? $categoryId : new Expr('null'),                            'tier_from'        => $data['tier_from'][$key],                            'tier_to'          => $data['tier_to'][$key],                        );                        if (count($row) > 0) {                            $table->update($array, $where);                        }                        else {                            $table->insert($array);                        }                    }                }            }        }        else {            foreach ($data as $key => $value) {                $where = $table->select()                    ->where('name = ?', $key)                    ->where('type = ?', $type);                if ($categoryId) {                    $where->where('category_id = ?', $categoryId);                }                else {                    $where->where('category_id IS NULL');                }                $row = $table->fetchRow($where);                $insert = array(                    'amount'           => $value,                    'calculation_type' => $calculationType);                if (count($row) > 0) {                    $table->update($insert, "id = '{$row['id']}'");                }                else {                    $insert['name'] = $key;                    if (isset($type)) {                        $insert['type'] = $type;                    }                    if ($categoryId) {                        $insert['category_id'] = $categoryId;                    }                    $table->insert($insert);                }            }        }        return $this;    }    /**     *     * get fees data for usage in admin setup forms     *     * @param string  $name       the name of the fee     * @param integer $categoryId id of the category     * @param string  $type       fee/listing type     *     * @return array     */    public function getData($name = null, $categoryId = null, $type = null)    {        if ($name === null) {            $name = $this->getFeeName();        }        if ($type !== null) {            $this->setType($type);        }        $type = $this->getType();        $select = $this->_table->select()            ->where('type = ?', $type);        if ($name !== null) {            $select->where("name = ?", $name);        }        if ($categoryId) {            $select->where("category_id = ?", $categoryId);        }        else {            $select->where("category_id IS NULL");        }        $data = $this->fetchAll($select)->toArray();        // if data = 1 then get all non tiered fields plus a 'type' field        if ($this->hasTiers() !== true) {            $result['fee_type'] = (isset($data[0]['calculation_type'])) ? $data[0]['calculation_type'] : self::DEFAULT_CALCULATION_TYPE;            $select = $this->_table->select()                ->where('type = ?', $type);            if ($categoryId) {                $select->where("category_id = ?", $categoryId);            }            else {                $select->where("category_id IS NULL");            }            $rows = $this->fetchAll($select);            foreach ($rows as $row) {                $result[$row['name']] = $row['amount'];            }            $data = $result;        }        $data['category_id'] = $categoryId;        return $data;    }    /**     *     * delete table data by id - fees tiers only     *     * @param array $data     *     * @return int          The number of affected rows.     */    public function delete(array $data)    {        $data = array_filter(            array_values($data));        if (count($data) > 0) {            return $this->_table->delete("id IN (" . implode(',', $data) . ")");        }        return null;    }    /**     *     * add tax to a certain value, and return the rounded value     *     * @param float $value     *     * @return float     */    protected function _addTax($value)    {        $value += $value * $this->getTaxType()->getData('amount') / 100;        return $this->_roundNumber($value);    }    /**     *     * apply voucher to a certain value and currency and return rounded value     *     * @param float  $value     * @param string $currency     *     * @return float     */    protected function _applyVoucher($value, $currency)    {        if (($voucher = $this->getVoucher()) instanceof Voucher) {            $value = $voucher->apply($value, $currency);        }        return $this->_roundNumber($value);    }    /**     *     * apply preferred sellers reduction, and return rounded value     *     * @param $value     *     * @return float     */    protected function _applyPreferredSellersReduction($value)    {        $settings = $this->getSettings();        if ($settings['preferred_sellers'] && $this->_user['preferred_seller']) {            $value = ($value * (1 - $settings['preferred_sellers_reduction'] / 100));        }        return $this->_roundNumber($value);    }    /**     *     * requires an array of data and     * makes the required modifications to the affected tables     *     * functionality defined in child classes     *     * @param bool  $ipn  true if payment is completed, false otherwise     * @param array $post data needed by the method     */    public function callback($ipn, array $post)    {    }    /**     *     * get the signup fee value (tax included)     *     * functionality defined in child classes     *     * @return void     */    public function getTotalAmount()    {    }}
 |