Skip to content

Commit 2b2a2d2

Browse files
committed
change products window to use a treeview for vendor product information,
also split financial and ordering into seperate tabs
1 parent e555e8a commit 2b2a2d2

File tree

3 files changed

+532
-605
lines changed

3 files changed

+532
-605
lines changed

src/db/database_utils.py

Lines changed: 9 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1321,7 +1321,15 @@ def check_and_update_version (db, statusbar):
13211321
cursor.execute("ALTER TABLE products ALTER COLUMN manufacturer_sku SET NOT NULL")
13221322
cursor.execute("ALTER TABLE products ALTER COLUMN job SET NOT NULL")
13231323
cursor.execute("ALTER TABLE public.products RENAME CONSTRAINT products_income_account_fkey TO products_revenue_account_fkey;")
1324-
cursor.execute("UPDATE settings SET version = '128'")
1324+
if version <= '128':
1325+
progressbar (128)
1326+
cursor.execute("ALTER TABLE public.vendor_product_numbers ADD CONSTRAINT vendor_product_numbers_product_id_vendor_id_key EXCLUDE USING btree (vendor_id WITH =, product_id WITH =) WHERE (deleted = false);")
1327+
cursor.execute("ALTER TABLE public.vendor_product_numbers ALTER COLUMN vendor_sku SET DEFAULT '';")
1328+
cursor.execute("ALTER TABLE public.vendor_product_numbers ALTER COLUMN vendor_sku SET NOT NULL;")
1329+
cursor.execute("ALTER TABLE public.vendor_product_numbers ADD COLUMN deleted boolean DEFAULT False")
1330+
cursor.execute("UPDATE public.vendor_product_numbers SET deleted = False")
1331+
cursor.execute("ALTER TABLE public.vendor_product_numbers ALTER COLUMN deleted SET NOT NULL")
1332+
cursor.execute("UPDATE settings SET version = '129'")
13251333
cursor.close()
13261334
db.commit()
13271335

src/products.py

Lines changed: 77 additions & 93 deletions
Original file line numberDiff line numberDiff line change
@@ -194,66 +194,83 @@ def product_column_sorted(self, treeview_column):
194194
self.product_store.set_sort_column_id (1, Gtk.SortType.DESCENDING )
195195
self.ascending = not self.ascending
196196

197-
def vendor_combo_changed(self, widget = None):
198-
if self.product_id == 0:
199-
return
200-
self.populating = True
201-
vendor_id = self.builder.get_object('comboboxtext2').get_active_id()
202-
if vendor_id != None :
203-
self.builder.get_object('label16').set_label('$0.00')
204-
sku_entry = self.builder.get_object('entry4')
205-
barcode_entry = self.builder.get_object('entry3')
206-
qty_entry = self.builder.get_object('spinbutton2')
207-
price_entry = self.builder.get_object('spinbutton3')
208-
self.cursor.execute("SELECT id, vendor_sku, vendor_barcode, qty, "
209-
"price "
210-
"FROM vendor_product_numbers "
211-
"WHERE (vendor_id, product_id) = (%s, %s) "
212-
"LIMIT 1",
213-
(vendor_id, self.product_id))
214-
for row in self.cursor.fetchall():
215-
self.sku_id = row[0]
216-
sku_entry.set_text(row[1])
217-
barcode_entry.set_text(row[2])
218-
qty_entry.set_value(int(row[3]))
219-
price_entry.set_value(float(row[4]))
220-
self.calculate_piece_cost ()
221-
break
222-
else: # vendor sku is not in the database
223-
sku_entry.set_text("")
224-
barcode_entry.set_text("")
225-
qty_entry.set_text('0')
226-
price_entry.set_text('0')
227-
self.sku_id = 0 # new vendor sku
228-
self.populating = False
229-
230-
def vendor_sku_changed(self, entry = None):
231-
if self.populating == True:
232-
return
233-
self.update_vendor_product_info ()
234-
235-
def vendor_barcode_changed(self, entry = None):
236-
if self.populating == True:
237-
return
238-
self.update_vendor_product_info ()
197+
def buy_qty_edited (self, cellrenderertext, path, text):
198+
store = self.builder.get_object('vendor_order_store')
199+
row_id = store[path][0]
200+
self.cursor.execute("UPDATE vendor_product_numbers "
201+
"SET qty = %s WHERE id = %s",
202+
(text, row_id))
203+
self.populate_vendor_order_numbers ()
204+
205+
def qty_price_edited (self, cellrenderertext, path, text):
206+
store = self.builder.get_object('vendor_order_store')
207+
row_id = store[path][0]
208+
self.cursor.execute("UPDATE vendor_product_numbers "
209+
"SET price = %s WHERE id = %s",
210+
(text, row_id))
211+
self.populate_vendor_order_numbers ()
212+
213+
def barcode_edited (self, cellrenderertext, path, text):
214+
store = self.builder.get_object('vendor_order_store')
215+
row_id = store[path][0]
216+
self.cursor.execute("UPDATE vendor_product_numbers "
217+
"SET vendor_barcode = %s WHERE id = %s",
218+
(text, row_id))
219+
self.populate_vendor_order_numbers ()
220+
221+
def order_number_edited (self, cellrenderertext, path, text):
222+
store = self.builder.get_object('vendor_order_store')
223+
row_id = store[path][0]
224+
self.cursor.execute("UPDATE vendor_product_numbers "
225+
"SET vendor_sku = %s WHERE id = %s",
226+
(text, row_id))
227+
self.db.commit()
228+
self.populate_vendor_order_numbers ()
229+
230+
def populate_vendor_order_numbers (self):
231+
store = self.builder.get_object('vendor_order_store')
232+
store.clear()
233+
self.cursor.execute("SELECT vpn.id, c.name, vendor_sku, "
234+
"vendor_barcode, qty::int, price::text "
235+
"FROM vendor_product_numbers AS vpn "
236+
"JOIN contacts AS c ON c.id = vpn.vendor_id "
237+
"AND vendor = True "
238+
"WHERE (product_id, vpn.deleted) = (%s, False) "
239+
"ORDER BY c.name", (self.product_id,))
240+
for row in self.cursor.fetchall():
241+
store.append(row)
239242

240-
def vendor_qty_changed (self, spinbutton):
241-
self.calculate_piece_cost ()
242-
if self.populating == True:
243+
def vendor_combo_changed(self, combo):
244+
vendor_id = combo.get_active_id()
245+
if self.product_id == 0 or vendor_id == None or vendor_id == '':
243246
return
244-
self.update_vendor_product_info ()
247+
c = self.db.cursor()
248+
c.execute("INSERT INTO vendor_product_numbers "
249+
"(product_id, vendor_id) VALUES (%s, %s) "
250+
"ON CONFLICT ON CONSTRAINT "
251+
"vendor_product_numbers_product_id_vendor_id_key "
252+
"DO NOTHING",
253+
(self.product_id, vendor_id))
254+
c.close()
255+
self.db.commit()
256+
self.populate_vendor_order_numbers ()
245257

246-
def vendor_price_changed (self, spinbutton):
247-
self.calculate_piece_cost ()
248-
if self.populating == True:
258+
def delete_order_number_menu_activated (self, menuitem):
259+
selection = self.builder.get_object('vendor_order_number_selection')
260+
model, path = selection.get_selected_rows()
261+
if path == []:
249262
return
250-
self.update_vendor_product_info ()
263+
row_id = model[path][0]
264+
self.cursor.execute("UPDATE vendor_product_numbers SET deleted = True "
265+
"WHERE id = %s", (row_id,))
266+
self.db.commit()
267+
self.populate_vendor_order_numbers ()
251268

252-
def cost_sell_ratio_changed (self, spinbutton):
253-
self.calculate_piece_cost ()
254-
if self.populating == True:
255-
return
256-
self.update_vendor_product_info ()
269+
def vendor_order_treeview_button_release (self, treeview, event):
270+
if event.button == 3:
271+
menu = self.builder.get_object('vendor_order_number_menu')
272+
menu.popup(None, None, None, None, event.button, event.time)
273+
menu.show_all()
257274

258275
def calculate_piece_cost (self):
259276
qty = self.builder.get_object('spinbutton2').get_value()
@@ -275,39 +292,6 @@ def apply_individual_cost_clicked (self, button):
275292
piece_cost = piece_cost / ratio
276293
self.builder.get_object('spinbutton1').set_value(piece_cost)
277294

278-
def update_vendor_product_info (self):
279-
if self.product_id == 0:
280-
return # we cannot save vendor info if the product does not exist
281-
vendor_id = self.builder.get_object('comboboxtext2').get_active_id()
282-
vendor_sku = self.builder.get_object('entry4').get_text()
283-
vendor_barcode = self.builder.get_object('entry3').get_text()
284-
vendor_qty = self.builder.get_object('spinbutton2').get_text()
285-
vendor_price = self.builder.get_object('spinbutton3').get_text()
286-
if vendor_sku == '' and vendor_barcode == '' and vendor_qty == '0'\
287-
and float(vendor_price) == 0.00:
288-
self.cursor.execute("DELETE FROM vendor_product_numbers "
289-
"WHERE (vendor_id, product_id) = (%s, %s)",
290-
(vendor_id, self.product_id))
291-
# delete any blank vendor info
292-
return #do not save, no vendor info
293-
if self.sku_id == 0:
294-
self.cursor.execute("INSERT INTO vendor_product_numbers "
295-
"(vendor_sku, vendor_id, vendor_barcode, "
296-
"product_id, qty, price) "
297-
"VALUES (%s, %s, %s, %s, %s, %s) "
298-
"RETURNING id", (vendor_sku, vendor_id,
299-
vendor_barcode, self.product_id, vendor_qty,
300-
vendor_price))
301-
self.sku_id = self.cursor.fetchone()[0]
302-
else:
303-
self.cursor.execute("UPDATE vendor_product_numbers SET "
304-
"(vendor_sku, vendor_id, vendor_barcode, "
305-
"qty, price) = "
306-
"(%s, %s, %s, %s, %s) WHERE id = %s",
307-
(vendor_sku, vendor_id, vendor_barcode,
308-
vendor_qty, vendor_price, self.sku_id))
309-
self.db.commit()
310-
311295
def focus_in_populate_comboboxes(self, widget, event):
312296
#self.populate_product_store ()
313297
self.populate_account_combos ()
@@ -323,14 +307,15 @@ def populate_account_combos(self):
323307
if current_tax != None:
324308
tax_combobox.set_active_id(current_tax)
325309
vendor_combobox = self.builder.get_object('comboboxtext2')
326-
current_vendor = vendor_combobox.get_active_id()
310+
#current_vendor = vendor_combobox.get_active_id()
327311
vendor_combobox.remove_all()
312+
vendor_combobox.append('', '')
328313
self.cursor.execute("SELECT id, name FROM contacts "
329314
"WHERE (deleted, vendor) = (False, True) "
330315
"ORDER BY name")
331316
for item in self.cursor.fetchall():
332317
vendor_combobox.append(str(item[0]),item[1])
333-
vendor_combobox.set_active_id(current_vendor)
318+
vendor_combobox.set_active (0)
334319
location_combo = self.builder.get_object('comboboxtext6')
335320
active_location = location_combo.get_active()
336321
location_combo.remove_all()
@@ -715,7 +700,7 @@ def select_product (self, product_id):
715700
self.populating = False
716701
#now update the prices
717702
self.load_product_terms_prices ()
718-
GLib.timeout_add(10, self.vendor_combo_changed )
703+
self.populate_vendor_order_numbers ()
719704

720705
def default_expense_account_combo_changed (self, combo):
721706
account_number = combo.get_active_id()
@@ -903,8 +888,6 @@ def new_product (self):
903888
self.builder.get_object('checkbutton3').set_active(False)
904889
self.builder.get_object('spinbutton10').set_value(0)
905890
self.builder.get_object('spinbutton11').set_value(0)
906-
self.builder.get_object('entry3').set_text("")
907-
self.builder.get_object('entry4').set_text("")
908891
self.builder.get_object('entry5').set_text("")
909892
self.builder.get_object('entry6').set_text("")
910893
self.builder.get_object('entry7').set_text("")
@@ -941,6 +924,7 @@ def new_product (self):
941924
default_id = self.cursor.fetchone()[0]
942925
self.builder.get_object('comboboxtext4').set_active_id(str(default_id))
943926
self.set_price_listbox_to_default ()
927+
self.builder.get_object('vendor_order_store').clear()
944928

945929
def show_message (self, message):
946930
dialog = Gtk.MessageDialog( self.window,

0 commit comments

Comments
 (0)