1 # -*- coding: utf-8 -*-
2 #######################################################################################
3 # Copyright © 2009 Benoît Pin <pin@cri.ensmp.fr> #
4 # Plinn - http://plinn.org #
7 # This program is free software; you can redistribute it and/or #
8 # modify it under the terms of the GNU General Public License #
9 # as published by the Free Software Foundation; either version 2 #
10 # of the License, or (at your option) any later version. #
12 # This program is distributed in the hope that it will be useful, #
13 # but WITHOUT ANY WARRANTY; without even the implied warranty of #
14 # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the #
15 # GNU General Public License for more details. #
17 # You should have received a copy of the GNU General Public License #
18 # along with this program; if not, write to the Free Software #
19 # Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. #
20 #######################################################################################
21 """ Cart definition used to store buyable prints
24 from Globals
import InitializeClass
, Persistent
, PersistentMapping
25 from Acquisition
import Implicit
26 from AccessControl
import ModuleSecurityInfo
27 from Products
.CMFCore
.utils
import getToolByName
28 from exceptions
import SoldOutError
, CartLockedError
29 from tool
import COPIES_COUNTERS
30 from order
import CopiesCounters
32 from logging
import getLogger
33 console
= getLogger('Products.photoprint.cart')
35 CART_ITEM_KEYS
= ['cmf_uid', 'printing_template', 'quantity']
37 msecurity
= ModuleSecurityInfo('Products.photoprint.cart')
38 msecurity
.declarePublic('PrintCart')
40 class PrintCart(Persistent
, Implicit
) :
42 items are store like that:
50 __allow_access_to_unprotected_subobjects__
= 1
53 self
._uids
= PersistentMapping()
54 self
._order
= tuple() # products sequence order
55 self
._shippingInfo
= PersistentMapping()
56 self
._confirmed
= False
57 self
.pendingOrderPath
= ''
59 def setShippingInfo(self
, **kw
) :
60 self
._shippingInfo
.update(kw
)
64 return self
._confirmed
66 def append(self
, context
, item
) :
69 assert isinstance(item
, dict)
72 assert keys
== CART_ITEM_KEYS
74 pptool
= getToolByName(context
, 'portal_photo_print')
75 uidh
= getToolByName(context
, 'portal_uidhandler')
78 template
= item
['printing_template']
79 quantity
= item
['quantity']
81 photo
= uidh
.getObject(uid
)
82 pOptions
= pptool
.getPrintingOptionsContainerFor(photo
)
83 template
= getattr(pOptions
, template
)
84 templateId
= template
.getId()
86 reference
= template
.productReference
88 # check / update counters
89 if template
.maxCopies
:
90 if not hasattr(photo
.aq_base
, COPIES_COUNTERS
) :
91 setattr(photo
, COPIES_COUNTERS
, CopiesCounters())
92 counters
= getattr(photo
, COPIES_COUNTERS
)
93 alreadySold
= counters
.get(reference
)
95 if (alreadySold
+ quantity
) > template
.maxCopies
:
96 raise SoldOutError(template
.maxCopies
- alreadySold
)
98 counters
[reference
] = alreadySold
+ quantity
100 if not self
._uids
.has_key(uid
) :
101 self
._uids
[uid
] = PersistentMapping()
102 self
._order
= self
._order
+ (uid
,)
104 if not self
._uids
[uid
].has_key(templateId
) :
105 self
._uids
[uid
][templateId
] = PersistentMapping()
106 self
._uids
[uid
][templateId
]['reference'] = reference
107 self
._uids
[uid
][templateId
]['quantity'] = 0
109 self
._uids
[uid
][templateId
]['quantity'] += quantity
111 def update(self
, context
, item
) :
113 raise CartLockedError
114 assert isinstance(item
, dict)
117 assert keys
== CART_ITEM_KEYS
119 pptool
= getToolByName(context
, 'portal_photo_print')
120 uidh
= getToolByName(context
, 'portal_uidhandler')
122 uid
= item
['cmf_uid']
123 template
= item
['printing_template']
124 quantity
= item
['quantity']
126 photo
= uidh
.getObject(uid
)
127 pOptions
= pptool
.getPrintingOptionsContainerFor(photo
)
128 template
= getattr(pOptions
, template
)
129 templateId
= template
.getId()
130 reference
= template
.productReference
132 currentQuantity
= self
._uids
[uid
][templateId
]['quantity']
133 delta
= quantity
- currentQuantity
134 if template
.maxCopies
:
135 counters
= getattr(photo
, COPIES_COUNTERS
)
137 already
= counters
[reference
]
138 if (already
+ delta
) > template
.maxCopies
:
139 raise SoldOutError(template
.maxCopies
- already
)
140 counters
[reference
] += delta
142 self
._uids
[uid
][templateId
]['quantity'] += delta
144 def remove(self
, context
, uid
, templateId
) :
146 raise CartLockedError
147 pptool
= getToolByName(context
, 'portal_photo_print')
148 uidh
= getToolByName(context
, 'portal_uidhandler')
150 photo
= uidh
.getObject(uid
)
151 pOptions
= pptool
.getPrintingOptionsContainerFor(photo
)
152 template
= getattr(pOptions
, templateId
)
153 reference
= template
.productReference
155 quantity
= self
._uids
[uid
][templateId
]['quantity']
156 if template
.maxCopies
:
157 counters
= getattr(photo
, COPIES_COUNTERS
)
158 counters
[reference
] -= quantity
160 del self
._uids
[uid
][templateId
]
161 if not self
._uids
[uid
] :
163 self
._order
= tuple([u
for u
in self
._order
if u
!= uid
])
167 for uid
in self
._order
:
169 item
['cmf_uid'] = uid
170 for templateId
, rq
in self
._uids
[uid
].items() :
171 item
['printing_template'] = templateId
172 item
['quantity'] = rq
['quantity']
175 def __nonzero__(self
) :
176 return len(self
._order
) > 0