| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569 | 
							- <?php
 
- /**
 
-  *
 
-  * PHP Pro Bid $Id$ o7sbe8CfJji4DIa8b0Lloyp/chIXnE+At24rYq22Ha0=
 
-  *
 
-  * @link        https://www.phpprobid.com
 
-  * @copyright   Copyright (c) 2017 Online Ventures Software & CodeCube SRL
 
-  * @license     https://www.phpprobid.com/license Commercial License
 
-  *
 
-  * @version     7.10 [rev.7.10.01]
 
-  */
 
- /**
 
-  * sales table service class
 
-  * creates/edits sales (a sale can include one ore more listings in it)
 
-  */
 
- namespace Ppb\Service;
 
- use Ppb\Db\Table,
 
-     Cube\Db\Expr,
 
-     Ppb\Service,
 
-     Ppb\Service\Table\SalesListings as SalesListingsTableService,
 
-     Ppb\Model\Shipping as ShippingModel,
 
-     Ppb\Db\Table\Row\Sale as SaleModel,
 
-     Ppb\Db\Table\Row\Listing as ListingModel,
 
-     Ppb\Db\Table\Row\UserAddressBook as UserAddressBookModel;
 
- class Sales extends AbstractService
 
- {
 
-     /**
 
-      *
 
-      * the id of the sale row updated/created by a save operation
 
-      *
 
-      * @var int
 
-      */
 
-     protected $_saleId;
 
-     /**
 
-      *
 
-      * sales listings table service
 
-      *
 
-      * @var \Ppb\Service\Table\SalesListings
 
-      */
 
-     protected $_salesListings;
 
-     /**
 
-      *
 
-      * listings table service class
 
-      *
 
-      * @var \Ppb\Service\Listings
 
-      */
 
-     protected $_listings = null;
 
-     /**
 
-      *
 
-      * reputation table service class
 
-      *
 
-      * @var \Ppb\Service\Reputation
 
-      */
 
-     protected $_reputation = null;
 
-     /**
 
-      *
 
-      * class constructor
 
-      */
 
-     public function __construct()
 
-     {
 
-         parent::__construct();
 
-         $this->setTable(
 
-             new Table\Sales());
 
-     }
 
-     /**
 
-      *
 
-      * set sale id
 
-      *
 
-      * @param int $saleId
 
-      *
 
-      * @return $this
 
-      */
 
-     public function setSaleId($saleId)
 
-     {
 
-         $this->_saleId = $saleId;
 
-         return $this;
 
-     }
 
-     /**
 
-      *
 
-      * get sale id
 
-      *
 
-      * @return int
 
-      */
 
-     public function getSaleId()
 
-     {
 
-         return $this->_saleId;
 
-     }
 
-     /**
 
-      *
 
-      * get sales listings table service
 
-      *
 
-      * @return \Ppb\Service\Table\SalesListings
 
-      */
 
-     public function getSalesListings()
 
-     {
 
-         if (!$this->_salesListings instanceof SalesListingsTableService) {
 
-             $this->setSalesListings(
 
-                 new SalesListingsTableService());
 
-         }
 
-         return $this->_salesListings;
 
-     }
 
-     /**
 
-      *
 
-      * set sales listings table
 
-      *
 
-      * @param \Ppb\Service\Table\SalesListings $salesListings
 
-      *
 
-      * @return \Ppb\Service\Sales
 
-      */
 
-     public function setSalesListings(SalesListingsTableService $salesListings)
 
-     {
 
-         $this->_salesListings = $salesListings;
 
-         return $this;
 
-     }
 
-     /**
 
-      *
 
-      * get listings table service class
 
-      *
 
-      * @return \Ppb\Service\Listings
 
-      */
 
-     public function getListings()
 
-     {
 
-         if (!$this->_listings instanceof Service\Listings) {
 
-             $this->setListings(
 
-                 new Service\Listings());
 
-         }
 
-         return $this->_listings;
 
-     }
 
-     /**
 
-      *
 
-      * set listings table service class
 
-      *
 
-      * @param \Ppb\Service\Listings $listings
 
-      *
 
-      * @return \Ppb\Service\Sales
 
-      */
 
-     public function setListings(Service\Listings $listings)
 
-     {
 
-         $this->_listings = $listings;
 
-         return $this;
 
-     }
 
-     /**
 
-      *
 
-      * get reputation table service class
 
-      *
 
-      * @return \Ppb\Service\Reputation
 
-      */
 
-     public function getReputation()
 
-     {
 
-         if (!$this->_reputation instanceof Service\Reputation) {
 
-             $this->setReputation(
 
-                 new Service\Reputation());
 
-         }
 
-         return $this->_reputation;
 
-     }
 
-     /**
 
-      *
 
-      * set reputation table service class
 
-      *
 
-      * @param \Ppb\Service\Reputation $reputation
 
-      *
 
-      * @return \Ppb\Service\Sales
 
-      */
 
-     public function setReputation(Service\Reputation $reputation)
 
-     {
 
-         $this->_reputation = $reputation;
 
-         return $this;
 
-     }
 
-     /**
 
-      *
 
-      * create or edit a sale (invoice). when creating a sale, also add rows in
 
-      * the sales listings table. when updating a sale, modify the sale id of the involved sales
 
-      * listings, and then remove any sales that do not contain any listings.
 
-      *
 
-      * calculates the postage when creating or editing the invoice
 
-      * the postage will be calculated based on the "postage_id" key, or the first option in the postage array will
 
-      * be used if the "postage_id" key doesnt correspond to a key in the results array
 
-      *
 
-      * will also add the calculated or edited insurance amount if "apply_insurance" is checked.
 
-      *
 
-      * an element from the listings array must include:
 
-      *      'listing' => object of type listing
 
-      *      'price' => the price the listing has been sold for
 
-      *      'quantity' => the quantity sold
 
-      *
 
-      * @param array $post
 
-      *
 
-      * @return \Ppb\Service\Sales
 
-      * @throws \InvalidArgumentException
 
-      */
 
-     public function save($post)
 
-     {
 
-         $sale = null;
 
-         $pending = (!empty($post['pending'])) ? $post['pending'] : 0;
 
-         if ((empty($post['buyer_id']) || empty($post['user_token'])) && empty($post['seller_id'])) {
 
-             throw new \InvalidArgumentException("The 'buyer_id'/'user_token' and 'seller_id' keys need to be specified when creating/editing a sale/shopping cart");
 
-         }
 
-         $data = $this->_prepareSaveData($post);
 
-         if (array_key_exists('id', $data)) {
 
-             $sale = $this->findBy('id', $data['id']);
 
-             unset($data['id']);
 
-         }
 
-         $newSale = false;
 
-         if (count($sale) > 0) {
 
-             $data['updated_at'] = new Expr('now()');
 
-             $sale->save($data);
 
-             $id = $sale['id'];
 
-         }
 
-         else {
 
-             $data['created_at'] = $data['updated_at'] = new Expr('now()');
 
-             $this->_table->insert($data);
 
-             $id = $this->_table->getAdapter()->lastInsertId();
 
-             $listing = $this->getListings()->findBy('id', $post['listings'][0]['listing_id']);
 
-             /** @var \Ppb\Db\Table\Row\Sale $sale */
 
-             $sale = $this->findBy('id', $id);
 
-             $sale->saveSaleData(array(
 
-                 'currency'       => $listing['currency'],
 
-                 'country'        => $listing['country'],
 
-                 'state'          => $listing['state'],
 
-                 'address'        => $listing['address'],
 
-                 'pickup_options' => $listing['pickup_options'],
 
-                 'apply_tax'      => $listing['apply_tax'],
 
-             ));
 
-             $newSale = true;
 
-         }
 
-         $this->setSaleId($id);
 
-         if (isset($post['listings'])) {
 
-             foreach ($post['listings'] as $data) {
 
-                 $data['sale_id'] = $id;
 
-                 // for shopping carts, don't allow an item to be added to a cart more than once.
 
-                 if ($pending) {
 
-                     $salesListingsTable = $this->getSalesListings()->getTable();
 
-                     $select = $salesListingsTable->select('id')
 
-                         ->where("listing_id = ?", $data['listing_id'])
 
-                         ->where("sale_id = ?", $data['sale_id']);
 
-                     if (!empty($data['product_attributes'])) {
 
-                         $select->where("product_attributes = ?", $data['product_attributes']);
 
-                     }
 
-                     $saleListing = $salesListingsTable->fetchRow($select);
 
-                     if ($saleListing) {
 
-                         $data['id'] = $saleListing->getData('id');
 
-                     }
 
-                 }
 
-                 $this->getSalesListings()->save($data);
 
-             }
 
-         }
 
-         if (!$pending) {
 
-             $postageId = (!empty($post['postage_id'])) ? $post['postage_id'] : 0;
 
-             $applyInsurance = (!empty($post['apply_insurance'])) ? $post['apply_insurance'] : 0;
 
-             $this->_processPostageFields($sale, $post, $postageId, $applyInsurance);
 
-             if ($newSale || isset($post['checkout'])) {
 
-                 $this->_processPostSaleActions();
 
-             }
 
-         }
 
-         return $this;
 
-     }
 
-     /**
 
-      *
 
-      * delete a sale (and all sale listings attached)
 
-      *
 
-      * @param int $id sale id
 
-      *
 
-      * @return int the number of affected rows
 
-      */
 
-     public function delete($id)
 
-     {
 
-         return $this->_table->delete(
 
-             $this->_table->getAdapter()->quoteInto('id = ?', $id));
 
-     }
 
-     /**
 
-      *
 
-      * if a sale is complete, do the following actions:
 
-      *
 
-      * - save sale transaction to accounting table
 
-      * - update the payer's balance if in account mode
 
-      * - prepare reputation rows for each listing in the sale
 
-      * - close any listings from the sale which had their quantity expired and update the quantity field in the listings table
 
-      * - add the tax rate to the sale if tax applies
 
-      * - set 'expires_at' field if force payment is enabled
 
-      * - email seller and buyer
 
-      * - V7.5: if sale total is 0.00 then flag_payment is set to 1
 
-      * - V7.8: if auto relist if sold is enabled: relist
 
-      *
 
-      * @return $this
 
-      */
 
-     protected function _processPostSaleActions()
 
-     {
 
-         /** @var \Ppb\Db\Table\Row\Sale $sale */
 
-         $sale = $this->findBy('id', $this->getSaleId());
 
-         $settings = $this->getSettings();
 
-         /** @var \Ppb\Db\Table\Row\User $seller */
 
-         $seller = $sale->findParentRow('\Ppb\Db\Table\Users', 'Seller');
 
-         /** @var \Ppb\Db\Table\Row\User $buyer */
 
-         $buyer = $sale->findParentRow('\Ppb\Db\Table\Users', 'Buyer');
 
-         /** @var \Ppb\Db\Table\Row\User $payer */
 
-         $payer = ($settings['sale_fee_payer'] == 'buyer') ? $buyer : $seller;
 
-         $saleTransactionService = new Service\Fees\SaleTransaction(
 
-             $sale, $payer
 
-         );
 
-         $saleTransactionFees = $saleTransactionService->calculate();
 
-         $totalAmount = $saleTransactionService->getTotalAmount();
 
-         $accountingService = new Service\Accounting();
 
-         if ($payer->userPaymentMode() == 'account') {
 
-             $payer->updateBalance(
 
-                 $totalAmount);
 
-             $sale->updateActive();
 
-             $accountingService->setRefundFlag(\Ppb\Db\Table\Row\Accounting::REFUND_ALLOWED);
 
-         }
 
-         else if ($totalAmount <= 0) {
 
-             $sale->updateActive();
 
-         }
 
-         $accountingService->setUserId($payer['id'])
 
-             ->setSaleId($this->getSaleId())
 
-             ->saveMultiple($saleTransactionFees);
 
-         $reputation = $this->getReputation();
 
-         $voucher = $sale->getVoucher();
 
-         if ($voucher !== null) {
 
-             $voucher->updateUses();
 
-         }
 
-         $salesListings = $sale->findDependentRowset('\Ppb\Db\Table\SalesListings');
 
-         $listingIds = array();
 
-         $taxCalculated = false;
 
-         /** @var \Ppb\Db\Table\Row\SaleListing $saleListing */
 
-         foreach ($salesListings as $saleListing) {
 
-             /** @var \Ppb\Db\Table\Row\Listing $listing */
 
-             $listing = $saleListing->findParentRow('\Ppb\Db\Table\Listings');
 
-             // get tax rate - retrieved based on the first listing in the sale
 
-             if ($taxCalculated !== true) {
 
-                 if (($taxType = $listing->getTaxType($buyer, $sale['billing_address_id'])) !== false) {
 
-                     $sale->save(array(
 
-                         'tax_rate' => $taxType->getData('amount')
 
-                     ));
 
-                 }
 
-                 $taxCalculated = true;
 
-             }
 
-             $quantity = $listing->updateQuantity($saleListing['quantity'], $saleListing['product_attributes'], ListingModel::SUBTRACT);
 
-             if ($quantity == 0) {
 
-                 $listing->close();
 
-             }
 
-             if ($voucher !== null) {
 
-                 $price = $voucher->apply($saleListing->price(), $sale['currency'], $listing['id']);
 
-                 $saleListing->save(array(
 
-                     'price' => $price,
 
-                 ));
 
-             }
 
-             // prepare reputation row: seller => buyer
 
-             $reputation->save(array(
 
-                 'user_id'         => $sale['buyer_id'],
 
-                 'poster_id'       => $sale['seller_id'],
 
-                 'sale_listing_id' => $saleListing['id'],
 
-                 'listing_name'    => $listing['name'],
 
-                 'reputation_type' => Reputation::PURCHASE,
 
-             ));
 
-             // prepare reputation row: buyer => seller
 
-             $reputation->save(array(
 
-                 'user_id'         => $sale['seller_id'],
 
-                 'poster_id'       => $sale['buyer_id'],
 
-                 'sale_listing_id' => $saleListing['id'],
 
-                 'listing_name'    => $listing['name'],
 
-                 'reputation_type' => Reputation::SALE,
 
-             ));
 
-             // relist only if the listing is closed
 
-             if ($quantity == 0) {
 
-                 $listingIds[] = $listing['id'];
 
-             }
 
-         }
 
-         if (count($listingIds) > 0) {
 
-             $select = $this->getListings()->getTable()->select()
 
-                 ->forUpdate()
 
-                 ->where('id IN (?)', $listingIds);
 
-             $this->getListings()->fetchAll($select)
 
-                 ->setAutomatic(true)
 
-                 ->relist();
 
-         }
 
-         if ($seller->isForcePayment()) {
 
-             $sale->setExpiresFlag();
 
-         }
 
-         $sale->clearSalesListings();
 
-         if ($sale->calculateTotal() <= 0) {
 
-             $sale->save(array(
 
-                 'flag_payment' => 1,
 
-             ));
 
-             $sale->setExpiresFlag(true);
 
-         }
 
-         $mail = new \Members\Model\Mail\User();
 
-         $mail->saleBuyerNotification($sale, $buyer)->send();
 
-         $mail->saleSellerNotification($sale, $seller)->send();
 
-         return $this;
 
-     }
 
-     /**
 
-      *
 
-      * process postage fields - calculate and save postage costs
 
-      * the shipping_address_id field will always need to be set in the sale row
 
-      * shipping needs to be enabled for this
 
-      *
 
-      *
 
-      * @param \Ppb\Db\Table\Row\Sale $sale
 
-      * @param array                  $post
 
-      * @param int                    $postageId
 
-      * @param int                    $applyInsurance
 
-      *
 
-      * @return $this
 
-      */
 
-     protected function _processPostageFields(SaleModel $sale, $post, $postageId, $applyInsurance)
 
-     {
 
-         /** @var \Ppb\Db\Table\Row\User $seller */
 
-         $seller = $sale->findParentRow('\Ppb\Db\Table\Users', 'Seller');
 
-         /** @var \Ppb\Db\Table\Row\User $buyer */
 
-         $buyer = $sale->findParentRow('\Ppb\Db\Table\Users', 'Buyer');
 
-         $shippingAddress = $buyer->getAddress($sale['shipping_address_id']);
 
-         $shippingModel = new ShippingModel($seller);
 
-         $shippingModel->setLocationId($shippingAddress['country'])
 
-             ->setPostCode($shippingAddress['zip_code']);
 
-         $salesListings = $sale->findDependentRowset('\Ppb\Db\Table\SalesListings');
 
-         /** @var \Ppb\Db\Table\Row\SaleListing $saleListing */
 
-         foreach ($salesListings as $saleListing) {
 
-             $shippingModel->addData(
 
-                 $saleListing->findParentRow('\Ppb\Db\Table\Listings'), $saleListing['quantity']);
 
-         }
 
-         $result = array();
 
-         try {
 
-             $result = $shippingModel->calculatePostage();
 
-         } catch (\RuntimeException $e) {
 
-         }
 
-         $shippingDetails = (!empty($result[$postageId])) ? $result[$postageId] : reset($result);
 
-         // TODO: only the seller or admin can enter a custom amount for the postage and insurance amounts
 
-         $insuranceAmount = (isset($post['insurance_amount'])) ? $post['insurance_amount'] : $shippingModel->calculateInsurance();
 
-         $postageAmount = (isset($post['postage_amount'])) ? $post['postage_amount'] : $shippingDetails['price'];
 
-         $sale->saveSaleData(array(
 
-             'postage_id'      => $postageId,
 
-             'apply_insurance' => $applyInsurance,
 
-             'postage'         => $shippingDetails,
 
-         ));
 
-         $postageData = array(
 
-             'postage_amount'   => (double)$postageAmount,
 
-             'insurance_amount' => (double)$insuranceAmount
 
-         );
 
-         if ($shippingAddress instanceof UserAddressBookModel) {
 
-             if ($shippingAddressId = $shippingAddress->getData('id')) {
 
-                 $postageData['shipping_address_id'] = $shippingAddressId;
 
-             }
 
-         }
 
-         $sale->save($postageData);
 
-         return $this;
 
-     }
 
-     /**
 
-      *
 
-      * get all carts of a certain user based on his token
 
-      *
 
-      * @var string $userToken
 
-      * @return array
 
-      */
 
-     public function getMultiOptions($userToken)
 
-     {
 
-         $data = array();
 
-         $select = $this->getTable()->select()
 
-             ->where('pending = ?', 1)
 
-             ->where('user_token = ?', $userToken)
 
-             ->order(array('updated_at DESC', 'created_at DESC'));
 
-         $rowset = $this->fetchAll($select);
 
-         /** @var \Ppb\Db\Table\Row\Sale $row */
 
-         foreach ($rowset as $row) {
 
-             /** @var \Ppb\Db\Table\Row\User $seller */
 
-             $seller = $row->findParentRow('\Ppb\Db\Table\Users', 'Seller');
 
-             $data[(string)$row['id']] = '[ ' . $row['id'] . ' ] ' .
 
-                 (($seller->storeStatus(true) == true) ?
 
-                     $seller->getData('store_name') : $seller->getData('username'));
 
-         }
 
-         return $data;
 
-     }
 
- }
 
 
  |