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)
    def test_create(self):
        customer = Customer.all(max_results=1)[0]
        item = Item.all(max_results=1)[0]

        credit_memo = CreditMemo()
        credit_memo.CustomerRef = customer.to_ref()

        detail_line = CreditMemoLine()
        detail_line.LineNum = 1
        detail_line.Description = "Test Description"
        detail_line.Amount = 100
        detail_line.DetailType = "SalesItemLineDetail"
        detail_line.SalesItemLineDetail = SalesItemLineDetail()
        detail_line.SalesItemLineDetail.ItemRef = item.to_ref()
        credit_memo.Line.append(detail_line)
        credit_memo.save()

        query_credit_memo = CreditMemo.get(credit_memo.Id)

        self.assertEquals(credit_memo.Id, query_credit_memo.Id)
        self.assertEquals(query_credit_memo.CustomerRef.value, customer.Id)

        line = query_credit_memo.Line[0]
        self.assertEquals(line.LineNum, 1)
        self.assertEquals(line.Description, "Test Description")
        self.assertEquals(line.Amount, 100)
        self.assertEquals(line.DetailType, "SalesItemLineDetail")
        self.assertEquals(line.SalesItemLineDetail.ItemRef.value, item.Id)
示例#3
0
    def test_create(self):
        customer = Customer.all(max_results=1, qb=self.qb_client)[0]
        item = Item.all(max_results=1, qb=self.qb_client)[0]

        credit_memo = CreditMemo()
        credit_memo.CustomerRef = customer.to_ref()

        detail_line = SalesItemLine()
        detail_line.LineNum = 1
        detail_line.Description = "Test Description"
        detail_line.Amount = 100
        detail_line.DetailType = "SalesItemLineDetail"
        detail_line.SalesItemLineDetail = SalesItemLineDetail()
        detail_line.SalesItemLineDetail.ItemRef = item.to_ref()
        credit_memo.Line.append(detail_line)
        credit_memo.save(qb=self.qb_client)

        query_credit_memo = CreditMemo.get(credit_memo.Id, qb=self.qb_client)

        self.assertEquals(credit_memo.Id, query_credit_memo.Id)
        self.assertEquals(query_credit_memo.CustomerRef.value, customer.Id)

        line = query_credit_memo.Line[0]
        self.assertEquals(line.LineNum, 1)
        self.assertEquals(line.Description, "Test Description")
        self.assertEquals(line.Amount, 100)
        self.assertEquals(line.DetailType, "SalesItemLineDetail")
        self.assertEquals(line.SalesItemLineDetail.ItemRef.value, item.Id)
示例#4
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)
示例#5
0
    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)
示例#6
0
    def test_update(self):
        customer = Customer.all(max_results=1, qb=self.qb_client)[0]
        unique_name = datetime.now().strftime('%d%H%M%S')

        customer.GivenName = unique_name
        customer.save(qb=self.qb_client)

        query_account = Customer.get(customer.Id, qb=self.qb_client)

        self.assertEqual(query_account.GivenName, unique_name)
示例#7
0
    def test_update(self):
        customer = Customer.all(max_results=1, qb=self.qb_client)[0]
        unique_name = datetime.now().strftime('%d%H%M%S')

        customer.GivenName = unique_name
        customer.save(qb=self.qb_client)

        query_account = Customer.get(customer.Id, qb=self.qb_client)

        self.assertEqual(query_account.GivenName, unique_name)
示例#8
0
 def setUp(self):
     self.qb_client = QuickBooks(
         sandbox=True,
         consumer_key=os.environ.get('CONSUMER_KEY'),
         consumer_secret=os.environ.get('CONSUMER_SECRET'),
         access_token=os.environ.get('ACCESS_TOKEN'),
         access_token_secret=os.environ.get('ACCESS_TOKEN_SECRET'),
         company_id=os.environ.get('COMPANY_ID')
     )
     self.customer = Customer.all(max_results=1, qb=self.qb_client)[0]
    def test_create(self):
        customer = Customer.all(max_results=1, qb=self.qb_client)[0]
        taxcode = TaxCode.all(max_results=1, qb=self.qb_client)[0]
        item = Item.filter(Type='Inventory', max_results=1,
                           qb=self.qb_client)[0]
        vendor = Vendor.all(max_results=1, qb=self.qb_client)[0]
        account = Account.all(max_results=1, qb=self.qb_client)[0]

        purchaseorder = PurchaseOrder()

        detail_line = ItemBasedExpenseLine()
        detail_line.Amount = 100
        detail_line.ItemBasedExpenseLineDetail = ItemBasedExpenseLineDetail()
        detail_line.ItemBasedExpenseLineDetail.BillableStatus = "NotBillable"
        detail_line.ItemBasedExpenseLineDetail.UnitPrice = 100
        detail_line.ItemBasedExpenseLineDetail.Qty = 1
        detail_line.ItemBasedExpenseLineDetail.CustomerRef = customer.to_ref()
        detail_line.ItemBasedExpenseLineDetail.TaxCodeRef = taxcode.to_ref()
        detail_line.ItemBasedExpenseLineDetail.ItemRef = item.to_ref()

        purchaseorder.Line.append(detail_line)
        purchaseorder.VendorRef = vendor.to_ref()
        purchaseorder.APAccountRef = account.to_ref()
        purchaseorder.TotalAmt = 100

        #print purchaseorder.to_json()
        purchaseorder.save(qb=self.qb_client)

        query_purchaseorder = PurchaseOrder.get(purchaseorder.Id,
                                                qb=self.qb_client)

        self.assertEqual(query_purchaseorder.VendorRef.value, vendor.Id)
        self.assertEqual(query_purchaseorder.APAccountRef.value, account.Id)
        self.assertEqual(query_purchaseorder.TotalAmt, 100)

        query_detail_line = query_purchaseorder.Line[0]

        self.assertEqual(query_detail_line.Amount, 100)
        self.assertEqual(
            query_detail_line.ItemBasedExpenseLineDetail.UnitPrice, 100)
        self.assertEqual(query_detail_line.ItemBasedExpenseLineDetail.Qty, 1)
        self.assertEqual(
            query_detail_line.ItemBasedExpenseLineDetail.CustomerRef.value,
            customer.Id)
        self.assertEqual(
            query_detail_line.ItemBasedExpenseLineDetail.TaxCodeRef.value,
            taxcode.Name)
        self.assertEqual(
            query_detail_line.ItemBasedExpenseLineDetail.ItemRef.value,
            item.Id)
示例#10
0
def importUsersFromQuickbooks(request):
    client = get_qb_client()
    customers = Customer.all(qb=client)

    for customer in customers:
        if customer.PrimaryEmailAddr:
            emails = customer.PrimaryEmailAddr.Address

            if ',' in emails:
                for email in emails.split(","):
                    if email:
                        email = email.strip()
                    else:
                        continue
                    if not User.objects.filter(email=email).exists():
                        password = User.objects.make_random_password(length=8,
                                                                     allowed_chars='abcdefghjkmnpqrstuvwxyzABCDEFGHJKLMNPQRSTUVWXYZ23456789')
                        created = User.objects.create_user(
                            first_name=customer.GivenName,
                            last_name=customer.FamilyName,
                            email=email,
                            qb_customer_id=customer.Id,
                        )

                        # TODO: Email raw password to the user on account creation
                        #  so they can change it themselves.
                        created.set_password(password)
                        created.save()
            else:
                email = emails

                if not User.objects.filter(email=email).exists():
                    password = User.objects.make_random_password(length=8,
                                                                 allowed_chars='abcdefghjkmnpqrstuvwxyzABCDEFGHJKLMNPQRSTUVWXYZ23456789')
                    created = User.objects.create_user(
                        first_name=customer.GivenName,
                        last_name=customer.FamilyName,
                        email=email,
                        qb_customer_id=customer.Id,
                    )

                    # TODO: Email raw password to the user on account creation
                    #  so they can change it themselves.
                    created.set_password(password)
                    created.save()
        else:
            continue

    return render(request, 'management.html')
示例#11
0
def qbo_callback():

    # https://github.com/sidecars/python-quickbooks
    from quickbooks import Oauth2SessionManager
    from quickbooks import QuickBooks

    error = request.args.get('error', '')
    if error:
        return "Error: " + error
    state = request.args.get('state', '')
    if not is_valid_state(state):
        # Uh-oh, this request wasn't started by us!
        abort(403)
    authorization_code = request.args.get('code')
    realm_id = request.args.get('realmId')

    session_manager = Oauth2SessionManager(
        client_id=CLIENT_ID,
        client_secret=CLIENT_SECRET,
        base_url='http://localhost:8000/qbo_callback',
    )

    session_manager.get_access_tokens(authorization_code)
    access_token = session_manager.access_token

    session_manager = Oauth2SessionManager(
    client_id=realm_id,
    client_secret=CLIENT_SECRET,
    access_token=access_token,
    )

    client = QuickBooks(
        sandbox=True,
        session_manager=session_manager,
        company_id=realm_id
    )
    
    from quickbooks.objects.customer import Customer
    customers = Customer.all(qb=client)

    import_googlesheets(customers)

    client.disconnect_account()

    # Note: In most cases, you'll want to store the access token, in, say,
    # a session for use in other parts of your web app.
    return "Your qbo authorization_code is %s realm_id is: %s customers: %s" % (authorization_code, realm_id, customers)
    def test_create(self):
        customer = Customer.all(max_results=1, qb=self.qb_client)[0]
        taxcode = TaxCode.all(max_results=1, qb=self.qb_client)[0]
        item = Item.filter(Type='Inventory', max_results=1, qb=self.qb_client)[0]
        vendor = Vendor.all(max_results=1, qb=self.qb_client)[0]
        account = Account.all(max_results=1, qb=self.qb_client)[0]

        purchaseorder = PurchaseOrder()

        detail_line = ItemBasedExpenseLine()
        detail_line.Amount = 100
        detail_line.ItemBasedExpenseLineDetail = ItemBasedExpenseLineDetail()
        detail_line.ItemBasedExpenseLineDetail.BillableStatus = "NotBillable"
        detail_line.ItemBasedExpenseLineDetail.UnitPrice = 100
        detail_line.ItemBasedExpenseLineDetail.Qty = 1
        detail_line.ItemBasedExpenseLineDetail.CustomerRef = customer.to_ref()
        detail_line.ItemBasedExpenseLineDetail.TaxCodeRef = taxcode.to_ref()
        detail_line.ItemBasedExpenseLineDetail.ItemRef = item.to_ref()

        purchaseorder.Line.append(detail_line)
        purchaseorder.VendorRef = vendor.to_ref()
        purchaseorder.APAccountRef = account.to_ref()
        purchaseorder.TotalAmt = 100

        print purchaseorder.to_json()
        purchaseorder.save(qb=self.qb_client)

        query_purchaseorder = PurchaseOrder.get(purchaseorder.Id, qb=self.qb_client)

        self.assertEquals(query_purchaseorder.VendorRef.value, vendor.Id)
        self.assertEquals(query_purchaseorder.APAccountRef.value, account.Id)
        self.assertEquals(query_purchaseorder.TotalAmt, 100)

        query_detail_line = query_purchaseorder.Line[0]

        self.assertEquals(query_detail_line.Amount, 100)
        self.assertEquals(query_detail_line.ItemBasedExpenseLineDetail.UnitPrice, 100)
        self.assertEquals(query_detail_line.ItemBasedExpenseLineDetail.Qty, 1)
        self.assertEquals(query_detail_line.ItemBasedExpenseLineDetail.CustomerRef.value, customer.Id)
        self.assertEquals(query_detail_line.ItemBasedExpenseLineDetail.TaxCodeRef.value, taxcode.Name)
        self.assertEquals(query_detail_line.ItemBasedExpenseLineDetail.ItemRef.value, item.Id)
 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()
示例#14
0
# Your app needs an OAuth 2.0 Access Token to access QuickBooks Online data. The OAuth 2.0 playground is the easiest way to get your access token.
#  https://developer.intuit.com/app/developer/playground
# CAN GET THE AUTH TOKEN FOR EITHER SANDBOX OR PRODUCTION APP!!!

# ALSO, this test API page lets you try things out...
# https://developer.intuit.com/app/developer/qbo/docs/api/accounting/all-entities/account

# https://developer.intuit.com/app/developer/qbo/docs/get-started

#  By now, you have your Client ID, Client Secret, and OAuth access token. Next, you can try making an API call. In the snippet below:
from quickbooks import QuickBooks
client = QuickBooks(
    auth_client=auth_client,
    refresh_token=oauth2_token_from_auth['refreshToken'],  #'REFRESH_TOKEN',
    company_id=realm_id,  #'COMPANY_ID',
    # minorversion=4
)

from quickbooks.objects.customer import Customer
customers = Customer.all(qb=client)
# Note: The maximum number of entities that can be returned in a response is 1000. If the result size is not specified, the default number is 100. (See Intuit developer guide for details)
print("####################\nShow CUSTOMER NAMES\n####################")
for (cnt, a) in enumerate(customers):
    print(cnt, a.DisplayName)

from quickbooks.objects.account import Account
accounts = Account.all(qb=client)
print("####################\nShow ACCOUNT NAMES\n####################")
for (cnt, a) in enumerate(accounts):
    print(cnt, a.Name)
示例#15
0
    def test_create(self):
        self.customer = Customer.all(max_results=1, qb=self.qb_client)[0]

        estimate = Estimate()
        estimate.TotalAmt = 31.5
        estimate.ApplyTaxAfterDiscount = False
        estimate.PrintStatus = "NeedToPrint"
        estimate.EmailStatus = "NotSet"

        estimate.BillAddr = Address()
        estimate.BillAddr.Line1 = "65 Ocean Dr."
        estimate.BillAddr.City = "Half Moon Bay"
        estimate.BillAddr.CountrySubDivisionCode = "CA"
        estimate.BillAddr.PostalCode = "94213"
        estimate.BillAddr.Lat = "37.4300318"
        estimate.BillAddr.Long = "-122.4336537"

        estimate.ShipAddr = Address()
        estimate.ShipAddr.Id = "2" + datetime.now().strftime('%d%H%M')
        estimate.ShipAddr.Line1 = "65 Ocean Dr."
        estimate.ShipAddr.City = "Half Moon Bay"
        estimate.ShipAddr.CountrySubDivisionCode = "CA"
        estimate.ShipAddr.PostalCode = "94213"
        estimate.ShipAddr.Lat = "37.4300318"
        estimate.ShipAddr.Long = "-122.4336537"

        estimate.BillEmail = EmailAddress()
        estimate.BillEmail.Address = "*****@*****.**"

        estimate.CustomerMemo = CustomerMemo()
        estimate.CustomerMemo.value = "Thank you for your business and have a great day!"

        estimate.CustomerRef = Ref()
        estimate.CustomerRef.value = self.customer.Id
        estimate.CustomerRef.name = self.customer.DisplayName

        estimate.TxnTaxDetail = TxnTaxDetail()
        estimate.TxnTaxDetail.TotalTax = 0

        line = SalesItemLine()
        line.LineNum = 1
        line.Description = "Pest Control Services"
        line.Amount = 35.0

        line.SalesItemLineDetail = SalesItemLineDetail()
        line.SalesItemLineDetail.UnitPrice = 35
        line.SalesItemLineDetail.Qty = 1

        item_ref = Ref()
        item_ref.value = "10"
        item_ref.name = "Pest Control"
        line.SalesItemLineDetail.ItemRef = item_ref

        tax_code_ref = Ref()
        tax_code_ref.value = "NON"
        line.SalesItemLineDetail.TaxCodeRef = tax_code_ref

        estimate.Line.append(line)

        line2 = DiscountLine()
        line2.Amount = 3.5

        line2.DiscountLineDetail = DiscountLineDetail()
        line2.DiscountLineDetail.PercentBased = True
        line2.DiscountLineDetail.DiscountPercent = 10

        line2.DiscountLineDetail.DiscountAccountRef = Ref()
        line2.DiscountLineDetail.DiscountAccountRef.value = "86"
        line2.DiscountLineDetail.DiscountAccountRef.name = "Discounts given"

        line2.DetailType = "DiscountLineDetail"

        estimate.Line.append(line2)

        estimate.save(qb=self.qb_client)

        query_estimate = Estimate.get(estimate.Id, qb=self.qb_client)

        self.assertEqual(query_estimate.Id, estimate.Id)
        self.assertEqual(query_estimate.TotalAmt, estimate.TotalAmt)
        self.assertEqual(query_estimate.ApplyTaxAfterDiscount,
                         estimate.ApplyTaxAfterDiscount)
        self.assertEqual(query_estimate.PrintStatus, estimate.PrintStatus)
        self.assertEqual(query_estimate.EmailStatus, estimate.EmailStatus)
        self.assertEqual(query_estimate.BillAddr.Line1,
                         estimate.BillAddr.Line1)
        self.assertEqual(query_estimate.BillAddr.City, estimate.BillAddr.City)
        self.assertEqual(query_estimate.BillAddr.CountrySubDivisionCode,
                         estimate.BillAddr.CountrySubDivisionCode)
        self.assertEqual(query_estimate.BillAddr.PostalCode,
                         estimate.BillAddr.PostalCode)
        self.assertEqual(query_estimate.ShipAddr.Line1,
                         estimate.ShipAddr.Line1)
        self.assertEqual(query_estimate.ShipAddr.City, estimate.ShipAddr.City)
        self.assertEqual(query_estimate.ShipAddr.CountrySubDivisionCode,
                         estimate.ShipAddr.CountrySubDivisionCode)
        self.assertEqual(query_estimate.ShipAddr.PostalCode,
                         estimate.ShipAddr.PostalCode)
        self.assertEqual(query_estimate.BillEmail.Address,
                         estimate.BillEmail.Address)
        self.assertEqual(query_estimate.CustomerMemo.value,
                         estimate.CustomerMemo.value)
        self.assertEqual(query_estimate.CustomerRef.value,
                         estimate.CustomerRef.value)
        self.assertEqual(query_estimate.CustomerRef.name,
                         estimate.CustomerRef.name)
        self.assertEqual(query_estimate.TxnTaxDetail.TotalTax,
                         estimate.TxnTaxDetail.TotalTax)
        self.assertEqual(query_estimate.Line[0].LineNum,
                         estimate.Line[0].LineNum)
        self.assertEqual(query_estimate.Line[0].Description,
                         estimate.Line[0].Description)
        self.assertEqual(query_estimate.Line[0].Amount,
                         estimate.Line[0].Amount)
        self.assertEqual(query_estimate.Line[0].SalesItemLineDetail.UnitPrice,
                         estimate.Line[0].SalesItemLineDetail.UnitPrice)
        self.assertEqual(query_estimate.Line[0].SalesItemLineDetail.Qty,
                         estimate.Line[0].SalesItemLineDetail.Qty)
        self.assertEqual(query_estimate.Line[2].Amount,
                         estimate.Line[1].Amount)
        self.assertEqual(
            query_estimate.Line[2].DiscountLineDetail.PercentBased,
            estimate.Line[1].DiscountLineDetail.PercentBased)
        self.assertEqual(
            query_estimate.Line[2].DiscountLineDetail.DiscountPercent,
            estimate.Line[1].DiscountLineDetail.DiscountPercent)
        self.assertEqual(
            query_estimate.Line[2].DiscountLineDetail.DiscountAccountRef.value,
            estimate.Line[1].DiscountLineDetail.DiscountAccountRef.value)
        self.assertEqual(
            query_estimate.Line[2].DiscountLineDetail.DiscountAccountRef.name,
            estimate.Line[1].DiscountLineDetail.DiscountAccountRef.name)