GetFieldOptions('PaymentCCExpDate'); $month_field = $options['month_field']; $year_field = $options['year_field']; if ( (isset($hash[$month_field]) && $this->GetDirtyField($month_field)) || (isset($hash[$year_field]) && $this->GetDirtyField($year_field)) ) { $this->SetDirtyField('PaymentCCExpDate', 0); $this->SetField('PaymentCCExpDate', 0); } } /** * Returns gateway data based on payment type used in order * * @param int $pt_id * @return Array * @access public */ public function getGatewayData($pt_id = null) { // get Gateway fields if ( !isset($pt_id) || !$pt_id ) { $pt_id = $this->GetDBField('PaymentType'); if ( !$pt_id ) { // no Payment Type Id found for this order - escape SQL fatal below return false; } } $pt_table = $this->Application->getUnitOption('pt', 'TableName'); $sql = 'SELECT GatewayId FROM %s WHERE PaymentTypeId = %s'; $gw_id = $this->Conn->GetOne(sprintf($sql, $pt_table, $pt_id)); $sql = 'SELECT * FROM %s WHERE GatewayId = %s'; $ret = $this->Conn->GetRow(sprintf($sql, TABLE_PREFIX . 'Gateways', $gw_id)); // get Gateway parameters based on payment type $gwf_table = $this->Application->getUnitOption('gwf', 'TableName'); $gwfv_table = $this->Application->getUnitOption('gwfv', 'TableName'); $sql = 'SELECT gwfv.Value, gwf.SystemFieldName FROM %s gwf LEFT JOIN %s gwfv ON gwf.GWConfigFieldId = gwfv.GWConfigFieldId WHERE gwfv.PaymentTypeId = %s AND gwf.GatewayId = %s'; $ret['gw_params'] = $this->Conn->GetCol(sprintf($sql, $gwf_table, $gwfv_table, $pt_id, $gw_id), 'SystemFieldName'); $ret['gw_params']['gateway_id'] = $gw_id; if ( $this->GetDBField('IsRecurringBilling') && $this->Application->ConfigValue('Comm_AutoProcessRecurringOrders') ) { if ( isset($ret['gw_params']['shipping_control']) ) { $ret['gw_params']['shipping_control'] = SHIPPING_CONTROL_DIRECT; } } return $ret; } /** * Checks if tangible items are present in order * * @return boolean */ public function HasTangibleItems() { $oi_table = TABLE_PREFIX . 'OrderItems'; if ( $this->IsTempTable() ) { $oi_table = $this->Application->GetTempName($oi_table, 'prefix:' . $this->Prefix); } $sql = 'SELECT COUNT(*) FROM ' . $oi_table . ' orditems LEFT JOIN ' . TABLE_PREFIX . 'Products p ON p.ProductId = orditems.ProductId WHERE (orditems.OrderId = ' . $this->GetID() . ') AND (p.Type = ' . PRODUCT_TYPE_TANGIBLE . ')'; return $this->Conn->GetOne($sql) > 0; } /** * Calculates tax value of order items based on billing & shipping country specified * * @return double */ function getTaxPercent() { /** @var kCountryStatesHelper $cs_helper */ $cs_helper = $this->Application->recallObject('CountryStatesHelper'); $shipping_country_id = $cs_helper->getCountryStateId($this->GetDBField('ShippingCountry'), DESTINATION_TYPE_COUNTRY); $shipping_state_id = $cs_helper->getCountryStateId($this->GetDBField('ShippingState'), DESTINATION_TYPE_STATE); $shipping_zip = (string) $this->GetDBField('ShippingZip'); $billing_country_id = $cs_helper->getCountryStateId($this->GetDBField('BillingCountry'), DESTINATION_TYPE_COUNTRY); $billing_state_id = $cs_helper->getCountryStateId($this->GetDBField('BillingState'), DESTINATION_TYPE_STATE); $billing_zip = (string) $this->GetDBField('BillingZip'); /* $dest_ids = array_diff( array_unique( Array( $shipping_country_id, $shipping_state_id, $billing_country_id, $billing_state_id ) ), Array(0) ); $dest_values = array_diff( array_unique( Array( $this->Conn->qstr($shipping_zip), $this->Conn->qstr($billing_zip) ) ), Array('\'\'') ); */ $tax = false; $sql = 'SELECT tx.* FROM '.$this->Application->getUnitOption('tax', 'TableName').' tx LEFT JOIN '.$this->Application->getUnitOption('taxdst', 'TableName').' txd ON tx.TaxZoneId = txd.TaxZoneId WHERE ( txd.StdDestId IN ('.$shipping_country_id.','.$shipping_state_id.') AND ( (txd.DestValue = "" OR txd.DestValue IS NULL) OR txd.DestValue = '.$this->Conn->qstr($shipping_zip).' ) ) OR ( txd.StdDestId IN ('.$billing_country_id.','.$billing_state_id.') AND ( (txd.DestValue = "" OR txd.DestValue IS NULL) OR txd.DestValue = '.$this->Conn->qstr($billing_zip).' ) ) ORDER BY tx.TaxValue DESC'; $tax = $this->Conn->GetRow($sql); if ($tax == false) { $tax['TaxValue'] = 0; $tax['ApplyToShipping'] = 0; $tax['ApplyToProcessing'] = 0; } return $tax; } function RecalculateTax() { $tax = $this->getTaxPercent(); $this->SetDBField('VATPercent', $tax['TaxValue']); $this->SetDBField('ShippingTaxable', $tax['ApplyToShipping']); $this->SetDBField('ProcessingTaxable', $tax['ApplyToProcessing']); $this->UpdateTotals(); if ( !$this->GetDBField('VATIncluded') ) { $subtotal = $this->GetDBField('AmountWithoutVAT'); $tax_exempt = $this->getTaxExempt(); if ( $tax_exempt ) { $subtotal -= $tax_exempt; } $this->SetDBField('VAT', round($subtotal * $tax['TaxValue'] / 100, 2)); $this->UpdateTotals(); } } /** * Returns order amount, that is excluded from tax calculations * * @return float * @access protected */ protected function getTaxExempt() { $sql = 'SELECT SUM(oi.Quantity * oi.Price) FROM ' . TABLE_PREFIX . 'OrderItems AS oi LEFT JOIN ' . TABLE_PREFIX . 'Products AS p ON p.ProductId = oi.ProductId WHERE p.Type = 6 AND oi.OrderId = ' . $this->GetDBField('OrderId'); return $this->Conn->GetOne($sql); } function UpdateTotals() { $total = 0; $total += $this->GetDBField('SubTotal'); if ( $this->GetDBField('ShippingTaxable') ) { $total += $this->GetDBField('ShippingCost'); } if ( $this->GetDBField('ProcessingTaxable') ) { $total += $this->GetDBField('ProcessingFee'); } if ( $this->GetDBField('VATIncluded') ) { $tax_exempt = $this->getTaxExempt(); $vat_percent = $this->GetDBField('VATPercent'); $this->SetDBField('VAT', round(($total - $tax_exempt) * $vat_percent / (100 + $vat_percent), 2)); $this->SetDBField('AmountWithoutVAT', $total - $this->GetDBField('VAT')); } else { $this->SetDBField('AmountWithoutVAT', $total); $total += $this->GetDBField('VAT'); } if ( !$this->GetDBField('ShippingTaxable') ) { $total += $this->GetDBField('ShippingCost'); } if ( !$this->GetDBField('ProcessingTaxable') ) { $total += $this->GetDBField('ProcessingFee'); } $total += $this->GetDBField('InsuranceFee'); $this->SetDBField('TotalAmount', $total); } function getTotalAmount() { return $this->GetDBField('SubTotal') + $this->GetDBField('ShippingCost') + ($this->GetDBField('VATIncluded') ? 0 : $this->GetDBField('VAT')) + $this->GetDBField('ProcessingFee') + $this->GetDBField('InsuranceFee') - $this->GetDBField('GiftCertificateDiscount'); } function requireCreditCard() { $sql = 'SELECT RequireCCFields FROM ' . $this->Application->getUnitOption('pt', 'TableName') . ' pt LEFT JOIN '.TABLE_PREFIX.'Gateways gw ON gw.GatewayId = pt.GatewayId WHERE pt.PaymentTypeId = ' . $this->GetDBField('PaymentType'); return $this->Conn->GetOne($sql); } function getNextSubNumber() { $table = $this->Application->GetLiveName($this->TableName); $sql = 'SELECT MAX(SubNumber) FROM '.$table.' WHERE Number = '.$this->GetDBField('Number'); return $this->Conn->GetOne($sql) + 1; } function ResetAddress($prefix) { $fields = Array('To','Company','Phone','Fax','Email','Address1','Address2','City','State','Zip','Country'); foreach($fields as $field) { $this->SetDBField($prefix.$field, $this->Fields[$prefix.$field]['default']); } } function IsProfileAddress($address_type) { return $this->Application->GetVar($this->Prefix.'_IsProfileAddress'); } // ===== Gift Certificates Related ===== function RecalculateGift($event) { $gc_id = $this->GetDBField('GiftCertificateId'); if ($gc_id < 1) { return; } /** @var kDBItem $gc */ $gc = $this->Application->recallObject('gc', null, Array('skip_autoload' => true)); $gc->Load($gc_id); if ($gc->GetDBField('Status') == gcDISABLED) { // disabled GC $this->SetDBField('GiftCertificateId', 0); $this->SetDBField('GiftCertificateDiscount', 0); // disabled return; } $debit = $gc->GetDBField('Debit') + $this->GetDBField('GiftCertificateDiscount'); $this->UpdateTotals(); $total = $this->GetDBField('TotalAmount'); $gift_certificate_discount = $debit >= $total ? $total : $debit; $this->SetDBField('TotalAmount', $total - $gift_certificate_discount); $this->GetDBField('GiftCertificateDiscount', $gift_certificate_discount); $debit -= $gift_certificate_discount; $gc->SetDBField('Debit', $debit); $gc->SetDBField('Status', $debit > 0 ? gcENABLED : gcUSED); $gc->Update(); if ($gift_certificate_discount == 0) { $this->RemoveGiftCertificate($object); $this->setCheckoutError(OrderCheckoutErrorType::GIFT_CERTIFICATE, OrderCheckoutError::GC_REMOVED_AUTOMATICALLY); } $this->SetDBField('GiftCertificateDiscount', $gift_certificate_discount); } function RemoveGiftCertificate() { $gc_id = $this->GetDBField('GiftCertificateId'); /** @var kDBItem $gc */ $gc = $this->Application->recallObject('gc', null, Array('skip_autoload' => true)); $gc->Load($gc_id); $debit = $gc->GetDBField('Debit') + $this->GetDBField('GiftCertificateDiscount'); if ($gc->isLoaded() && ($debit > 0)) { $gc->SetDBField('Debit', $debit); $gc->SetDBField('Status', gcENABLED); $gc->Update(); } $this->SetDBField('GiftCertificateId', 0); $this->SetDBField('GiftCertificateDiscount', 0); } /** * Sets checkout error * * @param int $error_type = {product,coupon,gc} * @param int $error_code * @param int $product_id - {ProductId}:{OptionsSalt}:{BackOrderFlag}:{FieldName} */ function setCheckoutError($error_type, $error_code, $product_id = null) { $errors = $this->Application->RecallVar('checkout_errors'); $errors = $errors ? unserialize($errors) : Array (); if ( isset($product_id) ) { $error_type .= ':' . $product_id; // any error takes priority over FIELD_UPDATE_SUCCESS error if ( isset($errors[$error_type]) && $error_code == OrderCheckoutError::FIELD_UPDATE_SUCCESS ) { return ; } } if ( is_numeric($error_code) ) { $errors[$error_type] = $error_code; } else { unset($errors[$error_type]); } if ( $this->Application->isDebugMode() ) { $this->Application->Debugger->appendHTML('CO_ERROR: ' . $error_type . ' - ' . $error_code); } $this->Application->StoreVar('checkout_errors', serialize($errors)); } }