Skip to content

Commit b7acfd3

Browse files
committed
Add Sales orders and items. Also add getting users
1 parent a32ad4f commit b7acfd3

File tree

4 files changed

+172
-53
lines changed

4 files changed

+172
-53
lines changed

fishbowl/api.py

Lines changed: 37 additions & 48 deletions
Original file line numberDiff line numberDiff line change
@@ -15,56 +15,18 @@
1515
from lxml import etree
1616

1717
from . import jsonrequests, objects, statuscodes, xmlrequests
18-
19-
logger = logging.getLogger(__name__)
20-
21-
PRICING_RULES_SQL = (
22-
"SELECT p.id, p.isactive, product.num, "
23-
"p.patypeid, p.papercent, p.pabaseamounttypeid, p.paamount, "
24-
"p.customerincltypeid, p.customerinclid, p.datelastmodified "
25-
"from pricingrule p INNER JOIN product on p.productinclid = product.id "
26-
"where p.productincltypeid = 2 and "
27-
"p.customerincltypeid in (1, 2)"
28-
)
29-
30-
31-
CUSTOMER_GROUP_PRICING_RULES_SQL = (
32-
"SELECT p.id, p.isactive, product.num, p.patypeid, p.papercent, "
33-
"p.pabaseamounttypeid, p.paamount, p.customerincltypeid, p.datelastmodified, "
34-
"p.customerinclid, c.id as customerid, ag.name as accountgroupname, "
35-
"c.name as customername "
36-
"FROM pricingrule p "
37-
"INNER JOIN product ON p.productinclid = product.id "
38-
"INNER JOIN accountgroup ag ON p.customerinclid = ag.id "
39-
"INNER JOIN accountgrouprelation agr ON agr.groupid = ag.id "
40-
"INNER JOIN customer c ON agr.accountid = c.accountid "
41-
"WHERE p.productincltypeid = 2 AND p.customerincltypeid = 3"
18+
from .queries import (
19+
CUSTOMER_GROUP_PRICING_RULES_SQL,
20+
PARTS_SQL,
21+
PRICING_RULES_SQL,
22+
PRODUCTS_SQL,
23+
SALES_ORDER_ITEMS,
24+
SALES_ORDER_LIST,
25+
SERIAL_NUMBER_SQL,
26+
USERS_SQL,
4227
)
4328

44-
# https://www.fishbowlinventory.com/files/databasedictionary/2017/tables/product.html
45-
PRODUCTS_SQL = """
46-
SELECT
47-
P.*,
48-
PART.STDCOST AS StandardCost,
49-
PART.TYPEID as TypeID
50-
{ci_fields}
51-
FROM PRODUCT P
52-
INNER JOIN PART ON P.PARTID = PART.ID
53-
{custom_joins}
54-
"""
55-
56-
# https://www.fishbowlinventory.com/files/databasedictionary/2017/tables/part.html
57-
PARTS_SQL = "SELECT * FROM Part"
58-
59-
60-
SERIAL_NUMBER_SQL = (
61-
"SELECT sn.id, sn.serialId, sn.serialNum, p.num as PartNum, "
62-
"t.dateCreated as DateCreated, t.dateLastModified as DateLastModified "
63-
"FROM serialnum sn "
64-
"LEFT JOIN serial s ON s.id = sn.serialId "
65-
"LEFT JOIN tag t on t.id = s.tagId "
66-
"LEFT JOIN part p on t.partId = p.id"
67-
)
29+
logger = logging.getLogger(__name__)
6830

6931

7032
def UnicodeDictReader(utf8_data, **kwargs):
@@ -911,6 +873,33 @@ def save_so(self, so):
911873
check_status(response.find("FbiMsgsRs"))
912874
return objects.SalesOrder(response.find("SalesOrder"))
913875

876+
@require_connected
877+
def get_sales_order_items(self, sales_order_id):
878+
return self.basic_query(
879+
SALES_ORDER_ITEMS.format(sales_order_id=sales_order_id), objects.SalesOrderItem
880+
)
881+
882+
@require_connected
883+
def get_sales_orders_list(self):
884+
"""
885+
A generator that returns sales orders, and the sales order items.
886+
"""
887+
for row in self.send_query(SALES_ORDER_LIST):
888+
obj = objects.SalesOrder(row)
889+
890+
# TODO: Still need to get memo at some point if needed
891+
row_objects = [r for r, _ in self.get_sales_order_items(row["id"])]
892+
obj._mapped["Items"] = row_objects
893+
894+
if not obj:
895+
continue
896+
897+
yield obj
898+
899+
@require_connected
900+
def get_users(self):
901+
return [u[0] for u in self.basic_query(USERS_SQL, objects.User)]
902+
914903
@require_connected
915904
def get_available_imports(self):
916905
"""

fishbowl/example.py

Lines changed: 21 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -68,27 +68,43 @@ def run():
6868
# serial = fishbowl.get_serial_numbers()
6969
# print(serial)
7070

71-
# fishbowl.send_request(
72-
# 'GetSOListRq',
71+
# response = fishbowl.send_request(
72+
# "GetSOListRq",
7373
# {
74-
# 'DateCreatedEnd': datetime.datetime(1900, 1, 1),
75-
# }
74+
# "DateLasteModifiedBegin": datetime.datetime(2021, 5, 1),
75+
# "DateLasteModifiedEnd": datetime.datetime(2021, 5, 15),
76+
# },
7677
# )
78+
# print("SO Response", response)
79+
# response = fishbowl.get_so("10045")
80+
81+
# response = fishbowl.get_sales_orders_list()
82+
83+
# for record in fishbowl.get_sales_orders_list():
84+
# print(record["Items"])
85+
86+
# response = fishbowl.get_users()
87+
7788
# fishbowl.send_request('GetPartListRq')
7889
# with open('LightPartListRq.xml', 'w') as f:
7990
# f.write(etree.tostring(fishbowl.send_request('LightPartListRq')))
8091
# response = fishbowl.send_request('GetShipListRq')
8192

8293
# products = fishbowl.get_products()
94+
# print(products)
8395
# customers = fishbowl.get_customers_fast(
8496
# populate_pricing_rules=False, populate_addresses=False
8597
# )
98+
# print(customers)
8699
# rules = fishbowl.get_pricing_rules()
87-
# import ipdb; ipdb.set_trace()
100+
# print(rules)
88101

89102
# response = fishbowl.send_request("CustomerNameListRq")
90103
# return etree.tostring(response)
91104

105+
# Inspect response here when possible so it closes the connection to fishbowl
106+
# print(response)
107+
92108

93109
if __name__ == "__main__":
94110
run()

fishbowl/objects.py

Lines changed: 15 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -174,6 +174,8 @@ def __setitem__(self, key, value):
174174
expected_type = getattr(expected_type, "type", expected_type)
175175
if expected_type is None:
176176
expected_type = str
177+
if isinstance(expected_type, list):
178+
expected_type = list
177179
if not isinstance(value, expected_type):
178180
raise ValueError("Value was not type {}".format(expected_type))
179181
self.mapped[key] = value
@@ -455,6 +457,19 @@ class Memo(FishbowlObject):
455457
)
456458

457459

460+
class User(FishbowlObject):
461+
fields = OrderedDict(
462+
[
463+
("ID", int),
464+
("Email", None),
465+
("firstName", None),
466+
("lastname", None),
467+
("phone", None),
468+
("username", None),
469+
]
470+
)
471+
472+
458473
class SalesOrder(FishbowlObject):
459474
fields = OrderedDict(
460475
[

fishbowl/queries.py

Lines changed: 99 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,99 @@
1+
SALES_ORDER_LIST = """
2+
SELECT
3+
s.id, s.billToAddress, s.billToCity, s.billToCountryId, s.billToName,
4+
s.billToStateId, s.billToZip, s.carrierId, s.cost, s.currencyId,
5+
s.currencyRate, s.customerContact, s.customerId, s.customerPO,
6+
s.dateCompleted, s.dateCreated AS `CreatedDate`, s.dateFirstShip AS `FirstShipDate`,
7+
s.dateIssued AS `IssuedDate`, s.dateLastModified, s.dateRevision, s.fobPointId,
8+
s.locationGroupId, s.note, s.num AS `Number`, s.paymentTermsId,
9+
s.qbClassId, s.registerID, s.salesman, s.salesmanId, s.salesmanInitials,
10+
s.shipTermsId, s.shipToAddress, s.shipToCity, s.shipToCountryId, s.shipToName,
11+
s.shipToStateId, s.shipToZip, s.statusId, s.taxRate, s.taxRateId, s.taxRateName,
12+
s.totalIncludesTax, s.totalPrice, s.totalTax, s.typeId, s.url, s.vendorPO,
13+
s.priorityId, c.name AS `Carrier`, ss.name AS status, f.name AS fob,
14+
st.name AS ShippingTerms, qb.name AS QuickBooksClassName,
15+
cu.name AS CustomerName, pt.name AS PaymentTerms,
16+
lg.name AS LocationGroup, cur.code AS CurrencyName
17+
FROM
18+
so s
19+
LEFT JOIN Carrier c ON s.carrierId = c.id
20+
LEFT JOIN sostatus ss ON s.statusId = ss.id
21+
LEFT JOIN fobpoint f ON s.fobpointid = f.id
22+
LEFT JOIN shipterms st ON s.shiptermsid = st.id
23+
LEFT JOIN qbclass qb ON s.qbclassid = qb.id
24+
LEFT JOIN customer cu ON s.customerid = cu.id
25+
LEFT JOIN paymentterms pt ON s.paymenttermsid = pt.id
26+
LEFT JOIN locationgroup lg ON s.locationgroupid = lg.id
27+
LEFT JOIN currency cur ON s.currencyid = cur.id
28+
"""
29+
30+
SALES_ORDER_ITEMS = """
31+
SELECT
32+
si.ID, si.adjustamount AS AdjustmentAmount, si.AdjustPercentage, si.CustomerPartNum,
33+
si.DateLastFulfillment, si.DateLastModified, si.DateScheduledFulfillment,
34+
si.Description, si.ExchangeSOLineItem, si.ItemAdjustID,
35+
si.productNum AS ProductNumber, si.qtytofulfill AS Quantity, si.QtyFulfilled,
36+
si.QtyPicked, si.revLevel AS RevisionLevel, si.ShowItemFlag, si.SOID,
37+
si.soLineItem AS LineNumber, si.TaxableFlag, si.TotalPrice, si.TotalCost,
38+
it.name AS ItemType, p.price AS ProductPrice, qb.name AS QuickBooksClassName,
39+
sis.name AS Status, u.code AS UOMCode
40+
FROM soitem si
41+
LEFT JOIN soitemtype it ON si.typeid = it.id
42+
LEFT JOIN product p ON si.productId = p.id
43+
LEFT JOIN qbclass qb ON si.qbclassid = qb.id
44+
LEFT JOIN soitemstatus sis ON si.statusId = sis.id
45+
LEFT JOIN uom u ON si.uomid = u.id
46+
WHERE si.soid = {sales_order_id}
47+
ORDER BY LineNumber ASC
48+
"""
49+
50+
PRICING_RULES_SQL = (
51+
"SELECT p.id, p.isactive, product.num, "
52+
"p.patypeid, p.papercent, p.pabaseamounttypeid, p.paamount, "
53+
"p.customerincltypeid, p.customerinclid, p.datelastmodified "
54+
"from pricingrule p INNER JOIN product on p.productinclid = product.id "
55+
"where p.productincltypeid = 2 and "
56+
"p.customerincltypeid in (1, 2)"
57+
)
58+
59+
60+
CUSTOMER_GROUP_PRICING_RULES_SQL = (
61+
"SELECT p.id, p.isactive, product.num, p.patypeid, p.papercent, "
62+
"p.pabaseamounttypeid, p.paamount, p.customerincltypeid, p.datelastmodified, "
63+
"p.customerinclid, c.id as customerid, ag.name as accountgroupname, "
64+
"c.name as customername "
65+
"FROM pricingrule p "
66+
"INNER JOIN product ON p.productinclid = product.id "
67+
"INNER JOIN accountgroup ag ON p.customerinclid = ag.id "
68+
"INNER JOIN accountgrouprelation agr ON agr.groupid = ag.id "
69+
"INNER JOIN customer c ON agr.accountid = c.accountid "
70+
"WHERE p.productincltypeid = 2 AND p.customerincltypeid = 3"
71+
)
72+
73+
# https://www.fishbowlinventory.com/files/databasedictionary/2017/tables/product.html
74+
PRODUCTS_SQL = """
75+
SELECT
76+
P.*,
77+
PART.STDCOST AS StandardCost,
78+
PART.TYPEID as TypeID
79+
{ci_fields}
80+
FROM PRODUCT P
81+
INNER JOIN PART ON P.PARTID = PART.ID
82+
{custom_joins}
83+
"""
84+
85+
# https://www.fishbowlinventory.com/files/databasedictionary/2017/tables/part.html
86+
PARTS_SQL = "SELECT * FROM Part"
87+
88+
89+
SERIAL_NUMBER_SQL = (
90+
"SELECT sn.id, sn.serialId, sn.serialNum, p.num as PartNum, "
91+
"t.dateCreated as DateCreated, t.dateLastModified as DateLastModified "
92+
"FROM serialnum sn "
93+
"LEFT JOIN serial s ON s.id = sn.serialId "
94+
"LEFT JOIN tag t on t.id = s.tagId "
95+
"LEFT JOIN part p on t.partId = p.id"
96+
)
97+
98+
99+
USERS_SQL = "SELECT id, email, firstName, lastname, phone, username FROM sysuser"

0 commit comments

Comments
 (0)