Example #1
0
    def create_qb_invoice(self, qb_client):
        invoice = QuickBooksInvoice()
        line = SalesItemLine()
        line.LineNum = 1
        line.Description = self.description
        line.Amount = self.amount
        # line.ServiceDate = qb_date_format(datetime.date(2019, 1, 1))
        line.SalesItemLineDetail = SalesItemLineDetail()
        line.SalesItemLineDetail.Qty = 1
        line.SalesItemLineDetail.UnitPrice = self.amount
        item = Item.choose(["MF"], field="SKU", qb=qb_client)[0]

        line.SalesItemLineDetail.ItemRef = item.to_ref()
        invoice.Line.append(line)

        customer = Customer.get(self.organization.qbo_id, qb=qb_client)
        invoice.CustomerRef = customer.to_ref()

        # term = Term.choose(['Net 30'], field='Name', qb=qb_client)[0]
        # invoice.SalesTermRef = term

        # invoice.TotalAmt = self.amount
        invoice.save(qb=qb_client)

        print(invoice.Id)
    def test_to_ref(self):
        invoice = Invoice()
        invoice.DocNumber = 1
        invoice.Id = 2

        ref = invoice.to_ref()
        self.assertIsInstance(ref, Ref)
        self.assertEquals(ref.type, "Invoice")
        self.assertEquals(ref.name, 1)  # should be DocNumber
        self.assertEquals(ref.value, 2)  # should be Id
Example #3
0
    def test_to_LinkedTxn(self):
        invoice = Invoice()
        invoice.TotalAmt = 10
        invoice.Id = 1

        linked_txn = invoice.to_linked_txn()

        self.assertEquals(linked_txn.TxnId, invoice.Id)
        self.assertEquals(linked_txn.TxnType, "Invoice")
        self.assertEquals(linked_txn.TxnLineId, 1)
    def test_delete(self):
        # First create an invoice
        invoice = Invoice()

        line = SalesItemLine()
        line.LineNum = 1
        line.Description = "description"
        line.Amount = 100
        line.SalesItemLineDetail = SalesItemLineDetail()
        item = Item.all(max_results=1, qb=self.qb_client)[0]

        line.SalesItemLineDetail.ItemRef = item.to_ref()
        invoice.Line.append(line)

        customer = Customer.all(max_results=1, qb=self.qb_client)[0]
        invoice.CustomerRef = customer.to_ref()

        invoice.CustomerMemo = CustomerMemo()
        invoice.CustomerMemo.value = "Customer Memo"
        invoice.save(qb=self.qb_client)

        # Then delete
        invoice_id = invoice.Id
        invoice.delete(qb=self.qb_client)

        query_invoice = Invoice.filter(Id=invoice_id, qb=self.qb_client)
        self.assertEqual([], query_invoice)
Example #5
0
    def create_invoices(client, invoices):
        '''
        Given a set of existing invoices, fetch the invoice from QuickBooks, make a copy, update it
        with new values and then have QuickBooks save the new invoice. Invoices are not sent,
        and must be sent via the QuickBooks web interface.
        '''

        for invoice in invoices:
            invoice_list = Invoice.query(
                "select * from invoice where Id = '%s'" %
                invoice['base_invoice'],
                qb=client)
            if not invoice_list:
                flash("Cannot fetch old invoice!")
                break

            new_invoice = invoice_list[0]
            new_invoice.Id = None
            new_invoice.DocNumber = None
            new_invoice.DueDate = None
            new_invoice.TxnDate = None
            new_invoice.ShipDate = None
            new_invoice.EInvoiceStatus = None
            new_invoice.MetaData = None
            new_invoice.TotalAmt = None
            new_invoice.EmailStatus = "NeedToSend"
            new_invoice.Line[0].SalesItemLineDetail.Qty = invoice['qty']
            new_invoice.Line[0].SalesItemLineDetail.UnitPrice = invoice[
                'price']
            new_invoice.Line[0].Amount = "%d" % round(
                float(invoice['price']) * float(invoice['qty']))
            new_invoice.CustomField[1].StringValue = invoice['begin']
            new_invoice.CustomField[2].StringValue = invoice['end']
            new_invoice.save(qb=client)
Example #6
0
    def _set_location_in_invoices(self):
        """
        Change Location value in invoice to Sales
        contained in client's suffix field

        TODO: make it scriptable to run into a cron job
        """
        invoices = Invoice.filter(max_results=1000,
                                  order_by="DocNumber DESC",
                                  qb=self.client)

        for i in invoices:
            if i.DepartmentRef is None:
                c = Customer.get(i.CustomerRef.value, qb=self.client)
                if c.Suffix != "":
                    location = self._get_location(sales_name=c.Suffix)
                    if location is not None:
                        # print(f"INVOICE {i.DocNumber} ASSIGNED TO {c.Suffix} LOCATION ID {location.Id}")
                        i.DepartmentRef = location.to_ref()
                        i.save(qb=self.client)
                    else:
                        print(
                            f"[ERROR] Location IS NONE FOR {c.Suffix} OF {c}")
                else:
                    print(f"[ERROR] c.Suffix IS NONE FOR {c}")
        print(f"set_location_in_invoices ended")
Example #7
0
    def get_qbo_events(self):
        qb_client, profile = Profile.get_qb_client()

        user = User.objects.get(username="******")

        for offset in [1, 100, 200, 300]:
            try:
                invoices = QuickBooksInvoice.all(qb=qb_client, start_position=offset)
            except AuthorizationException:
                profile.is_active = False
                profile.save()

                return

            for qb_invoice in invoices:
                try:
                    org = Organization.objects.get(qbo_id=qb_invoice.CustomerRef.value)
                except Organization.DoesNotExist:
                    continue

                log, is_created = BillingLog.objects.get_or_create(
                    qbo_id=qb_invoice.Id,
                    log_type="create_invoice",
                    defaults={
                        "organization": org,
                        "user": user,
                        "amount": qb_invoice.TotalAmt,
                    },
                )

                if is_created:
                    log.pub_date = arrow.get(
                        qb_invoice.MetaData["LastUpdatedTime"]
                    ).datetime
                    log.save()

        payments = QuickBooksPayment.all(qb=qb_client)
        for qb_payment in payments:
            try:
                org = Organization.objects.get(qbo_id=qb_payment.CustomerRef.value)
            except Organization.DoesNotExist:
                continue

            log, is_created = BillingLog.objects.get_or_create(
                qbo_id=qb_payment.Id,
                log_type="create_payment",
                defaults={
                    "organization": org,
                    "user": user,
                    "amount": qb_payment.TotalAmt,
                },
            )

            if is_created:
                log.pub_date = arrow.get(
                    qb_payment.MetaData["LastUpdatedTime"]
                ).datetime
                log.save()
Example #8
0
    def test_create(self):
        invoice = Invoice()

        line = SaleItemLine()
        line.LineNum = 1
        line.Description = "description"
        line.Amount = 100
        line.SalesItemLineDetail = SalesItemLineDetail()
        item = Item.all(max_results=1, qb=self.qb_client)[0]

        line.SalesItemLineDetail.ItemRef = item.to_ref()
        invoice.Line.append(line)

        customer = Customer.all(max_results=1, qb=self.qb_client)[0]
        invoice.CustomerRef = customer.to_ref()

        invoice.CustomerMemo = CustomerMemo()
        invoice.CustomerMemo.value = "Customer Memo"
        invoice.save(qb=self.qb_client)

        query_invoice = Invoice.get(invoice.Id, qb=self.qb_client)

        self.assertEquals(query_invoice.CustomerRef.name, customer.DisplayName)
        self.assertEquals(query_invoice.CustomerMemo.value, "Customer Memo")
        self.assertEquals(query_invoice.Line[0].Description, "description")
        self.assertEquals(query_invoice.Line[0].Amount, 100.0)
Example #9
0
def invoice_search(invoice_number, customer, client=None):
    """
    invoice_number
        if == 1 then will force create a new one
        999999999 will search for any existing
        specific # will search for that invoice #
    """
    if client is None:
        client = get_quickbooks_client()
    invoice = None
    if invoice_number == "999999999":
        # search for any NeedToSend invoices for chapter
        #   however, can not filter on EmailStatus directly
        invoices = Invoice.query(
            select=
            f"select * from Invoice where balance > '0' AND CustomerRef = '{customer.Id}'",
            qb=client,
        )
        for invoice_test in invoices:
            if invoice_test.EmailStatus == "NeedToSend":
                invoice = invoice_test
                break
    elif invoice_number != "1" and invoice_number != "":
        # search for specific invoice number
        invoices = Invoice.query(
            select=
            f"select * from Invoice where DocNumber = '{invoice_number}' AND CustomerRef = '{customer.Id}'",
            qb=client,
        )
        if invoices:
            invoice = invoices[0]
    if invoice is None:
        invoice = Invoice()
        term = Term.filter(name="Two Weeks", qb=client)[0]
        linenumber_count = 1
        invoice.CustomerRef = customer.to_ref()
        invoice.AllowOnlineACHPayment = True
        invoice.BillEmail = customer.PrimaryEmailAddr
        invoice.EmailStatus = "NeedToSend"
        invoice.SalesTermRef = term.to_ref()
        invoice.CustomerMemo = CustomerMemo()
    else:
        linenumber_count = len(invoice.Line)
    return invoice, linenumber_count
    def test_create(self):
        invoice = Invoice()

        line = SaleItemLine()
        line.LineNum = 1
        line.Description = "description"
        line.Amount = 100
        line.SalesItemLineDetail = SalesItemLineDetail()
        item = Item.all(max_results=1, qb=self.qb_client)[0]

        line.SalesItemLineDetail.ItemRef = item.to_ref()
        invoice.Line.append(line)

        customer = Customer.all(max_results=1, qb=self.qb_client)[0]
        invoice.CustomerRef = customer.to_ref()

        invoice.CustomerMemo = CustomerMemo()
        invoice.CustomerMemo.value = "Customer Memo"
        invoice.save(qb=self.qb_client)

        query_invoice = Invoice.get(invoice.Id, qb=self.qb_client)

        self.assertEquals(query_invoice.CustomerRef.name, customer.DisplayName)
        self.assertEquals(query_invoice.CustomerMemo.value, "Customer Memo")
        self.assertEquals(query_invoice.Line[0].Description, "description")
        self.assertEquals(query_invoice.Line[0].Amount, 100.0)
Example #11
0
def verify_invoice(doc_number="", email=""):
    # checks QBO to ensure invoice number matches email provided
    # if match, returns QBO customer object attached to invoice
    # if mismatch, returns None
    refresh_stored_tokens()
    qb = fetch('qbclient')
    invoice_list = Invoice.filter(DocNumber=doc_number, qb=qb)
    if invoice_list:
        customers = Customer.filter(id=invoice_list[0].CustomerRef.value,
                                    qb=qb)
    else:
        return None
    if customers:
        if customers[0].PrimaryEmailAddr.Address.lower() == email.lower():
            return customers[0]
        else:
            return None
    else:
        return None
Example #12
0
    def test_unicode(self):
        invoice = Invoice()
        invoice.TotalAmt = 10

        self.assertEquals(str(invoice), "10")
 def test_email_sent_false(self):
     invoice = Invoice()
     invoice.EmailStatus = "NotSent"
     self.assertFalse(invoice.email_sent)
Example #14
0
    def index(self):
        '''
        Load all customers and 100 invoices and the correlate them.
        Customers get put into three bins: Ready to invoice, current (no need for an invoice) and WTF (we couldn't sort what should happen).
        Send all this to the caller to render.
        '''

        # Look up access tokens from sessions, or make the user login
        access_token = session.get('access_token', None)
        refresh_token = session.get('refresh_token', "")
        realm = session.get('realm', None)

        if not access_token or not refresh_token:
            session['realm'] = realm
            session['access_token'] = access_token
            session['refresh_token'] = refresh_token
            return render_template("quickbooks/login.html")

        refreshed = False
        while True:
            # Now fetch customers and invoices
            try:
                client = get_client(realm, refresh_token)
                customers = Customer.filter(Active=True, qb=client)
                invoices = Invoice.query(
                    "select * from invoice order by metadata.createtime desc maxresults 300",
                    qb=client)
                break

            except quickbooks.exceptions.AuthorizationException as err:
                current_app.logger.error("Auth failed. Refresh token: '%s'" %
                                         client.refresh_token)
                if not refreshed:
                    current_app.logger.debug("Auth failed, trying refresh")
                    refreshed = True
                    current_app.quickbooks_auth_client.refresh()
                    continue

                flash("Authorization failed, please try again: %s" % err)
                current_app.logger.debug(
                    "Auth failed, logging out, starting over.")
                session['access_token'] = None
                return redirect(url_for("quickbooks/.index"))

            except quickbooks.exceptions.QuickbooksException as err:
                flash("Query failed: %s" % err)
                raise InternalServerError

        # Calculate a pile of dates, based on today date. Figure out
        # which quarter we're in, and the dates of this and 2 prior quarters
        dt = datetime.datetime.now()
        today = dt.strftime("%m-%d-%Y")
        q = (dt.month - 1) // 3
        pq = (q + 3) % 4
        ppq = (pq + 3) % 4

        year = dt.year
        (q_start, q_end) = self.calculate_quarter_dates(year, q)
        if pq > q:
            year -= 1
        (pq_start, pq_end) = self.calculate_quarter_dates(year, pq)
        if ppq > pq:
            year -= 1
        (ppq_start, ppq_end) = self.calculate_quarter_dates(year, ppq)

        # Iterate over all the invoices, parse their dates and arrange them into the invoice dict, by customer
        invoice_dict = {}
        for invoice in invoices:
            customer_id = invoice.CustomerRef.value
            if customer_id not in invoice_dict:
                invoice_dict[customer_id] = []

            create_time = parse(invoice.TxnDate).strftime("%m-%d-%Y")
            try:
                begin_dt = parse(invoice.CustomField[1].StringValue)
                begin_date = begin_dt.strftime("%m-%d-%Y")
            except ValueError:
                begin_date = ""
                begin_dt = None

            try:
                end_dt = parse(invoice.CustomField[2].StringValue)
                end_date = end_dt.strftime("%m-%d-%Y")
            except ValueError:
                end_date = ""
                end_dt = None

            try:
                tier = invoice.Line[0].SalesItemLineDetail.ItemRef.name
            except AttributeError:
                tier = ""

            invoice_dict[customer_id].append({
                'customer':
                customer_id,
                'date':
                create_time,
                'sortdate':
                invoice.TxnDate,
                'id':
                invoice.Id,
                'amount':
                invoice.TotalAmt,
                'begin':
                begin_date,
                'begin_dt':
                begin_dt,
                'end':
                end_date,
                'end_dt':
                end_dt,
                'service':
                tier,
                'number':
                invoice.DocNumber,
                'currency':
                invoice.CurrencyRef.value,
                'qty':
                invoice.Line[0].SalesItemLineDetail.Qty,
                'price':
                invoice.Line[0].SalesItemLineDetail.UnitPrice
            })

        # Finally, classify customers into the three bins
        ready_to_invoice = []
        wtf = []
        current = []
        for customer in customers:
            invoices = invoice_dict.get(customer.Id, [])
            invoices = sorted(invoices,
                              key=lambda invoice: invoice['sortdate'],
                              reverse=True)

            # If there are comments in the customer notes field that indicates # arrears or # donotinvoice,
            # we use those as hints to properly create new invoices or to ignore customers
            name = customer.DisplayName or customer.CompanyName
            desc = customer.Notes.lower()
            try:
                price = invoices[0]['price']
            except IndexError:
                price = 0

            if desc.find("arrears") >= 0:
                name += " (arrears)"
                is_arrears = True
            else:
                is_arrears = False

            if desc.find("donotinvoice") >= 0:
                do_not_invoice = True
                name += " (do not invoice)"
            else:
                do_not_invoice = False

            # create the customer object, ready for saving
            cust = {'name': name, 'invoices': invoices, 'id': customer.Id}
            if do_not_invoice:
                current.append(cust)
                continue

            # If there are no previous invoices, go WTF!
            if not invoices:
                wtf.append(cust)
                continue

            # If this customer should not be invoiced or if the last invoice corresponds to this quarter,
            # place them into the current bin
            if do_not_invoice or (invoices[0]['begin'] == q_start
                                  and invoices[0]['end'] == q_end):
                current.append(cust)
                continue

            # If the customer is not invoiced in arrears and the last invoice looks to be from last quarter -> ready to invoice
            if not is_arrears and invoices[0][
                    'begin'] == pq_start and invoices[0]['end'] == pq_end:
                self.add_new_invoice(invoices[0], cust, q_start, q_end, today,
                                     3, price)
                ready_to_invoice.append(cust)
                continue

            # If the customer is not invoiced in arrears and the last invoice is a partial invoice last quarter -> ready to invoice new customer
            if not is_arrears and invoices[0]['end'] == pq_end:
                cust['name'] += " (new customer)"
                self.add_new_invoice(invoices[0], cust, q_start, q_end, today,
                                     3, price)
                ready_to_invoice.append(cust)
                continue

            # If the customer is invoiced in arrears and the last invoice looks to be from last last quarter -> ready to invoice
            if is_arrears and invoices[0]['begin'] == ppq_start and invoices[
                    0]['end'] == ppq_end:
                self.add_new_invoice(invoices[0], cust, pq_start, pq_end,
                                     today, 3, price)
                ready_to_invoice.append(cust)
                continue

            # If the customer is invoiced in arrears and the last invoice was from the prior quarter -> current
            if is_arrears and invoices[0]['begin'] == pq_start and invoices[0][
                    'end'] == pq_end:
                current.append(cust)
                continue

            # Check to see if this is an annual invoice
            try:
                end_dt = invoices[0]['end_dt']
                begin_dt = invoices[0]['begin_dt']
                delta = end_dt - begin_dt
                if delta.days > 359 and delta.days < 366:
                    cust['name'] += " (annual)"
                    if time.mktime(end_dt.timetuple()) <= time.time():
                        end_date = datetime.date(
                            end_dt.year + 1, end_dt.month,
                            end_dt.day).strftime("%m-%d-%Y")
                        begin_date = datetime.date(
                            begin_dt.year + 1, begin_dt.month,
                            begin_dt.day).strftime("%m-%d-%Y")
                        self.add_new_invoice(invoices[0], cust, begin_date,
                                             end_date, today, 12, price)
                        ready_to_invoice.append(cust)
                    else:
                        current.append(cust)

                    continue
            except TypeError:
                wtf.append(cust)
                continue

            # If the end date is after the curent date, then consider it current
            if time.mktime(end_dt.timetuple()) > time.time():
                current.append(cust)
                continue

            # Everyone else, WTF?
            wtf.append(cust)

        return render_template("quickbooks/index.html",
                               ready=ready_to_invoice,
                               wtf=wtf,
                               current=current)
Example #15
0
    def get_qbo_events(self):
        qb_client, profile = Profile.get_qb_client()

        user = User.objects.get(username="******")

        for offset in [1, 100, 200, 300, 400, 500, 600, 700]:
            try:
                invoices = QuickBooksInvoice.all(qb=qb_client,
                                                 start_position=offset)
            except AuthorizationException:
                profile.is_active = False
                profile.save()

                return

            for qb_invoice in invoices:
                try:
                    org = Organization.objects.get(
                        qbo_id=qb_invoice.CustomerRef.value)
                except Organization.DoesNotExist:
                    continue

                log, is_created = BillingLog.objects.get_or_create(
                    qbo_id=qb_invoice.Id,
                    log_type="create_invoice",
                    defaults={
                        "organization": org,
                        "user": user,
                        "amount": qb_invoice.TotalAmt,
                    },
                )

                if is_created:
                    log.pub_date = arrow.get(
                        qb_invoice.MetaData["LastUpdatedTime"]).datetime
                    log.created_date = arrow.get(
                        qb_invoice.MetaData["CreateTime"]).date()
                    log.save()
                else:
                    log.invoice_year = log.pub_date.year
                    log.created_date = arrow.get(
                        qb_invoice.MetaData["CreateTime"]).date()
                    log.save()

        for offset in [1, 100, 200, 300, 400, 500, 600, 700]:
            payments = QuickBooksPayment.all(qb=qb_client,
                                             start_position=offset)
            for qb_payment in payments:
                try:
                    org = Organization.objects.get(
                        qbo_id=qb_payment.CustomerRef.value)
                except Organization.DoesNotExist:
                    continue

                log, is_created = BillingLog.objects.get_or_create(
                    qbo_id=qb_payment.Id,
                    log_type="create_payment",
                    defaults={
                        "organization": org,
                        "user": user,
                        "amount": qb_payment.TotalAmt,
                    },
                )

                if is_created:
                    log.pub_date = arrow.get(
                        qb_payment.MetaData["LastUpdatedTime"]).datetime
                    log.save()
Example #16
0
def post_payment(doc_number="", amount=0, btcp_id=''):
    # post payment to QBO
    '''
    doc_number: QBO invoice number
    amount: payment amount
    btcp_id: BTCPay invoice number
    '''
    refresh_stored_tokens()
    qb = fetch('qbclient')
    # check if BTCPay is already in QBO as a pmt method
    pmt_method_list = PaymentMethod.filter(Name="BTCPay", qb=qb)
    try:
        # if BTCPay is already in QBO, set it as pmt method
        pmt_method = pmt_method_list[0]
    except IndexError:
        # if BTCPay is not in QBO, create it as pmt method
        new_pmt_method = PaymentMethod()
        new_pmt_method.Name = "BTCPay"
        new_pmt_method.save(qb=qb)
        # set newly created BTCPay pmt method as pmt method
        pmt_method_list = PaymentMethod.filter(Name="BTCPay", qb=qb)
        pmt_method = pmt_method_list[0]
    # check if QBO has asset acct for Bitcoin-BTCPay
    deposit_acct_list = Account.filter(Name="Bitcoin-BTCPay", qb=qb)
    try:
        # if Bitcoin-BTCPay is in QBO, set as deposit acct
        deposit_acct = deposit_acct_list[0]
    except IndexError:
        # if Bitcoin-BTCPay is not in QBO, create it as deposit acct
        new_acct = Account()
        new_acct.Name = "Bitcoin-BTCPay"
        new_acct.AccountSubType = "OtherCurrentAssets"
        new_acct.save(qb=qb)
        # set newly created Bitcoin-BTCPay acct as deposit acct
        deposit_acct_list = Account.filter(Name="Bitcoin-BTCPay", qb=qb)
        deposit_acct = deposit_acct_list[0]
    # pull list of invoice objects matching invoice number from QBO
    invoice_list = Invoice.filter(DocNumber=doc_number, qb=qb)
    try:
        # only one invoice can match the inv #, so pull it from list
        invoice = invoice_list[0]
    except IndexError:
        app.logger.warning(f'No such invoice exists: {doc_number}')
        return None
    else:
        # convert invoice object to linked invoice object
        linked_invoice = invoice.to_linked_txn()
        description = 'BTCPay: ' + btcp_id
        payment_line = PaymentLine()
        payment_line.Amount = amount
        payment_line.Description = description
        # attach linked invoice object to payment line object
        payment_line.LinkedTxn.append(linked_invoice)
        payment = Payment()
        payment.TotalAmt = amount
        payment.CustomerRef = invoice.CustomerRef
        # create deposit acct reference object from deposit acct object
        deposit_account_ref = Ref()
        deposit_account_ref.value = deposit_acct.Id
        # create pmt method reference object from pmt method object
        pmt_method_ref = Ref()
        pmt_method_ref.name = pmt_method.Name
        # attach pmt method ref, dep acct ref, and pmt line obj to pmt obj
        payment.PaymentMethodRef = pmt_method_ref
        payment.DepositToAccountRef = deposit_account_ref
        payment.Line.append(payment_line)
        payment.save(qb=qb)
        # save payment to temp redis store to fliter duplicates
        app.redis.set(btcp_id, 'payment', ex=21600)
        return "Payment Made: " + str(payment)
 def test_email_sent_true(self):
     invoice = Invoice()
     invoice.EmailStatus = "EmailSent"
     self.assertTrue(invoice.email_sent)
Example #18
0
    last_years_customer_sales.update({sale.CustomerRef.value: sale.ClassRef})

# Now get this year sales

this_year_sales = SalesReceipt.query(f"SELECT * FROM salesreceipt where TxnDate > '2019-12-01' and TxnDate < '2020-06-01' MAXRESULTS 1000", qb=client)
#cnt = 0
this_years_customer_sales = {}

for sale in this_year_sales:
    #cnt += 1
    #print(f"CustomerName: {sale.CustomerRef.name}, CustomerID:{sale.CustomerRef.value}, Scout: {sale.CustomField[0].StringValue}")
    this_years_customer_sales.update({sale.CustomerRef.value: sale.CustomField[0].StringValue})

this_years_customer_invoices = {}
#this years invoices (from square)
this_year_invoices = Invoice.query(f"SELECT * FROM Invoice where TxnDate > '2019-12-01' and TxnDate < '2020-06-01' MAXRESULTS 1000", qb=client)

for invoice in this_year_invoices:
    print(f"InvoiceCustomerName: {invoice.CustomerRef.name}, InvoiceCustomerID:{invoice.CustomerRef.value}, InvoiceScout: {invoice.CustomField[0].StringValue}")
    this_years_customer_invoices.update({invoice.CustomerRef.value: invoice.CustomField[0].StringValue})

#now find the difference
#list(set(temp1) - set(temp2))

# #print out last year, then this year
# for last_key, last_value in last_years_customer_sales.items():
#     print(f"last_key:{last_key}, last value:{last_value}")
#
# #print out last year, then this year
# for this_key, this_value in this_years_customer_sales.items():
#     print(f"this_key:{this_key}, this value:{this_value}")
Example #19
0
    db = Database.Database(db_set.database, db_set.user, db_set.password,
                           db_set.host, db_set.port)
    try:
        con = db.connection()
        con.autocommit = True
        cur = con.cursor()
        print("database ", db.name, "is opened")
    except:
        raise NameError('failed to open the database')

#---------------------- outgoing_Invoices----------------------
    try:

        LocalInvoicesIDs = outgoing_invoices.GetAllOutgoingInvoices(con, cur)
        invoices = Invoice.all(qb=client)
        for x in range(len(invoices)):
            invoice_id = int(invoices[x].Id)
            if (invoice_id not in LocalInvoicesIDs):

                title = invoices[x].CustomerRef.name
                created_date = invoices[x].TxnDate
                expiration_date = invoices[x].DueDate
                fullfillement_date = None
                total_amount = invoices[x].TotalAmt
                total_vat = invoices[x].TxnTaxDetail.TotalTax
                currency = invoices[x].CurrencyRef.value
                products_list = []
                list_products = (invoices[x].Line)
                for y in range(len(list_products)):
                    try:
 def test_email_sent_true(self):
     invoice = Invoice()
     invoice.EmailStatus = "EmailSent"
     self.assertTrue(invoice.email_sent)
 def test_email_sent_false(self):
     invoice = Invoice()
     invoice.EmailStatus = "NotSent"
     self.assertFalse(invoice.email_sent)
    def test_valid_object_name(self):
        obj = Invoice()
        client = QuickBooks()
        result = client.isvalid_object_name(obj.qbo_object_name)

        self.assertTrue(result)
 def handle(self, *args, **options):
     live = options.get("live", False)
     print(f"This is LIVE: ", live)
     Invoice.objects.all().delete()
     client = get_quickbooks_client()
     customers = Customer.all(qb=client, max_results=1000)
     for customer in customers:
         chapter_name = customer.CompanyName
         if not chapter_name or not hasattr(customer, "CustomerTypeRef"):
             continue
         customer_type = customer.CustomerTypeRef["value"]
         if customer_type == "7300000000000214210":
             # This is a chapter
             if "Chapter" in chapter_name:
                 chapter_name = customer.CompanyName.split(" Chapter")[0]
         elif customer_type == "7300000000000214211":
             # This is a candidate chapter
             # Candidate Chapter is normally in the name
             pass
         elif customer_type == "7300000000000220483":
             # This is a natoff
             continue
         elif customer_type == "7300000000000247061":
             # This is other
             continue
         else:
             # Maybe not chapter/candidate chapter, but other?
             continue
         print(f"Syncing: ", chapter_name)
         try:
             chapter = Chapter.objects.get(name=chapter_name)
         except Chapter.DoesNotExist:
             print(f"    Chapter matching {chapter_name} does not exist")
             continue
         balance = customer.Balance
         print("    New balance: ", balance)
         if live:
             chapter.balance = balance
             chapter.balance_date = timezone.now()
             chapter.save()
         # Total emails are limited to 100 characters, need to be strategic
         # [regent, scribe, vice, treasurer]
         council_emails = chapter.get_current_officers_council_specific()
         # [email_regent, email_scribe, email_vice_regent, email_treasurer, email_corresponding_secretary, email,
         generic_emails = chapter.get_generic_chapter_emails()
         emails = [
             # Tresurer
             council_emails[3],
             generic_emails[3],
             # Generic
             generic_emails[5],
             # Regent
             council_emails[0],
             generic_emails[0],
             # Vice
             council_emails[2],
             generic_emails[2],
             # Scribe
             council_emails[1],
             generic_emails[1],
             # Corsec
             generic_emails[4],
         ]
         emails = [email for email in emails if email]
         if not emails:
             print("    NO EMAILS")
         email_str = ""
         for email in emails:
             if not isinstance(email, str):
                 email = email.email
             if not email:
                 continue
             if (len(email_str + email) +
                     1) < 100 and email not in email_str:
                 email_str = email_str + email + ","
             else:
                 break
         email_str = email_str[:-1]
         print("    Current Email: ", customer.PrimaryEmailAddr.Address)
         if customer.PrimaryEmailAddr.Address != email_str:
             print("    New Email: ", email_str)
             if live:
                 customer.PrimaryEmailAddr.Address = email_str
                 customer.save(qb=client)
         else:
             print("    No new emails")
         if not balance > 0:
             continue
         invoices = QBInvoice.query(
             select=
             f"select * from Invoice where balance > '0' AND CustomerRef = '{customer.Id}'",
             qb=client,
         )
         for invoice_res in invoices:
             invoice = QBInvoice.get(invoice_res.Id, qb=client)
             Invoice(
                 link=invoice.InvoiceLink,
                 due_date=invoice.DueDate,
                 central_id=invoice.DocNumber,
                 description="<br>".join([
                     f"{line.Description}; Line Amount: {line.Amount} <br>"
                     for line in invoice.Line
                     if line.DetailType == "SalesItemLineDetail"
                 ]),
                 total=invoice.Balance,
                 chapter=chapter,
             ).save()
def generate_sale_invoice(sales):
    payload = {
        "Line": [],
        "CustomerRef": {
            "value": "1"
        }
    }
    sale_invoice = Invoice()
    account_code_tax_code_mapping = {}
    overall_total_amount = 0
    # iterate over the sales to aggregate the line items by account code and tax code
    for sale in sales:
        for line_item in sale["register_sale_products"]:
            account_code = product_to_account_code[line_item["product_id"]]
            tax_code = line_item["tax_id"]

            key = (account_code, tax_code)
            price = float(line_item["price"])
            quantity = float(line_item["quantity"])
            tax = float(line_item["tax"])
            total_amount = (price + tax) * quantity

            if key in account_code_tax_code_mapping:
                account_code_tax_code_mapping[key] += total_amount
            else:
                account_code_tax_code_mapping[key] = total_amount

            overall_total_amount += total_amount

    # sale_invoice.TotalAmt = overall_total_amount
    payload["TotalAmt"] = overall_total_amount

    for key, value in account_code_tax_code_mapping.items():
        account_code = key[0]
        tax_code = key[1]

        external_tax_code = "NON"
        if tax_code == "02dcd191-ae2b-11e6-f485-a54b9896a941" or tax_code == "00000000-0002-0002-0002-000000000003":
            external_tax_code = "TAX"

        # line_item = SalesItemLine()
        # line_item.Amount = value
        # line_item.Description = "Account code: {} and Tax code: {}".format(account_code, tax_code)
        line_item = {
            "DetailType": "SalesItemLineDetail",
            "Amount": value,
            "Description": "Account code: {} and Tax code: {}".format(account_code, external_tax_code),
            "SalesItemLineDetail": {
                "ItemRef": {

                },
                "TaxCodeRef": {

                }
            }
        }

        line_item["SalesItemLineDetail"]["ItemRef"]["value"] = account_code

        line_item["SalesItemLineDetail"]["TaxCodeRef"]["value"] = external_tax_code

        payload["Line"].append(line_item)

    return payload