Example #1
0
    def _get_classcards_formatted_button_to_cart(self, scdID,
                                                 school_memberships_id,
                                                 customer_has_membership):
        """
            Get button to add card to shopping cart
        """
        from tools import OsTools
        from os_customer import Customer

        db = current.db
        auth = current.auth
        TODAY_LOCAL = current.TODAY_LOCAL
        os_gui = current.globalenv['os_gui']
        T = current.T

        customer = Customer(auth.user.id)
        memberships = customer.get_memberships_on_date(TODAY_LOCAL)
        ids = []
        for row in memberships:
            ids.append(row.id)

        if school_memberships_id and not school_memberships_id in ids:
            sm = db.school_memberships(school_memberships_id)
            return A(SPAN(T("Membership %s required" % sm.Name),
                          ' ',
                          os_gui.get_fa_icon('fa-arrow-right'),
                          _class='smaller_font'),
                     _href=URL('shop', 'memberships'))

        link = A(SPAN(os_gui.get_fa_icon('fa-shopping-cart fa-2x')),
                 _href=URL('classcard_add_to_cart', vars={'scdID': scdID}))

        return self._get_formatted_button_apply_accent_color(link)
    def get_price_for_customer(self, cuID=None):
        """
        :param cuID: db.auth_user.id
        :return: product price for customer
        """
        from os_customer import Customer
        TODAY_LOCAL = current.globalenv['TODAY_LOCAL']

        price = self.workshop_product.Price
        if not cuID:
            return price


        customer = Customer(cuID)
        # Check subscription
        if customer.has_subscription_on_date(self.workshop.Startdate, from_cache=False):
            if self.workshop_product.PriceSubscription:
                price = self.workshop_product.PriceSubscription

            # Check subscription earlybird
            if ( self.workshop_product.PriceSubscriptionEarlybird
                 and TODAY_LOCAL <= self.workshop_product.EarlybirdUntil ):
                price = self.workshop_product.PriceSubscriptionEarlybird

            return price

        # Check earlybird
        if ( self.workshop_product.PriceEarlybird and
             TODAY_LOCAL <= self.workshop_product.EarlybirdUntil ):
            price = self.workshop_product.PriceEarlybird

        return price
Example #3
0
    def list_member_add(self, list_id, cuID):
        """
            Add a member to a list
        """
        T = current.T

        from os_customer import Customer
        customer = Customer(cuID)
        subscriber_hash = customer.get_email_hash('md5')

        mailchimp = self.get_client()

        try:
            mailchimp.lists.members.create_or_update(
                list_id=list_id,
                subscriber_hash=subscriber_hash,
                data={
                    'email_address': customer.row.email,
                    'status': 'subscribed',
                    'status_if_new': 'pending',
                    'merge_fields': {
                        'FNAME': customer.row.first_name,
                        'LNAME': customer.row.last_name,
                    }
                })
            message = T('Subscription successful, please check your inbox')
        except MailChimpError as e:
            message = T(
                "We encountered an error while trying to subscribe you to this list, please try again later."
            )

        return message
Example #4
0
    def get_classcards(self, auth_user_id=None, public_only=True):
        """
            :param public_only: Defines whether or not to show only public classcards, True by default
                                False means all cards are returned
            Returns classcards for school
        """
        from tools import OsTools

        db = current.db
        os_tools = OsTools()

        allow_trial_for_existing_customers = os_tools.get_sys_property(
            'shop_allow_trial_cards_for_existing_customers')

        query = (db.school_classcards.Archived == False)
        if public_only:
            query &= (db.school_classcards.PublicCard == True)

        if auth_user_id and allow_trial_for_existing_customers != 'on':
            from os_customer import Customer

            customer = Customer(auth_user_id)
            has_or_had_subscription = customer.get_has_or_had_subscription()
            has_or_had_card = customer.get_has_or_had_classcard()

            if has_or_had_card or has_or_had_subscription:
                query &= (db.school_classcards.Trialcard == False)

        return db(query).select(db.school_classcards.ALL,
                                orderby=db.school_classcards.Trialcard
                                | db.school_classcards.Name)
Example #5
0
    def list_member_delete(self, list_id, cuID):
        """
            Delete a member from a list
        """
        from os_customer import Customer
        customer = Customer(cuID)

        mailchimp = self.get_client()

        mailchimp.lists.members.delete(
            list_id=list_id, subscriber_hash=customer.get_email_hash('md5'))
Example #6
0
    def _classes_reservation_add_get_button(self, clsID):
        """
            Returns add button for a customer to add a reservation
        """
        from os_customer import Customer
        from os_gui import OsGui
        os_gui = OsGui()

        session = current.session
        DATE_FORMAT = current.DATE_FORMAT

        date = session.customers_classes_reservation_add_vars['date']
        date_formatted = date.strftime(DATE_FORMAT)
        cuID = session.customers_classes_reservation_add_vars['cuID']
        customer = Customer(cuID)

        add = os_gui.get_button('add',
                                URL('classes',
                                    'reservation_add_choose',
                                    vars={
                                        'cuID': cuID,
                                        'clsID': clsID,
                                        'date': date_formatted
                                    }),
                                btn_size='btn-sm',
                                _class="pull-right")

        return add
    def get_barcode_label(self):
        """
            Print friendly display of a barcode label
        """
        from os_customer import Customer

        get_sys_property = current.globalenv['get_sys_property']
        response = current.response

        customer = Customer(self.row.auth_customer_id)

        template = get_sys_property('branding_default_template_barcode_label_membership') or 'barcode_label_membership/default.html'
        template_file = 'templates/' + template

        if not self.row.Barcode:
            self.set_date_id_and_barcode()
        barcode_image_url = URL('default', 'download', args=self.row.Barcode, host=True, scheme=True)

        html = response.render(template_file,
                               dict(customer=customer.row,
                                    membership=self.row,
                                    DATE_FORMAT=current.DATE_FORMAT,
                                    barcode_image_url=barcode_image_url,
                                    logo=self._get_barcode_label_get_logo()))

        return html
Example #8
0
    def set_customer_info(self, cuID):
        """
            Set customer information for an invoice
        """
        from os_customer import Customer

        customer = Customer(cuID)

        address = ''
        if customer.row.address:
            address = ''.join([address, customer.row.address, '\n'])
        if customer.row.city:
            address = ''.join([address, customer.row.city, ' '])
        if customer.row.postcode:
            address = ''.join([address, customer.row.postcode, '\n'])
        if customer.row.country:
            address = ''.join([address, customer.row.country])

        list_name = customer.row.full_name
        if customer.row.company:
            list_name = customer.row.company

        self.invoice.update_record(
            CustomerCompany=customer.row.company,
            CustomerCompanyRegistration=customer.row.company_registration,
            CustomerCompanyTaxRegistration=customer.row.
            company_tax_registration,
            CustomerName=customer.row.full_name,
            CustomerListName=list_name,
            CustomerAddress=address,
        )

        self.on_update()
Example #9
0
    def get_mailing_list_customer_subscription_status(self, mailchimp, list_id,
                                                      cuID):
        """
        :param: mailchimp: MailChimp object (mailchimp3)
        :param cuID: db.auth_user.id
        :return: boolean
        """

        import hashlib
        from os_customer import Customer

        customer = Customer(cuID)
        subscriber_hash = customer.get_email_hash('md5')
        try:
            member = mailchimp.lists.members.get(
                list_id=list_id, subscriber_hash=subscriber_hash)
            return member['status']
        except MailChimpError as e:
            return 'error'
Example #10
0
    def on_update(self):
        """

        :return:
        """
        from os_customer import Customer
        from os_exact_online import OSExactOnline

        os_customer = Customer(self.row.auth_customer_id)

        os_eo = OSExactOnline()
Example #11
0
    def add_get_form(self, cuID, csID=None, cmID=None, full_width=True):
        """
            Returns add form for an invoice
        """
        from os_customer import Customer
        from os_invoice import Invoice

        self._add_get_form_permissions_check()

        db = current.db
        T = current.T

        customer = Customer(cuID)
        self._add_get_form_set_default_values_customer(customer)
        self._add_get_form_enable_minimal_fields()
        if csID:
            self._add_get_form_enable_subscription_fields(csID)
        if cmID:
            self._add_get_form_enable_membership_fields(cmID)

        form = SQLFORM(db.invoices, formstyle='bootstrap3_stacked')

        elements = form.elements('input, select, textarea')
        for element in elements:
            element['_form'] = "invoice_add"

        form_element = form.element('form')
        form['_id'] = 'invoice_add'

        if form.process().accepted:
            iID = form.vars.id
            invoice = Invoice(
                iID
            )  # This sets due date and Invoice (calls invoice.on_create() #
            invoice.link_to_customer(cuID)
            self._add_reset_list_status_filter()

            if csID:
                invoice.link_to_customer_subscription(csID)
                invoice.item_add_subscription(form.vars.SubscriptionYear,
                                              form.vars.SubscriptionMonth)

            if cmID:
                invoice.item_add_membership(cmID,
                                            form.vars.MembershipPeriodStart,
                                            form.vars.MembershipPeriodEnd)

            redirect(URL('invoices', 'edit', vars={'iID': iID}))

        # So the grids display the fields normally
        for field in db.invoices:
            field.readable = True

        return form
Example #12
0
    def _get_subscriptions_formatted_button_to_cart(
            self, ssuID, school_memberships_id, customer_has_membership,
            customer_subscriptions_ids):
        """
            Get button to add card to shopping cart
        """
        from tools import OsTools
        from os_customer import Customer

        db = current.db
        auth = current.auth
        TODAY_LOCAL = current.TODAY_LOCAL
        os_gui = current.globalenv['os_gui']
        T = current.T

        customer = Customer(auth.user.id)
        memberships = customer.get_memberships_on_date(TODAY_LOCAL)
        ids = []
        for row in memberships:
            ids.append(row.id)

        if school_memberships_id and not school_memberships_id in ids:
            sm = db.school_memberships(school_memberships_id)
            return A(SPAN(T("Membership %s required" % sm.Name),
                          ' ',
                          os_gui.get_fa_icon('fa-arrow-right'),
                          _class='smaller_font'),
                     _href=URL('shop', 'memberships'))

        if ssuID in customer_subscriptions_ids:
            return SPAN(SPAN(T("You have this subscription"), _class='bold'),
                        BR(),
                        SPAN(
                            A(T("View invoices"),
                              _href=URL('profile', 'invoices'))),
                        _class='smaller_font')

        link = A(SPAN(os_gui.get_fa_icon('fa-shopping-cart fa-2x')),
                 _href=URL('subscription_terms', vars={'ssuID': ssuID}))

        return self._get_formatted_button_apply_accent_color(link)
    def on_create(self):
        """

        :return:
        """
        from os_customer import Customer
        from os_exact_online import OSExactOnline

        os_customer = Customer(self.row.auth_customer_id)

        os_eo = OSExactOnline()
        os_eo.create_bankaccount(os_customer, self)
Example #14
0
    def create_dd_mandate(self, os_customer_payment_info, os_cpim):
        """
        :param os_customer_payment_info: payment info object
        :param os_cpim: payment info mandates object
        :return:
        """
        from exactonline.http import HTTPError
        from tools import OsTools
        from os_customer import Customer

        TODAY_LOCAL = current.TODAY_LOCAL
        os_tools = OsTools()
        authorized = os_tools.get_sys_property('exact_online_authorized')

        if not authorized:
            self._log_error('create', 'directdebitmandate', os_cpim.cpimID,
                            "Exact online integration not authorized")

            return

        api = self.get_api()

        customer = Customer(os_customer_payment_info.row.auth_customer_id)
        eoID = customer.row.exact_online_relation_id
        if not eoID:
            eoID = self.create_relation(customer)

        eo_bankaccount_id = os_customer_payment_info.row.exact_online_bankaccount_id

        # print os_customer_payment_info.row

        if not eo_bankaccount_id:
            eo_bankaccount_id = self.create_bankaccount(
                customer, os_customer_payment_info)

        mandate_dict = {
            'Account': eoID,
            'BankAccount': eo_bankaccount_id,
            'Reference': os_cpim.row.MandateReference,
            'SignatureDate': TODAY_LOCAL.strftime("%Y-%m-%d")
        }

        try:
            result = api.directdebitmandates.create(mandate_dict)
            os_cpim.row.exact_online_directdebitmandates_id = result['ID']
            os_cpim.row.update_record()

        except HTTPError as e:
            error = True
            self._log_error('create', 'mandate',
                            os_customer_payment_info.cpiID, e)
Example #15
0
    def _render_email_workshops_info_mail(self, wspc, wsp, ws):
        """
        :param template_content: Mail content
        :param workshops_products_id: db.workshops_products.id
        :return: mail body for workshop
        """
        from os_customer import Customer

        db = current.db
        T = current.T
        DATE_FORMAT = current.DATE_FORMAT
        TIME_FORMAT = current.TIME_FORMAT
        customer = Customer(wspc.auth_customer_id)

        try:
            time_info = TR(
                TH(T('Date')),
                TD(ws.Startdate.strftime(DATE_FORMAT),
                   ' ',
                   ws.Starttime.strftime(TIME_FORMAT),
                   ' - ',
                   ws.Enddate.strftime(DATE_FORMAT),
                   ' ',
                   ws.Endtime.strftime(TIME_FORMAT),
                   _align="left"))
        except AttributeError:
            time_info = ''

        description = TABLE(TR(TH(T('Ticket')), TD(wsp.Name, _align="left")),
                            time_info,
                            _cellspacing="0",
                            _cellpadding='5px',
                            _width='100%',
                            border="0")

        wsm = db.workshops_mail(workshops_id=ws.id)
        try:
            content = wsm.MailContent
        except AttributeError:
            content = ''

        image = IMG(_src=URL('default',
                             'download',
                             ws.picture,
                             scheme=True,
                             host=True),
                    _style="max-width:500px")

        return dict(content=DIV(image, BR(), BR(), XML(content)),
                    description=description)
Example #16
0
    def book_classes(self, csID, date_from, date_until=None):
        """
        :param csID: db.customers_subscriptions.id
        :param date_from: datetime.date
        :param date_until: datetime.date
        :return: Integer - number of classes booked
        """
        from os_attendance_helper import AttendanceHelper
        from os_customer import Customer
        from os_customer_subscription import CustomerSubscription

        # Check subscription credits, if none, don't do anything
        credits = 0
        customer = Customer(self.row.auth_customer_id)

        cs = CustomerSubscription(csID)
        credits += cs.get_credits_balance()

        # Get list of classes for customer in a given month, based on reservations
        upcoming_classes = self.get_classes(date_from, date_until)
        ah = AttendanceHelper()
        classes_booked = 0
        while credits > 0 and len(upcoming_classes):
            # Sign in to a class
            ##
            # remove this reservation from the list, as we have just booked it, so it won't be booked again using
            # another subscription
            ##
            cls = upcoming_classes.pop(
                0
            )  # always get the first in the list, we pop all classes already booked
            ah.attendance_sign_in_subscription(self.row.auth_customer_id,
                                               cls['clsID'], cs.cs.id,
                                               cls['date'])

            classes_booked += 1

            # Subtract one credit from current balance in this object (self.add_credists_balance)
            credits -= 1

        return classes_booked
Example #17
0
    def update_sales_entry(self, os_invoice):
        """
        :param os_customer: OsCustomer object
        :return: None
        """
        from exactonline.resource import GET

        from os_customer import Customer
        from tools import OsTools

        os_tools = OsTools()
        authorized = os_tools.get_sys_property('exact_online_authorized')

        if not authorized:
            self._log_error('update', 'sales_entry', os_invoice.invoice.id,
                            "Exact online integration not authorized")

            return

        items = os_invoice.get_invoice_items_rows()
        if not len(items):
            return  # Don't do anything for invoices without items

        eoseID = os_invoice.invoice.ExactOnlineSalesEntryID

        if not eoseID:
            self.create_sales_entry(os_invoice)
            return

        import pprint

        from ConfigParser import NoOptionError
        from exactonline.http import HTTPError

        storage = self.get_storage()
        api = self.get_api()
        cuID = os_invoice.get_linked_customer_id()
        os_customer = Customer(os_invoice.get_linked_customer_id())

        try:
            selected_division = int(storage.get('transient', 'division'))
        except NoOptionError:
            selected_division = None

        amounts = os_invoice.get_amounts()

        remote_journal = os_invoice.invoice_group.JournalID
        invoice_date = os_invoice.invoice.DateCreated
        is_credit_invoice = os_invoice.is_credit_invoice()
        local_invoice_number = os_invoice.invoice.id
        payment_method = os_invoice.get_payment_method()

        invoice_data = {
            'AmountDC': str(amounts.TotalPriceVAT),  # DC = default currency
            'AmountFC': str(amounts.TotalPriceVAT),  # FC = foreign currency
            'EntryDate': invoice_date.strftime(
                '%Y-%m-%dT%H:%M:%SZ'),  # pretend we're in UTC
            'Customer': os_customer.row.exact_online_relation_id,
            'Description': os_invoice.invoice.Description,
            'Journal': remote_journal,  # 70 "Verkoopboek"
            'ReportingPeriod': invoice_date.month,
            'ReportingYear': invoice_date.year,
            'VATAmountDC': str(amounts.VAT),
            'VATAmountFC': str(amounts.VAT),
            'YourRef': local_invoice_number,
        }

        if payment_method and payment_method.AccountingCode:
            invoice_data['PaymentCondition'] = payment_method.AccountingCode

        if is_credit_invoice:
            invoice_data['Type'] = 21

        error = False

        try:
            result = api.invoices.update(eoseID, invoice_data)
            # print "Update invoice result:"
            # pp = pprint.PrettyPrinter(depth=6)
            # pp.pprint(result)

            self.update_sales_entry_lines(os_invoice)

        except HTTPError as e:
            error = True
            self._log_error('create', 'sales_entry', os_invoice.invoice.id, e)

        if error:
            return False
Example #18
0
    def customers_memberships_renew_expired(self, year, month):
        """
            Checks if a subscription exceeds the expiration of a membership.
            If so it creates a new membership and an invoice for it for the customer
        """
        from general_helpers import get_last_day_month
        from datetime import timedelta
        from os_customer import Customer
        from os_invoice import Invoice
        from os_school_membership import SchoolMembership

        T = current.T
        db = current.db
        DATE_FORMAT = current.DATE_FORMAT

        year = int(year)
        month = int(month)

        firstdaythismonth = datetime.date(year, month, 1)
        lastdaythismonth  = get_last_day_month(firstdaythismonth)
        firstdaynextmonth = lastdaythismonth + datetime.timedelta(days=1)

        query = (db.customers_memberships.Enddate >= firstdaythismonth) & \
                (db.customers_memberships.Enddate <= lastdaythismonth)

        rows = db(query).select(
            db.customers_memberships.ALL
        )

        renewed = 0

        for row in rows:
            new_cm_start = row.Enddate + datetime.timedelta(days=1)

            # Check if a subscription will be active next month for customer
            # if so, add another membership
            customer = Customer(row.auth_customer_id)

            # Check if a new membership hasn't ben added already
            if customer.has_membership_on_date(new_cm_start):
                continue

            # Ok all good, continue
            if customer.has_subscription_on_date(firstdaynextmonth, from_cache=False):
                new_cm_start = row.Enddate + datetime.timedelta(days=1)

                school_membership = SchoolMembership(row.school_memberships_id)

                school_membership.sell_to_customer(
                    row.auth_customer_id,
                    new_cm_start,
                    note=T("Renewal for membership %s" % row.id),
                    invoice=True,
                    payment_methods_id=row.payment_methods_id
                )

                renewed += 1
            # else:
            #
            #     print 'no subscription'
            # print renewed

        ##
        # For scheduled tasks db connection has to be committed manually
        ##
        db.commit()

        return T("Memberships renewed") + ': ' + unicode(renewed)
Example #19
0
    def get_classcards_formatted(self,
                                 auth_user_id=None,
                                 public_only=True,
                                 per_row=3,
                                 link_type=None):
        """
            :param public_only: show only public cards - Default: True
            :param per_row: Number of cards in each row - Default 4. Allowed values: [3, 4]
            :param link_type: Specified what kind of link will be shown in the footer of each classcard.
                Allowed values: ['backend', 'shop']
                - backend adds a modal to choose date
                - shop adds a button to add the card to the shopping cart
            Returns classcards formatted in BS3 style

        """
        def get_validity(row):
            """
                takes a db.school_classcards() row as argument
            """
            validity = SPAN(unicode(row.Validity), ' ')

            validity_in = represent_validity_units(row.ValidityUnit, row)
            if row.Validity == 1:  # Cut the last 's"
                validity_in = validity_in[:-1]

            validity.append(validity_in)

            return validity

        from os_customer import Customer

        TODAY_LOCAL = current.TODAY_LOCAL
        os_gui = current.globalenv['os_gui']
        T = current.T

        customer_has_membership = False
        if auth_user_id:
            customer = Customer(auth_user_id)
            customer_has_membership = customer.has_membership_on_date(
                TODAY_LOCAL)

        if per_row == 3:
            card_class = 'col-md-4'
        elif per_row == 4:
            card_class = 'col-md-3'
        else:
            raise ValueError('Incompatible value: per_row has to be 3 or 4')

        rows = self.get_classcards(public_only=public_only)

        cards = DIV()
        display_row = DIV(_class='row')
        row_item = 0

        for i, row in enumerate(rows):
            repr_row = list(rows[i:i + 1].render())[0]

            card_name = max_string_length(row.Name, 37)
            validity = get_validity(row)

            card_content = TABLE(TR(TD(T('Validity')), TD(validity)),
                                 TR(TD(T('Classes')), TD(repr_row.Classes)),
                                 TR(TD(T('Price')), TD(repr_row.Price)),
                                 TR(TD(T('Description')),
                                    TD(repr_row.Description or '')),
                                 _class='table')

            if row.Trialcard:
                panel_class = 'box-success'
            else:
                panel_class = 'box-primary'

            footer_content = ''
            if link_type == 'shop':
                footer_content = self._get_classcards_formatted_button_to_cart(
                    row.id, row.MembershipRequired, customer_has_membership)

            card = DIV(os_gui.get_box_table(card_name,
                                            card_content,
                                            panel_class,
                                            show_footer=True,
                                            footer_content=footer_content),
                       _class=card_class)

            display_row.append(card)

            row_item += 1

            if row_item == per_row or i == (len(rows) - 1):
                cards.append(display_row)
                display_row = DIV(_class='row')

                row_item = 0

        return cards
Example #20
0
    def get_subscriptions_formatted(self,
                                    auth_customer_id=None,
                                    per_row=3,
                                    public_only=True,
                                    link_type='shop'):
        """
            :param public: boolean, defines whether to show only public or all subscriptions
            :return: list of school_subscriptions formatted for shop
        """
        from openstudio.os_school_subscription import SchoolSubscription
        from openstudio.os_customer import Customer

        TODAY_LOCAL = current.TODAY_LOCAL
        os_gui = current.globalenv['os_gui']
        T = current.T

        customer_has_membership = False
        customer_subscriptions_ids = []
        if auth_customer_id:
            customer = Customer(auth_customer_id)
            customer_has_membership = customer.has_membership_on_date(
                TODAY_LOCAL)
            customer_subscriptions_ids = customer.get_school_subscriptions_ids_on_date(
                TODAY_LOCAL)

        if per_row == 3:
            card_class = 'col-md-4'
        elif per_row == 4:
            card_class = 'col-md-3'
        else:
            raise ValueError('Incompatible value: per_row has to be 3 or 4')

        rows = self.get_subscriptions(public_only=public_only)

        subscriptions = DIV()
        display_row = DIV(_class='row')
        row_item = 0

        for i, row in enumerate(rows):
            repr_row = list(rows[i:i + 1].render())[0]

            ssu = SchoolSubscription(row.id)
            name = max_string_length(row.Name, 33)

            classes = ''
            if row.Unlimited:
                classes = T('Unlimited')
            elif row.SubscriptionUnit == 'week':
                classes = SPAN(unicode(row.Classes) + ' / ' + T('Week'))
            elif row.SubscriptionUnit == 'month':
                classes = SPAN(unicode(row.Classes) + ' / ' + T('Month'))

            subscription_content = TABLE(
                TR(TD(T('Classes')), TD(classes)),
                TR(TD(T('Monthly')),
                   TD(ssu.get_price_on_date(datetime.date.today()))),
                TR(TD(T('Description')), TD(row.Description or '')),
                _class='table')

            panel_class = 'box-primary'

            footer_content = ''
            if link_type == 'shop':
                footer_content = self._get_subscriptions_formatted_button_to_cart(
                    row.id, row.MembershipRequired, customer_has_membership,
                    customer_subscriptions_ids)

            subscription = DIV(os_gui.get_box_table(
                name,
                subscription_content,
                panel_class,
                show_footer=True,
                footer_content=footer_content),
                               _class=card_class)

            display_row.append(subscription)

            row_item += 1

            if row_item == per_row or i == (len(rows) - 1):
                subscriptions.append(display_row)
                display_row = DIV(_class='row')
                row_item = 0

        return subscriptions
Example #21
0
    def item_add_class(self, cuID, caID, clsID, date, product_type):
        """
        Add invoice item when checking in to a class

        :param cuID: db.auth_user.id
        :param caID: db.classes_attendance.id
        :param clsID: db.classes.id
        :param date: datetime.date (class date)
        :param product_type: has to be 'trial' or 'dropin'
        :return:
        """
        from os_customer import Customer
        from os_class import Class

        db = current.db
        DATE_FORMAT = current.DATE_FORMAT
        T = current.T

        date_formatted = date.strftime(DATE_FORMAT)

        if product_type not in ['trial', 'dropin']:
            raise ValueError("Product type has to be 'trial' or 'dropin'.")

        customer = Customer(cuID)
        cls = Class(clsID, date)
        prices = cls.get_prices()

        has_membership = customer.has_membership_on_date(date)

        if product_type == 'dropin':
            price = prices['dropin']
            tax_rates_id = prices['dropin_tax_rates_id']
            glaccount = prices['dropin_glaccount']
            costcenter = prices['dropin_costcenter']

            if has_membership and prices['dropin_membership']:
                price = prices['dropin_membership']
                tax_rates_id = prices['dropin_tax_rates_id_membership']

            description = cls.get_invoice_order_description(
                2)  # 2 = drop in class

        elif product_type == 'trial':
            price = prices['trial']
            tax_rates_id = prices['trial_tax_rates_id']
            glaccount = prices['trial_glaccount']
            costcenter = prices['trial_costcenter']

            if has_membership and prices['trial_membership']:
                price = prices['trial_membership']
                tax_rates_id = prices['trial_tax_rates_id_membership']

            description = cls.get_invoice_order_description(
                1)  # 1 = trial class

        # link invoice to attendance
        self.link_to_classes_attendance(caID)

        next_sort_nr = self.get_item_next_sort_nr()
        iiID = db.invoices_items.insert(invoices_id=self.invoices_id,
                                        ProductName=T("Class"),
                                        Description=description,
                                        Quantity=1,
                                        Price=price,
                                        Sorting=next_sort_nr,
                                        tax_rates_id=tax_rates_id,
                                        accounting_glaccounts_id=glaccount,
                                        accounting_costcenters_id=costcenter)

        self.link_to_customer(cuID)
        # This calls self.on_update()
        self.set_amounts()
Example #22
0
    def get_classcards_formatted(self,
                                 auth_user_id=None,
                                 public_only=True,
                                 per_row=3,
                                 link_type=None):
        """
            :param public_only: show only public cards - Default: True
            :param per_row: Number of cards in each row - Default 4. Allowed values: [3, 4]
            :param link_type: Specified what kind of link will be shown in the footer of each classcard.
                Allowed values: ['backend', 'shop']
                - backend adds a modal to choose date
                - shop adds a button to add the card to the shopping cart
            Returns classcards formatted in BS3 style

        """
        def get_validity(row):
            """
                takes a db.school_classcards() row as argument
            """
            validity = SPAN(unicode(row.Validity), ' ')

            validity_in = represent_validity_units(row.ValidityUnit, row)
            if row.Validity == 1:  # Cut the last 's"
                validity_in = validity_in[:-1]

            validity.append(validity_in)

            return validity

        from os_customer import Customer

        TODAY_LOCAL = current.TODAY_LOCAL
        os_gui = current.globalenv['os_gui']
        T = current.T

        customer_has_membership = False
        if auth_user_id:
            customer = Customer(auth_user_id)
            customer_has_membership = customer.has_membership_on_date(
                TODAY_LOCAL)

        if per_row == 3:
            card_class = 'col-md-4'
        elif per_row == 4:
            card_class = 'col-md-3'
        else:
            raise ValueError('Incompatible value: per_row has to be 3 or 4')

        rows = self.get_classcards(auth_user_id=auth_user_id,
                                   public_only=public_only)

        cards = DIV()
        display_row = DIV(_class='row')
        row_item = 0

        for i, row in enumerate(rows):
            repr_row = list(rows[i:i + 1].render())[0]

            card_name = max_string_length(row.Name, 37)
            validity = get_validity(row)

            over_trial_times = self._get_classcards_formatted_trialcard_over_times_available(
                row)

            description = repr_row.Description
            btn_cart = self._get_classcards_formatted_button_to_cart(
                row.id, row.school_memberships_id, customer_has_membership)
            if over_trial_times:
                description = T(
                    "You've reached the maximum number of times you can purchase this card."
                )
                btn_cart = SPAN(os_gui.get_fa_icon('fa-ban fa-2x'),
                                _class='grey')

            card = DIV(DIV(DIV(
                self._get_formatted_display_widget_header(
                    card_name, repr_row.Price)),
                           DIV(DIV(description, _class='col-md-12'),
                               _class='box-body'),
                           DIV(
                               DIV(DIV(DIV(H5(validity,
                                              _class="description-header"),
                                           SPAN(T("Validity"),
                                                _class="description-text"),
                                           _class="description-block"),
                                       _class="col-sm-4 border-right"),
                                   DIV(DIV(H5(repr_row.Classes,
                                              _class="description-header"),
                                           SPAN(T("Classes"),
                                                _class="description-text"),
                                           _class="description-block"),
                                       _class="col-sm-4 border-right"),
                                   DIV(DIV(H5(btn_cart,
                                              _class="description-header"),
                                           SPAN(T(""),
                                                _class="description-text"),
                                           _class="description-block"),
                                       _class="col-sm-4"),
                                   _class="row"),
                               _class="box-footer",
                           ),
                           _class="box box-widget widget-user"),
                       _class=card_class)

            display_row.append(card)

            row_item += 1

            if row_item == per_row or i == (len(rows) - 1):
                cards.append(display_row)
                display_row = DIV(_class='row')

                row_item = 0

        return cards
Example #23
0
    def get_subscriptions_formatted(self,
                                    auth_customer_id=None,
                                    per_row=3,
                                    public_only=True,
                                    link_type='shop'):
        """
            :param public: boolean, defines whether to show only public or all subscriptions
            :return: list of school_subscriptions formatted for shop
        """
        from general_helpers import get_last_day_month
        from openstudio.os_school_subscription import SchoolSubscription
        from openstudio.os_customer import Customer

        T = current.T
        TODAY_LOCAL = current.TODAY_LOCAL
        os_gui = current.globalenv['os_gui']
        get_sys_property = current.globalenv['get_sys_property']

        customer_has_membership = False
        customer_subscriptions_ids = []
        if auth_customer_id:
            startdate = TODAY_LOCAL
            shop_subscriptions_start = get_sys_property(
                'shop_subscriptions_start')
            if not shop_subscriptions_start == None:
                if shop_subscriptions_start == 'next_month':
                    startdate = get_last_day_month(
                        TODAY_LOCAL) + datetime.timedelta(days=1)

            customer = Customer(auth_customer_id)
            customer_has_membership = customer.has_membership_on_date(
                startdate)
            customer_subscriptions_ids = customer.get_school_subscriptions_ids_on_date(
                startdate)

        if per_row == 3:
            card_class = 'col-md-4'
        elif per_row == 4:
            card_class = 'col-md-3'
        else:
            raise ValueError('Incompatible value: per_row has to be 3 or 4')

        rows = self.get_subscriptions(public_only=public_only)

        subscriptions = DIV()
        display_row = DIV(_class='row')
        row_item = 0

        for i, row in enumerate(rows):
            repr_row = list(rows[i:i + 1].render())[0]

            ssu = SchoolSubscription(row.id)
            name = max_string_length(row.Name, 33)

            classes = ''
            classes_unit = ''
            classes_text = T("Classes")
            if row.Unlimited:
                classes = T('Unlimited')
                classes_unit = T("Classes")
            elif row.SubscriptionUnit == 'week':
                if row.Classes == 1:
                    classes_text = T("Class")
                classes = SPAN(unicode(row.Classes) + ' ' + classes_text)
                classes_unit = T("Per week")
            elif row.SubscriptionUnit == 'month':
                if row.Classes == 1:
                    classes_text = T("Class")
                classes = SPAN(unicode(row.Classes) + ' ' + classes_text)
                classes_unit = T("Per month")

            subscription = DIV(DIV(
                self._get_formatted_display_widget_header(
                    name, ssu.get_price_on_date(TODAY_LOCAL)),
                DIV(DIV(repr_row.Description, _class='col-md-12'),
                    _class='box-body'),
                DIV(
                    DIV(DIV(DIV(H5('Payment', _class="description-header"),
                                SPAN(T("Monthly"), _class="description-text"),
                                _class="description-block"),
                            _class="col-sm-4 border-right"),
                        DIV(DIV(H5(classes, _class="description-header"),
                                SPAN(classes_unit, _class="description-text"),
                                _class="description-block"),
                            _class="col-sm-4 border-right"),
                        DIV(DIV(H5(
                            self._get_subscriptions_formatted_button_to_cart(
                                row.id, row.school_memberships_id,
                                customer_has_membership,
                                customer_subscriptions_ids),
                            _class="description-header"),
                                SPAN(T(""), _class="description-text"),
                                _class="description-block"),
                            _class="col-sm-4"),
                        _class="row"),
                    _class="box-footer",
                ),
                _class="box box-widget widget-user"),
                               _class=card_class)

            # subscription_content = TABLE(TR(TD(T('Classes')),
            #                                 TD(classes)),
            #                              TR(TD(T('Monthly')),
            #                                 TD(ssu.get_price_on_date(datetime.date.today()))),
            #                              TR(TD(T('Description')),
            #                                 TD(row.Description or '')),
            #                              _class='table')
            #
            # panel_class = 'box-primary'
            #
            # footer_content = ''
            # if link_type == 'shop':
            #     footer_content = self._get_subscriptions_formatted_button_to_cart(
            #         row.id,
            #         row.MembershipRequired,
            #         customer_has_membership,
            #         customer_subscriptions_ids
            #     )
            #
            # subscription = DIV(os_gui.get_box_table(name,
            #                                         subscription_content,
            #                                         panel_class,
            #                                         show_footer=True,
            #                                         footer_content=footer_content),
            #                    _class=card_class)

            display_row.append(subscription)

            row_item += 1

            if row_item == per_row or i == (len(rows) - 1):
                subscriptions.append(display_row)
                display_row = DIV(_class='row')
                row_item = 0

        return subscriptions
Example #24
0
    def create_sales_entry(self, os_invoice):
        """
        :param os_customer: OsCustomer object
        :param os_invoice: OsInvoice Object
        :return:
        """
        from exactonline.resource import GET
        from os_customer import Customer
        from tools import OsTools

        db = current.db
        os_tools = OsTools()
        authorized = os_tools.get_sys_property('exact_online_authorized')

        if not authorized:
            self._log_error('create', 'sales_entry', os_invoice.invoice.id,
                            "Exact online integration not authorized")

            return

        items = os_invoice.get_invoice_items_rows()
        if not len(items):
            return  # Don't do anything for invoices without items

        import pprint

        from ConfigParser import NoOptionError
        from exactonline.http import HTTPError

        storage = self.get_storage()
        api = self.get_api()
        cuID = os_invoice.get_linked_customer_id()
        os_customer = Customer(os_invoice.get_linked_customer_id())
        eoID = os_customer.row.exact_online_relation_id

        if not eoID:
            self._log_error(
                'create', 'sales_entry', os_invoice.invoice.id,
                "This customer is not linked to Exact Online - " +
                unicode(os_customer.row.id))
            return

        try:
            selected_division = int(storage.get('transient', 'division'))
        except NoOptionError:
            selected_division = None

        amounts = os_invoice.get_amounts()

        remote_journal = os_invoice.invoice_group.JournalID
        invoice_date = os_invoice.invoice.DateCreated
        is_credit_invoice = os_invoice.is_credit_invoice()
        local_invoice_number = os_invoice.invoice.id
        payment_method = os_invoice.get_payment_method()

        invoice_data = {
            'AmountDC': str(amounts.TotalPriceVAT),  # DC = default currency
            'AmountFC': str(amounts.TotalPriceVAT),  # FC = foreign currency
            'EntryDate': invoice_date.strftime(
                '%Y-%m-%dT%H:%M:%SZ'),  # pretend we're in UTC
            'Customer': eoID,
            'Description': os_invoice.invoice.Description,
            'Journal': remote_journal,  # 70 "Verkoopboek"
            'ReportingPeriod': invoice_date.month,
            'ReportingYear': invoice_date.year,
            'SalesEntryLines': self.format_os_sales_entry_lines(os_invoice),
            'VATAmountDC': str(amounts.VAT),
            'VATAmountFC': str(amounts.VAT),
            'YourRef': local_invoice_number,
        }

        if payment_method and payment_method.AccountingCode:
            invoice_data['PaymentCondition'] = payment_method.AccountingCode

        if is_credit_invoice:
            invoice_data['Type'] = 21

        error = False

        try:
            result = api.invoices.create(invoice_data)
            #
            # print "Create invoice result:"
            # pp = pprint.PrettyPrinter(depth=6)
            # pp.pprint(result)

            eoseID = result['EntryID']
            os_invoice.invoice.ExactOnlineSalesEntryID = eoseID
            os_invoice.invoice.InvoiceID = result['EntryNumber']
            os_invoice.invoice.update_record()

            uri = result[u'SalesEntryLines'][u'__deferred']['uri']
            entry_lines = api.restv1(GET(str(uri)))
            # pp.pprint(entry_lines)

            for i, line in enumerate(entry_lines):
                query = (db.invoices_items.invoices_id == os_invoice.invoice.id) & \
                        (db.invoices_items.Sorting == i + 1)
                db(query).update(ExactOnlineSalesEntryLineID=line['ID'])

        except HTTPError as e:
            error = True
            self._log_error('create', 'sales_entry', os_invoice.invoice.id, e)

        if error:
            return False

        return eoseID