Exemple #1
0
 def validate(self, value):
     super(SketchFileValidator, self).validate(value)
     
     fzzName = value.filename
     fzzNameLower = fzzName.lower()
     
     if not (fzzNameLower.endswith('.fzz')):
         raise Invalid(
             _(u"We can only produce from shareable Fritzing sketch files (.fzz)"))
     
     # use StringIO to make the blob to look like a file object:
     fzzData = StringIO(value.data)
     
     zf = None
     try:
         zf = zipfile.ZipFile(fzzData) 
     except:
         raise Invalid(
             _(u"Hmmm, '%s' doesn't seem to be a valid .fzz file. Sorry, we only support those at this time." % fzzName))
     
     pairs = getboardsize.fromZipFile(zf, fzzName)
     
     if not (len(pairs) >= 2):
         raise Invalid(
             _(u"No boards found in '%s'." % fzzName))
     
     if not (len(pairs) == 2):
         raise Invalid(
             _(u"Multiple boards found in '%s'. Sorry, we still work on the support for multiple boards per file." % fzzName))
     
     value.width = pairs[0] / 10
     value.height = pairs[1] / 10
     
     return True
Exemple #2
0
class PayPalCheckout(grok.View):
    """Order checkout
    """
    grok.name('paypal_checkout')
    grok.require('zope2.View')
    grok.context(IFabOrder)

    label = _(u"PayPal Checkout")
    description = _(u"Order checkout")

    def update(self):
        portal_workflow = getToolByName(self, 'portal_workflow')
        review_state = getStateId(None, self.context, portal_workflow)

        if review_state != 'open':
            self.addStatusMessage(_(u"Already checked out."), "info")
            return
        if not self.context.area > 0:
            self.addStatusMessage(
                _(u"Sketches missing/invalid, checkout aborted."), "error")
            return

        portal_workflow.doActionFor(self.context, action='submit')

        # send e-mails
        sendStatusMail(self.context)

        self.request.set('disable_border', 1)

    def addStatusMessage(self, message, messageType):
        IStatusMessage(self.request).addStatusMessage(message, messageType)
        faborderURL = self.context.absolute_url()
        self.request.response.redirect(faborderURL)
Exemple #3
0
class Index(grok.View):
    """Review the order
    """
    grok.require('zope2.View')
    grok.context(IFabOrder)

    label = _(u"Order your PCBs")
    description = _(u"Review the order")

    # make tools availible to the template as view.toolname()
    from fritzing.fab.tools \
        import encodeFilename, getStateId, getStateTitle, isStateId

    def update(self):
        member = self.context.portal_membership.getAuthenticatedMember()
        self.isManager = member.has_role('Manager')
        if not (self.isManager):
            self.request.set('disable_border', 1)

        if self.context.shipTo:
            self.shipToTitle = IFabOrder['shipTo'].vocabulary.getTerm(
                self.context.shipTo).title

        primeCostsPerSquareCm = 0.21
        earningsPerSquareCm = 0.7 * (self.context.pricePerSquareCm -
                                     primeCostsPerSquareCm)
        devHourCosts = 50.0
        self.devMinutes = (earningsPerSquareCm *
                           self.context.area) / (devHourCosts / 60.0)
Exemple #4
0
class Edit(dexterity.EditForm):
    """Edit the order
    """
    grok.name('edit')
    grok.require('cmf.ModifyPortalContent')
    grok.context(IFabOrder)

    schema = IFabOrder

    label = _(u"Edit order")
    description = _(u"Edit the order")
Exemple #5
0
class Checkout(grok.View):
    """Order checkout
    """
    grok.name('checkout')
    grok.require('cmf.ModifyPortalContent')
    grok.context(IFabOrder)

    label = _(u"Checkout")
    description = _(u"Order checkout")

    def render(self):
        faborderURL = self.context.absolute_url()
        self.request.response.redirect(faborderURL)
Exemple #6
0
class CheckoutSuccess(grok.View):
    """Order checkout success
    """
    grok.name('checkout_success')
    grok.require('zope2.View')
    grok.context(IFabOrder)

    label = _(u"Checkout")
    description = _(u"Order checkout")

    def render(self):
        faborderURL = self.context.absolute_url()
        self.request.response.redirect(faborderURL)
Exemple #7
0
class AddForm(dexterity.AddForm):
    """adds a sketch
    """
    grok.name('sketch')
    grok.require('cmf.AddPortalContent')
    grok.context(IFabOrder)

    schema = ISketch

    label = _(u"Add Sketch")
    description = u''

    def create(self, data):
        sketch = createObject('sketch')
        sketch.id = data['orderItem'].filename.encode("ascii")

        # lets make shure this file doesn't already exist
        if self.context.hasObject(sketch.id):
            IStatusMessage(self.request).addStatusMessage(
                _(u"A Sketch with this name already exists."), "error")
            return None

        sketch.title = data['orderItem'].filename
        sketch.orderItem = data['orderItem']
        sketch.copies = data['copies']
        sketch.check = True
        return sketch

    def add(self, object):
        if isinstance(object, Item):
            self.context._setObject(object.id, object)
Exemple #8
0
def sendStatusMail(context):
    """Sends notification on the order status to the orderer and faborders.salesEmail
    """
    mail_text = u""
    charset = 'utf-8'

    portal = getSite()
    mail_template = portal.mail_order_status_change
    faborders = context.aq_parent

    from_address = faborders.salesEmail
    from_name = "Fritzing Fab"
    to_address = context.email
    user = context.getOwner()
    to_name = user.getProperty('fullname')
    # we expect a name to contain non-whitespace characters:
    if not re.search('\S', to_name):
        to_name = u"%s" % user

    state_id = getStateId(False, context)
    state_title = getStateTitle(False, context)
    delivery_date = faborders.nextProductionDelivery

    mail_subject = _(u"Your Fritzing Fab order #%s is now %s") % (
        context.id, state_title.lower())

    mail_text = mail_template(
        to_name=to_name,
        to_address=to_address,
        state_id=state_id,
        state_title=state_title,
        delivery_date=delivery_date,
        faborder=context,
        ship_to=IFabOrder['shipTo'].vocabulary.getTerm(context.shipTo).title,
    )

    try:
        host = getToolByName(context, 'MailHost')
        # send our copy:
        host.send(
            MIMEText(mail_text, 'plain', charset),
            mto=formataddr((from_name, from_address)),
            mfrom=formataddr((from_name, from_address)),
            subject=mail_subject,
            charset=charset,
            msg_type="text/plain",
        )
        # send notification for the orderer:
        host.send(
            MIMEText(mail_text, 'plain', charset),
            mto=formataddr((to_name, to_address)),
            mfrom=formataddr((from_name, from_address)),
            subject=mail_subject,
            charset=charset,
            msg_type="text/plain",
        )
    except SMTPRecipientsRefused:
        # Don't disclose email address on failure
        raise SMTPRecipientsRefused('Recipient address rejected by server')
Exemple #9
0
 def update(self):
     portal_workflow = getToolByName(self, 'portal_workflow')
     review_state = getStateId(None, self.context, portal_workflow)
     
     if review_state != 'open':
         self.addStatusMessage(_(u"Already checked out."), "info")
         return
     if not self.context.area > 0:
         self.addStatusMessage(_(u"Sketches missing/invalid, checkout aborted."), "error")
         return
     
     portal_workflow.doActionFor(self.context, action='submit')
     
     # send e-mails
     sendStatusMail(self.context)
     
     self.request.set('disable_border', 1)
Exemple #10
0
def sendStatusMail(context):
    """Sends notification on the order status to the orderer and faborders.salesEmail
    """
    mail_text = u""
    charset = 'utf-8'
    
    portal = getSite()
    mail_template = portal.mail_order_status_change
    faborders = context.aq_parent
    
    from_address = faborders.salesEmail
    from_name = "Fritzing Fab"
    to_address = context.email
    user  = context.getOwner()
    to_name = user.getProperty('fullname')
    # we expect a name to contain non-whitespace characters:
    if not re.search('\S', to_name):
        to_name = u"%s" % user
    
    state_id = getStateId(False, context)
    state_title = getStateTitle(False, context)
    delivery_date = faborders.nextProductionDelivery
    
    mail_subject = _(u"Your Fritzing Fab order #%s is now %s") % (context.id, state_title.lower())
    
    mail_text = mail_template(
        to_name = to_name,
        to_address = to_address,
        state_id = state_id,
        state_title = state_title,
        delivery_date = delivery_date,
        faborder = context,
        ship_to = IFabOrder['shipTo'].vocabulary.getTerm(context.shipTo).title,
        )
    
    try:
        host = getToolByName(context, 'MailHost')
        # send our copy:
        host.send(
            MIMEText(mail_text, 'plain', charset), 
            mto = formataddr((from_name, from_address)),
            mfrom = formataddr((from_name, from_address)),
            subject = mail_subject,
            charset = charset,
            msg_type="text/plain",
        )
        # send notification for the orderer:
        host.send(
            MIMEText(mail_text, 'plain', charset), 
            mto = formataddr((to_name, to_address)),
            mfrom = formataddr((from_name, from_address)),
            subject = mail_subject,
            charset = charset,
            msg_type="text/plain",
        )
    except SMTPRecipientsRefused:
        # Don't disclose email address on failure
        raise SMTPRecipientsRefused('Recipient address rejected by server')
Exemple #11
0
    def update(self):
        portal_workflow = getToolByName(self, 'portal_workflow')
        review_state = getStateId(None, self.context, portal_workflow)

        if review_state != 'open':
            self.addStatusMessage(_(u"Already checked out."), "info")
            return
        if not self.context.area > 0:
            self.addStatusMessage(
                _(u"Sketches missing/invalid, checkout aborted."), "error")
            return

        portal_workflow.doActionFor(self.context, action='submit')

        # send e-mails
        sendStatusMail(self.context)

        self.request.set('disable_border', 1)
Exemple #12
0
    def validate(self, value):
        super(SketchFileValidator, self).validate(value)

        fzzName = value.filename
        fzzNameLower = fzzName.lower()

        if not (fzzNameLower.endswith('.fzz')):
            raise Invalid(
                _(u"We can only produce from shareable Fritzing sketch files (.fzz)"
                  ))

        # use StringIO to make the blob to look like a file object:
        fzzData = StringIO(value.data)

        zf = None
        try:
            zf = zipfile.ZipFile(fzzData)
        except:
            raise Invalid(
                _(u"Hmmm, '%s' doesn't seem to be a valid .fzz file. Sorry, we only support those at this time."
                  % fzzName))

        pairs = getboardsize.fromZipFile(zf, fzzName)

        if not (len(pairs) >= 2):
            raise Invalid(_(u"No boards found in '%s'." % fzzName))

        if not (len(pairs) == 2):
            raise Invalid(
                _(u"Multiple boards found in '%s'. Sorry, we still work on the support for multiple boards per file."
                  % fzzName))

        value.width = pairs[0] / 10
        value.height = pairs[1] / 10

        return True
Exemple #13
0
    def create(self, data):
        sketch = createObject('sketch')
        sketch.id = data['orderItem'].filename.encode("ascii")

        # lets make shure this file doesn't already exist
        if self.context.hasObject(sketch.id):
            IStatusMessage(self.request).addStatusMessage(
                _(u"A Sketch with this name already exists."), "error")
            return None

        sketch.title = data['orderItem'].filename
        sketch.orderItem = data['orderItem']
        sketch.copies = data['copies']
        sketch.check = True
        return sketch
Exemple #14
0
 def create(self, data):
     sketch = createObject('sketch')
     sketch.id = data['orderItem'].filename.encode("ascii")
     
     # lets make shure this file doesn't already exist
     if self.context.hasObject(sketch.id):
         IStatusMessage(self.request).addStatusMessage(
             _(u"A Sketch with this name already exists."), "error")
         return None
     
     sketch.title = data['orderItem'].filename
     sketch.orderItem = data['orderItem']
     sketch.copies = data['copies']
     sketch.check = True
     return sketch
Exemple #15
0
def checkEMail(eMailAddress):
    """Check if the e-mail address looks valid
    """
    if not (eMailMatch(eMailAddress)):
        raise Invalid(_(u"Invalid e-mail address"))
    return True
Exemple #16
0
def checkEMail(eMailAddress):
    """Check if the e-mail address looks valid
    """
    if not (eMailMatch(eMailAddress)):
        raise Invalid(_(u"Invalid e-mail address"))
    return True
Exemple #17
0
class ISketch(form.Schema):
    """A Fritzing Sketch file
    """
    
    orderItem = NamedBlobFile(
        title = _(u"Sketch file"),
        description = _(u"The .fzz file of your sketch"))
    
    copies = Int(
        title = _(u"Copies"),
        description = _(u"The more copies, the cheaper each one gets"),
        min = 1,
        default = 1)
    
    form.omitted('check')
    check = Bool(
        title = _(u"File Check"),
        description = _(u"Have us check your design for an extra 4 EUR"),
        default = True)
    
    form.omitted(
        'width', 
        'height', 
        'area')
    
    width = Float(
        title = _(u"Width"),
        description = _(u"The width of this sketch in cm"),
        min = 0.0,
        default = 0.0)
    
    height = Float(
        title = _(u"Height"),
        description = _(u"The height of this sketch in cm"),
        min = 0.0,
        default = 0.0)
    
    area = Float(
        title = _(u"Area"),
        description = _(u"The area of this sketch in cm^2"),
        min = 0.0,
        default = 0.0)
Exemple #18
0
class IFabOrders(form.Schema):
    """Fritzing Fab orders Folder
    """
    
    title = TextLine(
        title = _(u"Order-folder name"),
        description = _(u"The title of this fab-instance"))
    
    description = Text(
        title = _(u"Order-folder description"),
        description = _(u"The description (also subtitle) of this fab-instance"))
    
    salesEmail = TextLine(
        title = _(u"Sales e-mail"),
        description = _(u"Order status changes are e-mailed to this address"),
        constraint = checkEMail)
    
    shippingGermany = Float(
        title = _(u"Shipping Costs Germany"),
        description = _(u"The shipping costs for Germany in Euro"),
        min = 0.0,
        default = 4.0)
    
    shippingEU = Float(
        title = _(u"Shipping Costs EU"),
        description = _(u"The shipping costs for the EU in Euro"),
        min = 0.0,
        default = 6.0)
    
    shippingWorld = Float(
        title = _(u"Shipping Costs outside EU"),
        description = _(u"The shipping costs for otside of the EU in Euro"),
        min = 0.0,
        default = 6.0)
    
    taxesGermany = Float(
        title = _(u"Taxes Germany"),
        description = _(u"The taxes for Germany in Percent"),
        min = 0.0,
        default = 19.0)
    
    taxesEU = Float(
        title = _(u"Taxes EU"),
        description = _(u"The taxes for the EU in Percent"),
        min = 0.0,
        default = 19.0)
    
    taxesWorld = Float(
        title = _(u"Taxes outside EU"),
        description = _(u"The taxes for outside of the EU in Percent"),
        min = 0.0,
        default = 0.0)
    
    nextProductionDelivery = Date(
        title = _(u"Next production delivery date"),
        description = _(u"Estimated delivery date of PCBs from the next production"),
        required = False)
    
    nextProductionClosingDate = Date(
        title = _(u"Next production closing date"),
        description = _(u"Orders must be send in before this date to be included in the next production run"),
        required = False)
    
    editableContent = RichText(
        title = _(u"Order-folder text"),
        description = _(u"The text of this fab-instance"))
Exemple #19
0
class IFabOrder(form.Schema):
    """Fritzing Fab order details
    """
    
    shipTo = Choice(
        title = _(u"Shipping Area"),
        description = _(u"Where you are located"),
        vocabulary = SimpleVocabulary([
            SimpleTerm(value = u'germany', title = _(u'Germany')),
            SimpleTerm(value = u'eu', title = _(u'European Union (EU)')),
            SimpleTerm(value = u'world', title = _(u'Worldwide'))
        ]))
    
    email = TextLine(
        title = _(u"E-Mail"),
        description = _(u"Your e-mail address"),
        constraint = checkEMail)
    
    form.omitted(
        'telephone',
        'area', 
        'pricePerSquareCm', 
        'priceNetto', 
        'priceShipping', 
        'numberOfQualityChecks', 
        'priceQualityChecksNetto', 
        'taxesPercent', 
        'taxes', 
        'priceTotalNetto', 
        'priceTotalBrutto',
        'trackingNumber')
    
    telephone = ASCIILine(
        title = _(u"Telephone number"),
        description = _(u"We prefer a mobile number"))
    
    area = Float(
        title = _(u"Area"),
        description = _(u"The total area of all sketches in cm^2"),
        min = 0.0,
        default = 0.0)
    
    pricePerSquareCm = Float(
        title = _(u"Price per cm^2"),
        description = _(u"The price per cm^2 in Euro"),
        min = 0.0,
        default = 0.0)
    
    priceNetto = Float(
        title = _(u"Netto price"),
        description = _(u"The netto price without shipping in Euro"),
        min = 0.0,
        default = 0.0)
    
    priceShipping = Float(
        title = _(u"Shipping costs"),
        description = _(u"The shipping costs in Euro"),
        min = 0.0,
        default = 0.0)
    
    numberOfQualityChecks = Int(
        title = _(u"Number of quality checks"),
        description = _(u"Number of quality checks"),
        min = 0,
        default = 0)
    
    priceQualityChecksNetto = Float(
        title = _(u"Costs for quality checks"),
        description = _(u"The costs for quality checks in Euro"),
        min = 0.0,
        default = 0.0)
    
    taxesPercent = Float(
        title = _(u"Percent Taxes"),
        description = _(u"Taxes like VAT in Percent"),
        min = 0.0,
        default = 0.0)
    
    taxes = Float(
        title = _(u"Taxes"),
        description = _(u"Taxes like VAT"),
        min = 0.0,
        default = 0.0)
    
    priceTotalNetto = Float(
        title = _(u"Total Netto"),
        description = _(u"The netto price costs in Euro"),
        min = 0.0,
        default = 0.0)
    
    priceTotalBrutto = Float(
        title = _(u"Total"),
        description = _(u"The price including shipping costs and taxes in Euro"),
        min = 0.0,
        default = 0.0)
    
    trackingNumber = TextLine(
        title = _(u"Tracking Number"),
        description = _(u"The tracking number assigned by the parcel service"))