from AccessControl.requestmethod import postonly
from zope.interface import implements
from zope.component.factory import Factory
+from persistent.list import PersistentList
from OFS.SimpleItem import SimpleItem
from ZTUtils import make_query
from DateTime import DateTime
from interfaces import IPrintOrderTemplate, IPrintOrder
from permissions import ManagePrintOrderTemplate, ManagePrintOrders
from price import Price
-from utils import Message as _
-from utils import translate
from xml.dom.minidom import Document
from tool import COPIES_COUNTERS
from App.config import getConfiguration
-from paypal.interface import PayPalInterface
+try :
+ from paypal.interface import PayPalInterface
+ paypalAvailable = True
+except ImportError :
+ paypalAvailable = False
from logging import getLogger
console = getLogger('Products.photoprint.order')
self.id = id
self.items = []
self.quantity = 0
+ self.discount = 0 # discount ratio in percent
self.price = Price(0, 0)
# billing and shipping addresses
self.billing = PersistentMapping()
self.shipping = PersistentMapping()
self.shippingFees = Price(0,0)
- self._paymentResponse = PersistentMapping()
+ self._paypalLog = PersistentList()
@property
def amountWithFees(self) :
- return self.price + self.shippingFees
+ coeff = (100 - self.discount) / 100.
+ return self.price * coeff + self.shippingFees
security.declareProtected(ModifyPortalContent, 'editBilling')
pptool = getToolByName(self, 'portal_photo_print')
uidh = getToolByName(self, 'portal_uidhandler')
mtool = getToolByName(self, 'portal_membership')
+ utool = getToolByName(self, 'portal_url')
items = []
for item in cart :
counters.confirm(reference, quantity)
self.items = tuple(items)
+ discount_script = getattr(utool.getPortalObject(), 'photoprint_discount', None)
+ if discount_script :
+ self.discount = discount_script(self.price, self.quantity)
member = mtool.getAuthenticatedMember()
mg = lambda name : member.getProperty(name, '')
portal = utool.getPortalObject()
member = mtool.getAuthenticatedMember()
- options = {#'PAYMENTREQUEST_0_AMT' : '99.55', # todo
- 'PAYMENTREQUEST_0_CURRENCYCODE' : 'EUR',
+ options = {'PAYMENTREQUEST_0_CURRENCYCODE' : 'EUR',
'PAYMENTREQUEST_0_PAYMENTACTION' : 'Sale',
'RETURNURL' : '%s/photoprint_order_confirm' % self.absolute_url(),
'CANCELURL' : '%s/photoprint_order_cancel' % self.absolute_url(),
- # 'CALLBACK' : TODO
'ALLOWNOTE' : 0, # The buyer is unable to enter a note to the merchant.
'HDRIMG' : '%s/logo.gif' % portal_url,
'EMAIL' : member.getProperty('email'),
'GIFTRECEIPTENABLE' : 0,
'BUYEREMAILOPTINENABLE' : 0, # Do not enable buyer to provide email address.
'NOSHIPPING' : 1, # PayPal does not display shipping address fields whatsoever.
- # 'PAYMENTREQUEST_0_NOTIFYURL' : TODO
-
'PAYMENTREQUEST_0_SHIPTONAME' : self.billing['name'],
'PAYMENTREQUEST_0_SHIPTOSTREET' : self.billing['address'],
'PAYMENTREQUEST_0_SHIPTOCITY' : self.billing['city'],
'PAYMENTREQUEST_0_SHIPTOPHONENUM' : self.billing['phone'],
}
- quantitySum = reduce(lambda a, b : a['quantity'] + b['quantity'], self.items)
- priceSum = reduce(lambda a, b : a['unit_price'] * a['quantity'] + b['unit_price'] * b['quantity'], self.items)
- priceValues = priceSum.getValues()
+ if len(self.items) > 1 :
+ quantitySum = reduce(lambda a, b : a + b, [item['quantity'] for item in self.items])
+ else :
+ quantitySum = self.items[0]['quantity']
total = round(self.amountWithFees.getValues()['taxed'], 2)
- options['L_PAYMENTREQUEST_0_NAME0'] = 'Commande realis photo ref. %s' % self.getId()
+ options['L_PAYMENTREQUEST_0_NAME0'] = 'Commande photo ref. %s' % self.getId()
if quantitySum == 1 :
options['L_PAYMENTREQUEST_0_DESC0'] = "Commande d'un tirage photographique"
else :
options['L_PAYMENTREQUEST_0_DESC0'] = 'Commande de %d tirages photographiques' % quantitySum
options['L_PAYMENTREQUEST_0_AMT0'] = total
options['PAYMENTINFO_0_SHIPPINGAMT'] = round(self.shippingFees.getValues()['taxed'], 2)
- # options['L_PAYMENTREQUEST_0_TAXAMT0'] = tax
- # options['L_PAYMENTREQUEST_0_QTY%d' % n] = 1
options['PAYMENTREQUEST_0_AMT'] = total
ppi = self._initPayPalInterface()
response = ppi.set_express_checkout(**options)
response = PrintOrder.recordifyPPResp(response)
- # self._paypalLog.append(response)
+ self._paypalLog.append(response)
response['url'] = ppi.generate_express_checkout_redirect_url(response['TOKEN'])
console.info(options)
console.info(response)
ppi = self._initPayPalInterface()
response = ppi.get_express_checkout_details(TOKEN=token)
response = PrintOrder.recordifyPPResp(response)
- # self._paypalLog.append(response)
+ self._paypalLog.append(response)
return response
security.declarePrivate('ppDoExpressCheckoutPayment')
TOKEN=token,
PAYERID=payerid)
response = PrintOrder.recordifyPPResp(response)
- # self._paypalLog.append(response)
+ self._paypalLog.append(response)
return response
security.declareProtected(ModifyPortalContent, 'ppPay')
security.declareProtected(ManagePortal, 'getPPLog')
def getPPLog(self) :
return self._paypalLog
-
-
-
- # security.declareProtected(View, 'getPaymentRequest')
- # def getPaymentRequest(self) :
- # config = _getCyberplusConfig()
- # requester = CyberplusRequester(config)
- # hereurl = self.absolute_url()
- # amount = self.price + self.shippingFees
- # amount = amount.getValues()['taxed']
- # amount = amount * 100
- # amount = str(int(round(amount, 0)))
- # pptool = getToolByName(self, 'portal_photo_print')
- # transaction_id = pptool.getNextTransactionId()
- #
- # userLanguages = getPreferredLanguages(self)
- # for pref in userLanguages :
- # lang = pref.split('-')[0]
- # if lang in CYBERPLUS_LANGUAGES :
- # break
- # else :
- # lang = 'en'
- #
- # options = { 'amount': amount
- # ,'cancel_return_url' : '%s/paymentCancelHandler' % hereurl
- # ,'normal_return_url' : '%s/paymentManualResponseHandler' % hereurl
- # ,'automatic_response_url' :'%s/paymentAutoResponseHandler' % hereurl
- # ,'transaction_id' : transaction_id
- # ,'order_id' : self.getId()
- # ,'language' : lang
- # }
- # req = requester.generateRequest(options)
- # return req
- #
- # def _decodeCyberplusResponse(self, form) :
- # config = _getCyberplusConfig()
- # responder = CyberplusResponder(config)
- # response = responder.getResponse(form)
- # return response
- #
- # def _compareWithAutoResponse(self, manu) :
- # keys = manu.keys()
- # auto = self._paymentResponse
- # autoKeys = auto.keys()
- # if len(keys) != len(autoKeys) :
- # console.warn('Manual has not the same keys.\nauto: %r\nmanual: %r' % \
- # (sorted(autoKeys), sorted(keys)))
- # else :
- # for k, v in manu.items() :
- # if not auto.has_key(k) :
- # console.warn('%r field only found in manual response.' % k)
- # else :
- # if v != auto[k] :
- # console.warn('data mismatch for %r\nauto: %r\nmanual: %r' % (k, auto[k], v))
- #
- # def _checkOrderId(self, response) :
- # expected = self.getId()
- # assert expected == response['order_id'], \
- # "Cyberplus response transaction_id doesn't match the order object:\n" \
- # "expected: %s\n" \
- # "found: %s" % (expected, response['transaction_id'])
-
- # def _executeOrderWfTransition(self, response) :
- # if CyberplusResponder.transactionAccepted(response) :
- # wfaction = 'auto_accept_payment'
- # elif CyberplusResponder.transactionRefused(response) :
- # self.resetCopiesCounters()
- # wfaction = 'auto_refuse_payment'
- # elif CyberplusResponder.transactionCanceled(response) :
- # wfaction = 'auto_cancel_order'
- # else :
- # # transaction failed
- # wfaction = 'auto_transaction_failed'
- #
- # wtool = getToolByName(self, 'portal_workflow')
- # wf = wtool.getWorkflowById('order_workflow')
- # tdef = wf.transitions.get(wfaction)
- # wf._changeStateOf(self, tdef)
- # wtool._reindexWorkflowVariables(self)
-
- # security.declarePublic('paymentAutoResponseHandler')
- # @postonly
- # def paymentAutoResponseHandler(self, REQUEST) :
- # """\
- # Handle cyberplus payment auto response.
- # """
- # response = self._decodeCyberplusResponse(REQUEST.form)
- # self._checkOrderId(response)
- # self._paymentResponse.update(response)
- # self._executeOrderWfTransition(response)
- #
- # @postonly
- # def paymentManualResponseHandler(self, REQUEST) :
- # """\
- # Handle cyberplus payment manual response.
- # """
- # response = self._decodeCyberplusResponse(REQUEST.form)
- # self._checkOrderId(response)
- #
- # autoResponse = self._paymentResponse
- # if not autoResponse :
- # console.warn('Manual response handled before auto response at %s' % '/'.join(self.getPhysicalPath()))
- # self._paymentResponse.update(response)
- # self._executeOrderWfTransition(response)
- # else :
- # self._compareWithAutoResponse(response)
- #
- # url = '%s?%s' % (self.absolute_url(),
- # make_query(portal_status_message=translate('Your payment is complete.', self).encode('utf-8'))
- # )
- # return REQUEST.RESPONSE.redirect(url)
- #
- # @postonly
- # def paymentCancelHandler(self, REQUEST) :
- # """\
- # Handle cyberplus cancel response.
- # This handler can be invoqued in two cases:
- # - the user cancel the payment form
- # - the payment transaction has been refused
- # """
- # response = self._decodeCyberplusResponse(REQUEST.form)
- # self._checkOrderId(response)
- #
- # if self._paymentResponse :
- # # normaly, it happens when the transaction is refused by cyberplus.
- # self._compareWithAutoResponse(response)
- #
- #
- # if CyberplusResponder.transactionRefused(response) :
- # if not self._paymentResponse :
- # console.warn('Manual response handled before auto response at %s' % '/'.join(self.getPhysicalPath()))
- # self._paymentResponse.update(response)
- # self._executeOrderWfTransition(response)
- #
- # msg = 'Your payment has been refused.'
- #
- # else :
- # self._executeOrderWfTransition(response)
- # msg = 'Your payment has been canceled. You will be able to pay later.'
- #
- # url = '%s?%s' % (self.absolute_url(),
- # make_query(portal_status_message= \
- # translate(msg, self).encode('utf-8'))
- # )
- # return REQUEST.RESPONSE.redirect(url)
-
def getCustomerSummary(self) :
' '
return {'quantity':self.quantity,