Exemplo n.º 1
0
 public function onBeforeWrite()
 {
     parent::onBeforeWrite();
     if (!$this->Currency) {
         $this->Currency = ShopConfig::current_shop_config()->BaseCurrency;
     }
 }
 public function Amount($order)
 {
     $shopConfig = ShopConfig::current_shop_config();
     $amount = new Price();
     $amount->setAmount($order->SubTotal()->getAmount() * ($this->Rate / 100));
     $amount->setCurrency($shopConfig->BaseCurrency);
     $amount->setSymbol($shopConfig->BaseCurrencySymbol);
     return $amount;
 }
Exemplo n.º 3
0
 /**
  * Set value of the field with explicitly formatted numbers.
  * 
  * @param mixed $val
  */
 public function setValue($val)
 {
     if (!$val) {
         $val = 0.0;
     }
     $shopConfig = ShopConfig::current_shop_config();
     $precision = $shopConfig->BaseCurrencyPrecision;
     $this->value = number_format((double) preg_replace('/[^0-9.\\-]/', '', $val), $precision);
     return $this;
 }
 public function Amount()
 {
     // TODO: Multi currency
     $shopConfig = ShopConfig::current_shop_config();
     $amount = new Price();
     $amount->setAmount($this->Price);
     $amount->setCurrency($shopConfig->BaseCurrency);
     $amount->setSymbol($shopConfig->BaseCurrencySymbol);
     $this->extend('updateAmount', $amount);
     return $amount;
 }
Exemplo n.º 5
0
 /**
  * Returns amount reduced by $this->Measure.
  *
  * @param Price|number $amount
  * @param $discount
  * @return Price
  */
 public function discountedAmount($forAmount)
 {
     if ($this->owner->UsePriceColumn) {
         $price = new Price();
         $price->setCurrency(ShopConfig::current_shop_config()->BaseCurrency);
         if ($forAmount instanceof Money) {
             $price->setAmount($forAmount->getAmount());
         } else {
             $price->setAmount($forAmount);
         }
         $price->setAmount(Zend_Locale_Math::Sub($price->getAmount(), $this->owner->Measure, 10));
         return $price;
     }
     return null;
 }
 /**
  * Get the form fields for the OrderForm.
  * 
  * @return FieldList List of fields
  */
 public function getFormFields()
 {
     $fields = new FieldList();
     $field = new XeroTaxModifierField($this, _t('Xero.TAX', 'Tax'));
     $shopConfig = ShopConfig::current_shop_config();
     $amount = new Price();
     $amount->setAmount($this->Price);
     $amount->setCurrency($shopConfig->BaseCurrency);
     $amount->setSymbol($shopConfig->BaseCurrencySymbol);
     $field->setAmount($amount);
     $fields->push($field);
     if (!$fields->exists()) {
         Requirements::javascript('swipestripe-flatfeetax/javascript/FlatFeeTaxModifierField.js');
     }
     return $fields;
 }
Exemplo n.º 7
0
 /**
  * Iterate through extensions to ask them to calculate the new amount.
  *
  * @param $forAmount
  * @return mixed|Price
  */
 public function discountedAmount($forAmount)
 {
     $price = new Price();
     if ($values = $this->extend('discountedAmount', $forAmount)) {
         $price = reset($values);
         if (!$price->getCurrency()) {
             $price->setCurrency(ShopConfig::current_shop_config()->BaseCurrency);
         }
     } else {
         if ($forAmount instanceof Money) {
             $price->setAmount($forAmount->getAmount());
             $price->setCurrency($forAmount->getCurrency());
         } else {
             $price->setAmount($forAmount);
             $price->setCurrency(ShopConfig::current_shop_config()->BaseCurrency);
         }
     }
     return $price;
 }
 /**
  * Calculate the tax component based on tax rates for the items and modifications in the order
  * 
  * @param  Order  $order
  * @return Price  The tax amount for the order
  */
 public function calculate(Order $order)
 {
     $taxAmount = 0;
     $shopConfig = ShopConfig::current_shop_config();
     $items = $order->Items();
     if ($items && $items->exists()) {
         foreach ($items as $item) {
             $taxAmount += $item->Total()->getAmount() * ($item->XeroTaxRate / 100);
         }
     }
     $mods = $order->Modifications();
     if ($mods && $mods->exists()) {
         foreach ($mods as $mod) {
             $taxAmount += $mod->Amount()->getAmount() * ($mod->XeroTaxRate / 100);
         }
     }
     $amount = new Price();
     $amount->setAmount($taxAmount);
     $amount->setCurrency($shopConfig->BaseCurrency);
     $amount->setSymbol($shopConfig->BaseCurrencySymbol);
     return $amount;
 }
 /**
  * Returns the amount minus percentage from Measure.
  *
  * @param Price $forAmount
  * @return Price
  */
 public function discountedAmount($forAmount)
 {
     if ($this->owner->UsePercentageColumn) {
         $price = new Price();
         if ($forAmount instanceof Money) {
             $price->setAmount($forAmount->getAmount());
             $price->setCurrency($forAmount->getCurrency());
         } else {
             $price->setAmount($forAmount);
             $price->setCurrency(ShopConfig::current_shop_config()->BaseCurrency);
         }
         // only recalculate if there is a percentage
         if ($this->owner->Measure != 0) {
             $original = $price->getAmount();
             $percentage = Zend_Locale_Math::Div($this->owner->Measure, self::OneHundred, 10);
             $difference = Zend_Locale_Math::Mul($original, $percentage, 10);
             $price->setAmount(Zend_Locale_Math::Sub($original, $difference, 10));
         }
         return $price;
     }
     return null;
 }
Exemplo n.º 10
0
 /**
  * Delete abandoned carts according to the Order timeout. This will release the stock 
  * in the carts back to the shop. Can be run from a cron job task, also run on Product, Cart and
  * Checkout pages so that cron job is not necessary.
  * 
  * @return Void
  */
 public static function delete_abandoned()
 {
     $shopConfig = ShopConfig::current_shop_config();
     $timeout = DateInterval::createFromDateString($shopConfig->CartTimeout . ' ' . $shopConfig->CartTimeoutUnit);
     $ago = new DateTime();
     $ago->sub($timeout);
     //Get orders that were last active over x ago according to shop config cart lifetime
     $orders = Order::get()->where("\"Order\".\"LastActive\" < '" . $ago->format('Y-m-d H:i:s') . "' AND \"Order\".\"Status\" = 'Cart' AND \"Payment\".\"ID\" IS NULL")->leftJoin('Payment', "\"Payment\".\"OrderID\" = \"Order\".\"ID\"");
     if ($orders && $orders->exists()) {
         foreach ($orders as $order) {
             $order->delete();
             $order->destroy();
         }
     }
 }
 /**
  * Create invoices by generating XML and sending to Xero.
  * 
  * @param  XeroOAuth $XeroOAuth Connection to Xero
  */
 private function createInvoices($XeroOAuth)
 {
     $xeroConnection = clone $XeroOAuth;
     $shopConfig = ShopConfig::current_shop_config();
     $invoicePrefix = $this->config()->invoicePrefix;
     $defaultAccountCode = $this->config()->defaultAccountCode;
     $invoices = array();
     // Orders that have not been sent to Xero and are completed
     $orders = Order::get()->where(" \"XeroInvoiceID\" IS NULL AND \"Status\" != 'Cart'");
     $i = 0;
     if ($orders && $orders->exists()) {
         foreach ($orders as $order) {
             $invoices[$i]['Invoice'] = array('Type' => 'ACCREC', 'InvoiceNumber' => $invoicePrefix . $order->ID, 'Contact' => array('Name' => $order->Member()->getName()), 'Date' => $order->OrderedOn, 'DueDate' => $order->OrderedOn, 'Status' => 'AUTHORISED', 'LineAmountTypes' => 'Exclusive', 'CurrencyCode' => $shopConfig->BaseCurrency);
             // Line items for each item in the order
             $items = $order->Items();
             if ($items && $items->exists()) {
                 foreach ($items as $item) {
                     $object = $item->Variation() ? $item->Variation() : $item->Product();
                     $description = $object->Title;
                     if ($object instanceof Variation) {
                         $description = strip_tags($object->Product()->Title . ' ' . $object->SummaryOfOptions());
                     }
                     $invoices[$i]['Invoice']['LineItems'][]['LineItem'] = array('Description' => $description, 'Quantity' => $item->Quantity, 'UnitAmount' => $item->Price, 'AccountCode' => $defaultAccountCode, 'TaxType' => $item->XeroTaxType);
                 }
             }
             // Line items for each order modifier
             $modifications = $order->Modifications();
             if ($modifications && $modifications->exists()) {
                 foreach ($modifications as $modification) {
                     if ($modification->XeroTaxType) {
                         $invoices[$i]['Invoice']['LineItems'][]['LineItem'] = array("Description" => $modification->Description, "Quantity" => 1, "UnitAmount" => $modification->Amount()->getAmount(), "AccountCode" => $defaultAccountCode, 'TaxType' => $modification->XeroTaxType);
                     }
                 }
             }
             $i++;
         }
     }
     // If no data do not send to Xero
     if (empty($invoices)) {
         return;
     }
     $invoicesXML = new SimpleXMLElement("<Invoices></Invoices>");
     $this->arrayToXML($invoices, $invoicesXML);
     $xml = $invoicesXML->asXML();
     $response = $xeroConnection->request('POST', $xeroConnection->url('Invoices', 'core'), array(), $xml);
     if ($xeroConnection->response['code'] == 200) {
         $invoices = $xeroConnection->parseResponse($xeroConnection->response['response'], $xeroConnection->response['format']);
         echo count($invoices->Invoices[0]) . " invoice(s) created in this Xero organisation.";
         // Update Orders that have been pushed to Xero so that they are not sent again
         foreach ($invoices->Invoices->Invoice as $invoice) {
             $order = Order::get()->filter('ID', str_replace($invoicePrefix, '', $invoice->InvoiceNumber->__toString()))->first();
             if ($order && $order->exists()) {
                 $order->XeroInvoiceID = $invoice->InvoiceID->__toString();
                 $order->write();
             }
         }
     } else {
         echo 'Error: ' . $xeroConnection->response['response'] . PHP_EOL;
         SS_Log::log(new Exception(print_r($xeroConnection, true)), SS_Log::NOTICE);
     }
 }
Exemplo n.º 12
0
 /**
  * Check that current product variation is valid
  *
  * @param Array $data Submitted data
  * @return Boolean Returns TRUE if the submitted data is valid, otherwise FALSE.
  */
 public function php($data)
 {
     $valid = parent::php($data);
     $fields = $this->form->Fields();
     //Check that variation exists if necessary
     $form = $this->form;
     $request = $this->form->getRequest();
     //Get product variations from options sent
     //TODO refactor this
     $productVariations = new ArrayList();
     $options = $request->postVar('Options');
     $product = DataObject::get_by_id($data['ProductClass'], $data['ProductID']);
     $variations = $product ? $product->Variations() : new ArrayList();
     if ($variations && $variations->exists()) {
         foreach ($variations as $variation) {
             $variationOptions = $variation->Options()->map('AttributeID', 'ID')->toArray();
             if ($options == $variationOptions && $variation->isEnabled()) {
                 $productVariations->push($variation);
             }
         }
     }
     if ((!$productVariations || !$productVariations->exists()) && $product && $product->requiresVariation()) {
         $this->form->sessionMessage(_t('ProductForm.VARIATIONS_REQUIRED', 'This product requires options before it can be added to the cart.'), 'bad');
         //Have to set an error for Form::validate()
         $this->errors[] = true;
         $valid = false;
         return $valid;
     }
     //Validate that base currency is set for this cart
     $config = ShopConfig::current_shop_config();
     if (!$config->BaseCurrency) {
         $this->form->sessionMessage(_t('ProductForm.BASE_CURRENCY_NOT_SET', 'The currency is not set.'), 'bad');
         //Have to set an error for Form::validate()
         $this->errors[] = true;
         $valid = false;
     }
     return $valid;
 }
Exemplo n.º 13
0
 /**
  * Set some CMS fields for managing Products
  * 
  * @see Page::getCMSFields()
  * @return FieldList
  */
 public function getCMSFields()
 {
     $shopConfig = ShopConfig::current_shop_config();
     $fields = parent::getCMSFields();
     //Main Product Image
     $fields->addFieldToTab("Root.Main", $uploadField = new UploadField("MainProductImage", "Main Product Image"));
     $uploadField->setFolderName('Store');
     $uploadField->setAllowedExtensions(array('jpg', 'jpeg', 'png', 'gif'));
     // Use SortableUploadField instead of UploadField!
     $imageField = new SortableUploadField('OtherImages', 'Other Product Images');
     $imageField->setFolderName('Store');
     $imageField->setAllowedExtensions(array('jpg', 'jpeg', 'png', 'gif'));
     $fields->addFieldToTab('Root.Main', $imageField);
     //Product fields
     $fields->addFieldToTab('Root.Main', new PriceField('Price'), 'Content');
     //Replace URL Segment field
     if ($this->ParentID == -1) {
         $urlsegment = new SiteTreeURLSegmentField("URLSegment", 'URLSegment');
         $baseLink = Controller::join_links(Director::absoluteBaseURL(), 'product/');
         $url = strlen($baseLink) > 36 ? "..." . substr($baseLink, -32) : $baseLink;
         $urlsegment->setURLPrefix($url);
         $fields->replaceField('URLSegment', $urlsegment);
     }
     if ($this->isInDB()) {
         //Product attributes
         $listField = new GridField('Attributes', 'Attributes', $this->Attributes(), GridFieldConfig_BasicSortable::create());
         $fields->addFieldToTab('Root.Attributes', $listField);
         //Product variations
         $attributes = $this->Attributes();
         if ($attributes && $attributes->exists()) {
             //Remove the stock level field if there are variations, each variation has a stock field
             $fields->removeByName('Stock');
             $variationFieldList = array();
             foreach ($attributes as $attribute) {
                 $variationFieldList['AttributeValue_' . $attribute->ID] = $attribute->Title;
             }
             $variationFieldList = array_merge($variationFieldList, singleton('Variation')->summaryFields());
             $config = GridFieldConfig_HasManyRelationEditor::create();
             $dataColumns = $config->getComponentByType('GridFieldDataColumns');
             $dataColumns->setDisplayFields($variationFieldList);
             $listField = new GridField('Variations', 'Variations', $this->Variations(), $config);
             $fields->addFieldToTab('Root.Variations', $listField);
         }
     }
     //Ability to edit fields added to CMS here
     $this->extend('updateProductCMSFields', $fields);
     if ($warning = ShopConfig::base_currency_warning()) {
         $fields->addFieldToTab('Root.Main', new LiteralField('BaseCurrencyWarning', '<p class="message warning">' . $warning . '</p>'), 'Title');
     }
     return $fields;
 }
 /**
  * Build default list of billing countries
  * 
  * @see Country::$iso_3166_countryCodes
  * @see DataObject::requireDefaultRecords()
  */
 public function requireDefaultRecords()
 {
     parent::requireDefaultRecords();
     if (!DataObject::get_one('Country_Billing')) {
         $shopConfig = ShopConfig::current_shop_config();
         if (isset($shopConfig->ID)) {
             foreach (self::$iso_3166_countryCodes as $code => $title) {
                 $country = new Country_Billing();
                 $country->Code = $code;
                 $country->Title = $title;
                 $country->ShopConfigID = $shopConfig->ID;
                 $country->write();
             }
             DB::alteration_message('Billing countries created', 'created');
         } else {
             DB::alteration_message('Billing countries not created, please re-run /dev/build', 'error');
         }
     }
 }
Exemplo n.º 15
0
 public static function rate_for_currency($currency = null)
 {
     $currency = $currency ?: ShopConfig::current_shop_config()->BaseCurrency;
     $rates = StreakGSTModule::currency_percentages();
     return isset($rates[$currency]) ? $rates[$currency] : 0;
 }
 public function run($request)
 {
     $dbAdmin = DatabaseAdmin::create();
     increase_time_limit_to(600);
     SS_ClassLoader::instance()->getManifest()->regenerate();
     $dbAdmin->clearAllData();
     $dbAdmin->doBuild(true);
     // Build again for good measure
     $dbAdmin->doBuild(true, false);
     //Move images to assets/Uploads/
     $assetsDir = Director::baseFolder() . '/assets/Uploads';
     $imagesDir = Director::baseFolder() . '/swipestripe-builder/images';
     foreach (new DirectoryIterator($assetsDir) as $fileInfo) {
         if (!$fileInfo->isDot()) {
             @unlink($fileInfo->getPathname());
         }
     }
     Filesystem::sync();
     foreach (new DirectoryIterator($imagesDir) as $fileInfo) {
         if ($fileInfo->isFile()) {
             copy($fileInfo->getPathname(), $assetsDir . '/' . $fileInfo->getFilename());
         }
     }
     //Build DB
     $fixture = Injector::inst()->create('YamlFixture', self::$fixture_file);
     $fixture->writeInto($this->getFixtureFactory());
     //Update the shop config
     $config = ShopConfig::current_shop_config();
     $config->BaseCurrency = 'NZD';
     $config->BaseCurrencySymbol = '$';
     $config->EmailSignature = '';
     $config->ReceiptSubject = 'Your order details from SwipeStripe demo site';
     $config->ReceiptBody = '';
     $config->ReceiptFrom = '*****@*****.**';
     $config->NotificationSubject = 'New order on SwipeStripe demo site';
     $config->NotificationBody = '';
     $config->NotificationTo = '*****@*****.**';
     $config->write();
     // Populate flat fee shipping rates
     $this->createShippingRates();
     // Populate tax rates
     $this->createTaxRates();
     // Populate exchange rates
     $this->createExchangeRates();
     // Populate coupon codes
     $this->createCouponCodes();
     // Product categories
     $this->createProductCategories();
     // Product images
     $this->createProductImages();
     // Clear product meta
     $products = Product::get();
     if ($products && $products->exists()) {
         foreach ($products as $product) {
             $product->ExtraMeta = '';
             $product->doPublish();
         }
     }
     // Create home page
     if (class_exists('HomePage')) {
         $page = Page::get()->where("\"URLSegment\" = 'home'")->first();
         $page->ClassName = 'HomePage';
         $page->doPublish();
     }
 }
 public function onBeforePayment()
 {
     //Set the currency for Order from the session
     if ($currency = Session::get('SWS.Currency')) {
         //Get the exchange rate, alter the amount
         $rate = ExchangeRate::get()->where("\"Currency\" = '{$currency}'")->limit(1)->first();
         if ($rate && $rate->exists()) {
             $this->owner->Currency = $rate->Currency;
             $this->owner->CurrencySymbol = $rate->CurrencySymbol;
             $this->owner->ExchangeRate = $rate->Rate;
         }
     } else {
         //Currency has not been set in the session, assume base currency
         $shopConfig = ShopConfig::current_shop_config();
         $this->owner->Currency = $shopConfig->BaseCurrency;
         $this->owner->CurrencySymbol = $shopConfig->BaseCurrencySymbol;
         $this->owner->ExchangeRate = 1.0;
         //1 to 1 exchange rate
     }
     $this->owner->write();
 }
Exemplo n.º 18
0
 /**
  * Update stock level associated with this Variation.
  * 
  * (non-PHPdoc)
  * @see DataObject::onBeforeWrite()
  */
 public function onBeforeWrite()
 {
     parent::onBeforeWrite();
     //Save in base currency
     $shopConfig = ShopConfig::current_shop_config();
     $this->Currency = $shopConfig->BaseCurrency;
 }
Exemplo n.º 19
0
 public static function default_stock_level()
 {
     return ShopConfig::current_shop_config()->DefaultStockLevel ?: self::config()->get('default_stock_level');
 }
Exemplo n.º 20
0
 public function process($data, $form)
 {
     $this->extend('onBeforeProcess', $data);
     //Check payment type
     try {
         $paymentMethod = Convert::raw2sql($data['PaymentMethod']);
         $paymentProcessor = PaymentFactory::factory($paymentMethod);
     } catch (Exception $e) {
         Debug::friendlyError(403, _t('CheckoutPage.NOT_VALID_METHOD', "Sorry, that is not a valid payment method."), _t('CheckoutPage.TRY_AGAIN', "Please go back and try again."));
         return;
     }
     //Save or create a new customer/member
     $member = Customer::currentUser() ? Customer::currentUser() : singleton('Customer');
     if (!$member->exists()) {
         $existingCustomer = Customer::get()->filter('Email', $data['Email']);
         if ($existingCustomer && $existingCustomer->exists()) {
             $form->sessionMessage(_t('CheckoutPage.MEMBER_ALREADY_EXISTS', 'Sorry, a member already exists with that email address. If this is your email address, please log in first before placing your order.'), 'bad');
             $this->controller->redirectBack();
             return false;
         }
         $member = Customer::create();
         $form->saveInto($member);
         $member->write();
         $member->addToGroupByCode('customers');
         $member->logIn();
     }
     //Save the order
     $order = Cart::get_current_order();
     $items = $order->Items();
     $form->saveInto($order);
     $order->MemberID = $member->ID;
     $order->Status = Order::STATUS_PENDING;
     $order->OrderedOn = SS_Datetime::now()->getValue();
     $order->write();
     //Saving an update on the order
     if ($notes = $data['Notes']) {
         $update = new Order_Update();
         $update->Note = $notes;
         $update->Visible = true;
         $update->OrderID = $order->ID;
         $update->MemberID = $member->ID;
         $update->write();
     }
     //Add modifiers to order
     $order->updateModifications($data)->write();
     Session::clear('Cart.OrderID');
     $order->onBeforePayment();
     try {
         $shopConfig = ShopConfig::current_shop_config();
         $precision = $shopConfig->BaseCurrencyPrecision;
         $paymentData = array('Amount' => number_format($order->Total()->getAmount(), $precision, '.', ''), 'Currency' => $order->Total()->getCurrency(), 'Reference' => $order->ID);
         $paymentProcessor->payment->OrderID = $order->ID;
         $paymentProcessor->payment->PaidByID = $member->ID;
         $paymentProcessor->setRedirectURL($order->Link());
         $paymentProcessor->capture($paymentData);
     } catch (Exception $e) {
         //This is where we catch gateway validation or gateway unreachable errors
         $result = $paymentProcessor->gateway->getValidationResult();
         $payment = $paymentProcessor->payment;
         //TODO: Need to get errors and save for display on order page
         SS_Log::log(new Exception(print_r($result->message(), true)), SS_Log::NOTICE);
         SS_Log::log(new Exception(print_r($e->getMessage(), true)), SS_Log::NOTICE);
         $this->controller->redirect($order->Link());
     }
 }