itkdb-gtk 0.0.3__py3-none-any.whl → 0.20.1__py3-none-any.whl

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (37) hide show
  1. itkdb_gtk/{sendShipments.py → CreateShipments.py} +74 -78
  2. itkdb_gtk/{getShipments.py → GetShipments.py} +99 -106
  3. itkdb_gtk/GlueWeight.py +45 -66
  4. itkdb_gtk/ITkDB.desktop +8 -0
  5. itkdb_gtk/ITkDB.svg +380 -0
  6. itkdb_gtk/ITkDBlogin.py +10 -6
  7. itkdb_gtk/ITkDButils.py +295 -57
  8. itkdb_gtk/PanelVisualInspection.py +590 -0
  9. itkdb_gtk/QRScanner.py +120 -0
  10. itkdb_gtk/SensorUtils.py +492 -0
  11. itkdb_gtk/ShowAttachments.py +267 -0
  12. itkdb_gtk/ShowComments.py +94 -0
  13. itkdb_gtk/ShowDefects.py +103 -0
  14. itkdb_gtk/UploadModuleIV.py +566 -0
  15. itkdb_gtk/UploadMultipleTests.py +746 -0
  16. itkdb_gtk/UploadTest.py +509 -0
  17. itkdb_gtk/VisualInspection.py +297 -0
  18. itkdb_gtk/WireBondGui.py +1304 -0
  19. itkdb_gtk/__init__.py +38 -12
  20. itkdb_gtk/dashBoard.py +292 -33
  21. itkdb_gtk/dbGtkUtils.py +356 -75
  22. itkdb_gtk/findComponent.py +242 -0
  23. itkdb_gtk/findVTRx.py +36 -0
  24. itkdb_gtk/readGoogleSheet.py +1 -2
  25. itkdb_gtk/untrash_component.py +35 -0
  26. {itkdb_gtk-0.0.3.dist-info → itkdb_gtk-0.20.1.dist-info}/METADATA +21 -12
  27. itkdb_gtk-0.20.1.dist-info/RECORD +30 -0
  28. {itkdb_gtk-0.0.3.dist-info → itkdb_gtk-0.20.1.dist-info}/WHEEL +1 -1
  29. itkdb_gtk-0.20.1.dist-info/entry_points.txt +12 -0
  30. itkdb_gtk/checkComponent.py +0 -131
  31. itkdb_gtk/groundingTest.py +0 -225
  32. itkdb_gtk/readAVSdata.py +0 -565
  33. itkdb_gtk/uploadPetalInformation.py +0 -604
  34. itkdb_gtk/uploadTest.py +0 -384
  35. itkdb_gtk-0.0.3.dist-info/RECORD +0 -19
  36. itkdb_gtk-0.0.3.dist-info/entry_points.txt +0 -7
  37. {itkdb_gtk-0.0.3.dist-info → itkdb_gtk-0.20.1.dist-info}/top_level.txt +0 -0
@@ -5,31 +5,33 @@ Items can be added via a QR reader.
5
5
  """
6
6
  import pathlib
7
7
  import sys
8
+ import re
8
9
 
9
10
  try:
10
- import dbGtkUtils
11
- import ITkDBlogin
12
- import ITkDButils
13
- except ModuleNotFoundError:
14
- from itkdb_gtk import dbGtkUtils, ITkDBlogin, ITkDButils
11
+ import itkdb_gtk
12
+
13
+ except ImportError:
14
+ from pathlib import Path
15
+ cwd = Path(__file__).parent.parent
16
+ sys.path.append(cwd.as_posix())
17
+
18
+ from itkdb_gtk import dbGtkUtils, ITkDBlogin, ITkDButils, QRScanner
15
19
 
16
20
  import gi
17
- import serial
18
21
  gi.require_version("Gtk", "3.0")
19
- from gi.repository import Gtk, Gio, GLib
22
+ from gi.repository import Gtk, Gio
20
23
 
21
24
  # Check if Gtk can be open
22
25
  gtk_runs, gtk_args = Gtk.init_check()
23
26
 
24
27
 
25
- class SendShipments(dbGtkUtils.ITkDBWindow):
28
+ class CreateShipments(dbGtkUtils.ITkDBWindow):
26
29
  """Create a shipment from input."""
27
30
 
28
- def __init__(self, session):
31
+ def __init__(self, session, help_link=None):
29
32
  """Initialization.
30
33
 
31
34
  Args:
32
- ----
33
35
  session: ITkDB session.
34
36
 
35
37
  """
@@ -39,7 +41,8 @@ class SendShipments(dbGtkUtils.ITkDBWindow):
39
41
  self.attachment = None
40
42
  global gtk_runs
41
43
  if gtk_runs:
42
- super().__init__(session=session, title="Upload AVS Data", gtk_runs=gtk_runs)
44
+ super().__init__(session=session, title="Create Shipment",
45
+ help_link=help_link, gtk_runs=gtk_runs)
43
46
  self.init_window()
44
47
 
45
48
  def init_window(self):
@@ -48,7 +51,7 @@ class SendShipments(dbGtkUtils.ITkDBWindow):
48
51
  self.set_border_width(10)
49
52
 
50
53
  # intercept keyboard
51
- self.setup_scanner()
54
+ self.scanner = QRScanner.QRScanner(self.get_qrcode)
52
55
 
53
56
  # Prepare HeaderBar
54
57
  self.hb.props.title = "Create Shipment"
@@ -95,8 +98,8 @@ class SendShipments(dbGtkUtils.ITkDBWindow):
95
98
  box = Gtk.Box(orientation=Gtk.Orientation.HORIZONTAL)
96
99
  self.mainBox.pack_start(box, False, False, 0)
97
100
 
98
- dbGtkUtils.add_button_to_container(box, "Add Item",
99
- "Click to add a new item.",
101
+ dbGtkUtils.add_button_to_container(box, "Add Items",
102
+ "Click to add a new items.\nAdd SNs separated by\n\tnew line,\n\ttab\n\tespace or\n\tcomma.",
100
103
  self.add_item)
101
104
 
102
105
  dbGtkUtils.add_button_to_container(box, "Remove Item",
@@ -125,8 +128,7 @@ class SendShipments(dbGtkUtils.ITkDBWindow):
125
128
  paned.add1(tree_view)
126
129
 
127
130
  # The text view
128
- frame = self.create_text_view()
129
- paned.add2(frame)
131
+ paned.add2(self.message_panel.frame)
130
132
 
131
133
  self.show_all()
132
134
 
@@ -175,53 +177,63 @@ class SendShipments(dbGtkUtils.ITkDBWindow):
175
177
 
176
178
  def add_item(self, *args):
177
179
  """Add new item."""
178
- # We will get the input either from a Dialog or from the QR reder.
180
+ # We will get the input either from a Dialog or from the QR reader.
179
181
  # For the later we get the SN in the argument list.
180
182
  if isinstance(args[0], Gtk.Button):
181
- SN = dbGtkUtils.get_a_value("Enter item SN")
182
- else:
183
- SN = args[0]
184
-
185
- try:
186
- # Check that the object exists and get some information about it.
187
- rc = ITkDButils.get_DB_component(self.session, SN)
188
- if 'inTransit' in rc and rc['inTransit']:
189
- dbGtkUtils.complain("Item {} is already in transit".format(SN),
190
- "This item is already in transit to {}".format(rc['shipmentDestination']['code']))
183
+ txt = dbGtkUtils.get_a_value("Enter item SN", is_tv=True)
184
+ if txt is None:
191
185
  return
192
- nick = rc['alternativeIdentifier']
193
- id = rc['id']
194
- obj = rc['componentType']['name']
195
- loc = rc['currentLocation']['code']
196
-
197
- # Check tha tthe input is not already there
198
- model = self.tree.get_model()
199
- iter = model.get_iter_first()
200
- while iter:
201
- if model.get_value(iter, 0) == SN:
202
- dbGtkUtils.complain("Duplicated item.",
203
- "Object {} is already in the list".format(SN))
204
- return
205
186
 
206
- iter = model.iter_next(iter)
187
+ tmp = re.split(';|,| |\n|\t', txt)
188
+ SNlist = [s.strip() for s in tmp if len(s.strip())>0]
189
+ else:
190
+ SNlist = [args[0]]
207
191
 
208
- # Add the item in the liststore.
209
- model.append([SN, nick, obj, loc, id])
192
+ for SN in SNlist:
193
+ try:
194
+ # Check that the object exists and get some information about it.
195
+ rc = ITkDButils.get_DB_component(self.session, SN)
196
+ if 'inTransit' in rc and rc['inTransit']:
197
+ dbGtkUtils.complain("Item {} is already in transit".format(SN),
198
+ "This item is already in transit to {}".format(rc['shipmentDestination']['code']))
199
+ return
210
200
 
211
- except Exception:
212
- dbGtkUtils.complain("Error querying DB",
213
- "object {} does not exist.".format(SN))
214
- print(ITkDButils.get_db_response())
201
+ nick = rc['alternativeIdentifier']
202
+ obj_id = rc['id']
203
+ obj = rc['componentType']['name']
204
+ loc = rc['currentLocation']['code']
205
+ serialN = rc['serialNumber']
206
+ if serialN is None:
207
+ serialN = obj_id
208
+
209
+ # Check tha tthe input is not already there
210
+ model = self.tree.get_model()
211
+ lv_iter = model.get_iter_first()
212
+ while lv_iter:
213
+ if model.get_value(lv_iter, 0) == SN:
214
+ dbGtkUtils.complain("Duplicated item.",
215
+ "Object {} is already in the list".format(SN))
216
+ return
217
+
218
+ lv_iter = model.iter_next(lv_iter)
219
+
220
+ # Add the item in the liststore.
221
+ model.append([serialN, nick, obj, loc, obj_id])
222
+
223
+ except Exception:
224
+ dbGtkUtils.complain("Error querying DB",
225
+ "object {} does not exist.".format(SN))
226
+ print(ITkDButils.get_db_response())
215
227
 
216
228
  def remove_item(self, *args):
217
229
  """Remove selected item."""
218
230
  select = self.tree.get_selection()
219
- model, iter = select.get_selected()
220
- if iter:
221
- values = model[iter]
231
+ model, lv_iter = select.get_selected()
232
+ if lv_iter:
233
+ values = model[lv_iter]
222
234
  rc = dbGtkUtils.ask_for_confirmation("Remove this items ?", values[0])
223
235
  if rc:
224
- model.remove(iter)
236
+ model.remove(lv_iter)
225
237
 
226
238
  def add_attachment_dialog(self):
227
239
  """Create the add attachment dialog."""
@@ -274,7 +286,7 @@ class SendShipments(dbGtkUtils.ITkDBWindow):
274
286
 
275
287
  T = T if len(T) else None
276
288
  D = D if len(D) else None
277
- att = ITkDButils.Attachment(path, T, D)
289
+ att = ITkDButils.Attachment(path=path, title=T, desc=D)
278
290
  self.attachment = att
279
291
 
280
292
  dlg.hide()
@@ -288,26 +300,8 @@ class SendShipments(dbGtkUtils.ITkDBWindow):
288
300
  else:
289
301
  self.write_message("No attachment found\n")
290
302
 
291
- def setup_scanner(self):
292
- """Setup scanner."""
293
- for fnam in ["/dev/ttyACM0", "/dev/cu.usbmodemS_N_G19F204881"]:
294
- P = pathlib.Path(fnam)
295
- if P.exists():
296
- rdr = serial.Serial(fnam, 9600)
297
- GLib.unix_fd_add_full(GLib.PRIORITY_DEFAULT, rdr.fileno(), GLib.IOCondition.IN, self.get_qrcode, rdr)
298
- break
299
-
300
- def get_qrcode(self, fd, state, reader):
303
+ def get_qrcode(self, txt):
301
304
  """Gets data from QR scanner."""
302
- available = reader.in_waiting
303
- while True:
304
- delta = reader.in_waiting - available
305
- if not delta:
306
- break
307
-
308
- # Get data from serial device passed in via
309
- data = reader.read_until(expected='\r', size=reader.in_waiting).strip()
310
- txt = data.decode('utf-8')
311
305
  self.write_message("{}\n".format(txt))
312
306
 
313
307
  # Try to add item to the list
@@ -318,16 +312,16 @@ class SendShipments(dbGtkUtils.ITkDBWindow):
318
312
  def send_items(self, *args):
319
313
  """Send items in liststore."""
320
314
  model = self.tree.get_model()
321
- iter = model.get_iter_first()
315
+ lv_iter = model.get_iter_first()
322
316
  items = []
323
317
  senders = {}
324
- while iter:
325
- values = model[iter]
318
+ while lv_iter:
319
+ values = model[lv_iter]
326
320
  items.append(values[0])
327
321
  senders[values[3]] = senders.setdefault(values[3], 0) + 1
328
- iter = model.iter_next(iter)
322
+ lv_iter = model.iter_next(lv_iter)
329
323
 
330
- if len(items):
324
+ if len(items)>0:
331
325
  if len(senders) != 1:
332
326
  dbGtkUtils.complain("Too many senders.",
333
327
  "There are objects located in differen sites:{}".format('\n'.join(senders.keys())))
@@ -354,7 +348,7 @@ class SendShipments(dbGtkUtils.ITkDBWindow):
354
348
  self.tree.set_model(model)
355
349
  self.comments.set_text("")
356
350
  self.name.set_text("")
357
- self.attachments = None
351
+ self.attachment = None
358
352
 
359
353
  else:
360
354
  self.write_message("Empty list of items when creating shipment.")
@@ -363,6 +357,8 @@ class SendShipments(dbGtkUtils.ITkDBWindow):
363
357
  def main():
364
358
  """Main entry."""
365
359
  # main entry of the program
360
+ HELP_LINK="https://itkdb-gtk.docs.cern.ch"
361
+
366
362
  dlg = ITkDBlogin.ITkDBlogin()
367
363
  client = dlg.get_client()
368
364
  if client is None:
@@ -371,7 +367,7 @@ def main():
371
367
  sys.exit()
372
368
 
373
369
  client.user_gui = dlg
374
- IS = SendShipments(client)
370
+ IS = CreateShipments(client, help_link="{}/createShipment.html".format(HELP_LINK))
375
371
  IS.set_accept_focus(True)
376
372
  IS.present()
377
373
  IS.connect("destroy", Gtk.main_quit)
@@ -1,17 +1,17 @@
1
1
  #!/usr/bin/env python3
2
2
  """GEt shipments to a particular site (default is IFIC)."""
3
- import pathlib
4
3
  import sys
4
+ from pathlib import Path
5
5
 
6
6
  try:
7
- import dbGtkUtils
8
- import ITkDBlogin
9
- import ITkDButils
10
- except ModuleNotFoundError:
11
- from itkdb_gtk import dbGtkUtils, ITkDBlogin, ITkDButils
7
+ import itkdb_gtk
12
8
 
9
+ except ImportError:
10
+ cwd = Path(__file__).parent.parent
11
+ sys.path.append(cwd.as_posix())
12
+
13
+ from itkdb_gtk import dbGtkUtils, ITkDBlogin, ITkDButils, QRScanner, findVTRx
13
14
  import gi
14
- import serial
15
15
 
16
16
  gi.require_version("Gtk", "3.0")
17
17
  from gi.repository import Gtk, Gio, GLib
@@ -23,29 +23,32 @@ gtk_runs, gtk_args = Gtk.init_check()
23
23
  class ReceiveShipments(dbGtkUtils.ITkDBWindow):
24
24
  """Find shipments related to given recipient."""
25
25
 
26
- def __init__(self, session, recipient="IFIC"):
26
+ def __init__(self, session, recipient=None, help_link=None):
27
27
  """Initialization.
28
28
 
29
29
  Args:
30
- ----
31
30
  session: ITkDB session.
32
31
  recipient: default recipient
33
32
 
34
33
  """
35
- self.recipient = recipient
36
34
  self.state = "inTransit"
37
35
  self.institute = None
38
36
  self.model = None
39
37
  self.store = None
38
+ self.tree = None
40
39
  self.shipments = {}
41
40
 
42
41
  global gtk_runs
43
42
  if gtk_runs:
44
- super().__init__(session=session, title="Upload AVS Data",
45
- show_search="Cliick to search shipments",
46
- gtk_runs=gtk_runs)
43
+ super().__init__(session=session, title="Receive Shipments",
44
+ show_search="Click to search shipments",
45
+ gtk_runs=gtk_runs, help_link=help_link)
47
46
 
47
+ self.recipient = self.pdb_user["institutions"][0]["code"]
48
48
  self.init_window()
49
+ else:
50
+ pdb_user = ITkDButils.get_db_user(session)
51
+ self.recipient = pdb_user["institutions"][0]["code"]
49
52
 
50
53
  def init_window(self):
51
54
  """Initialize window."""
@@ -53,7 +56,7 @@ class ReceiveShipments(dbGtkUtils.ITkDBWindow):
53
56
  self.set_border_width(10)
54
57
 
55
58
  # intercept keyboard
56
- self.setup_scanner()
59
+ self.scanner = QRScanner.QRScanner(self.get_qrcode)
57
60
 
58
61
  # Prepare HeaderBar
59
62
  self.hb.props.title = "{} shipments".format(self.recipient)
@@ -72,7 +75,7 @@ class ReceiveShipments(dbGtkUtils.ITkDBWindow):
72
75
  self.mainBox.pack_start(grid, False, True, 0)
73
76
 
74
77
  # The shipment receiver
75
- receiver = self.create_institute_combo()
78
+ receiver = self.create_institute_combo(only_user=True)
76
79
  receiver.connect("changed", self.on_receiver)
77
80
  receiver.set_tooltip_text("Select the Institute receiving the items.")
78
81
  dbGtkUtils.set_combo_iter(receiver, self.recipient)
@@ -112,6 +115,12 @@ class ReceiveShipments(dbGtkUtils.ITkDBWindow):
112
115
  btn.connect("clicked", self.receive_items)
113
116
  grid.attach(btn, 2, 3, 1, 1)
114
117
 
118
+ self.check_all = Gtk.ToggleButton(label="Check A_ll", use_underline=True)
119
+ self.check_all.set_active(1)
120
+ self.check_all.set_tooltip_text("If toggled, items will need to be `received`\none by one by unchecking the check box.")
121
+ grid.attach(self.check_all, 3, 3, 1, 1)
122
+
123
+
115
124
  # Add a Separator
116
125
  self.mainBox.pack_start(Gtk.Separator(orientation=Gtk.Orientation.VERTICAL), False, True, 0)
117
126
 
@@ -125,8 +134,7 @@ class ReceiveShipments(dbGtkUtils.ITkDBWindow):
125
134
  paned.add1(tree_view)
126
135
 
127
136
  # The text view
128
- frame = self.create_text_view()
129
- paned.add2(frame)
137
+ paned.add2(self.message_panel.frame)
130
138
 
131
139
  self.show_all()
132
140
 
@@ -154,55 +162,31 @@ class ReceiveShipments(dbGtkUtils.ITkDBWindow):
154
162
 
155
163
  return scrolled
156
164
 
157
- def setup_scanner(self):
158
- """Setup scanner."""
159
- for fnam in ["/dev/ttyACM0", "/dev/cu.usbmodemS_N_G19F204881"]:
160
- P = pathlib.Path(fnam)
161
- if P.exists():
162
- rdr = serial.Serial(fnam, 9600)
163
- GLib.unix_fd_add_full(GLib.PRIORITY_DEFAULT, rdr.fileno(), GLib.IOCondition.IN, self.get_qrcode, rdr)
164
- break
165
-
166
- def get_qrcode(self, fd, state, reader):
165
+ def get_qrcode(self, txt):
167
166
  """Gets data from QR scanner."""
168
- available = reader.in_waiting
169
- while True:
170
- delta = reader.in_waiting - available
171
- if not delta:
172
- break
173
-
174
- # Get data from serial device passed in via
175
- data = reader.read_until(expected='\r', size=reader.in_waiting).strip()
176
- txt = data.decode('utf-8')
177
167
  self.write_message("{}\n".format(txt))
178
168
 
169
+ if findVTRx.is_vtrx(txt):
170
+ try:
171
+ txt = findVTRx.find_vtrx(self.session, txt)
172
+ except ValueError as e:
173
+ self.write_message("Error: {}\n".format(e))
174
+ return
175
+
179
176
  # search code in the list
180
177
  if self.store:
181
- iter = self.store.get_iter_first()
182
- while iter:
183
- if (self.store.get_value(iter, 0) == txt):
184
- self.write_message("...found\n")
185
- self.store[iter][3] = False
178
+ lv_iter = self.store.get_iter_first()
179
+ while lv_iter:
180
+ mSN = self.store.get_value(lv_iter, 0)
181
+ mID = self.store.get_value(lv_iter, 5)
182
+ if mSN == txt or mID == txt:
183
+ self.write_message("...found {}\n".format(mSN))
184
+ self.store[lv_iter][3] = False
186
185
 
187
- iter = self.store.iter_next(iter)
186
+ lv_iter = self.store.iter_next(lv_iter)
188
187
 
189
188
  return True
190
189
 
191
- def get_institute_list(self):
192
- """Get the institute list."""
193
- sites = self.session.get("listInstitutions", json={})
194
- liststore = Gtk.ListStore(str, str)
195
- for site in sites:
196
- self.code2inst[site['code']] = site['name']
197
- self.inst2code[site['name']] = site['code']
198
- liststore.append([site["code"], site["code"]])
199
- liststore.append([site["name"], site["code"]])
200
-
201
- completion = Gtk.EntryCompletion()
202
- completion.set_model(liststore)
203
- completion.set_text_column(0)
204
- return completion
205
-
206
190
  def on_cell_toggled(self, widget, path):
207
191
  """A cell has been toggled."""
208
192
  model = self.tree.get_model()
@@ -223,9 +207,9 @@ class ReceiveShipments(dbGtkUtils.ITkDBWindow):
223
207
 
224
208
  # Store the model associated to this shipment.
225
209
  self.store = self.shipments[shpmnt]
226
- filter = self.store.filter_new()
227
- filter.set_visible_column(3)
228
- self.tree.set_model(filter)
210
+ sfilter = self.store.filter_new()
211
+ sfilter.set_visible_column(3)
212
+ self.tree.set_model(sfilter)
229
213
 
230
214
  def on_status_changed(self, combo):
231
215
  """Status changed."""
@@ -239,30 +223,12 @@ class ReceiveShipments(dbGtkUtils.ITkDBWindow):
239
223
 
240
224
  self.state = name
241
225
 
242
- def get_institute_from_combo(self, combo):
243
- """Get Institute from combo."""
244
- tree_iter = combo.get_active_iter()
245
- if tree_iter is not None:
246
- model = combo.get_model()
247
- name = model[tree_iter][1]
248
-
249
- else:
250
- name = combo.get_child().get_text()
251
- if name in self.inst2code:
252
- name = self.inst2code[name]
253
-
254
- elif name not in self.code2inst:
255
- name = None
256
-
257
- return name
258
-
259
226
  def on_receiver(self, combo):
260
227
  """Sets the recipient."""
261
228
  name = self.get_institute_from_combo(combo)
262
229
  if name:
263
230
  self.recipient = name
264
- hb = self.get_titlebar()
265
- hb.props.title = "{} shipments".format(self.recipient)
231
+ self.set_window_title("{} shipments".format(self.recipient))
266
232
 
267
233
  def on_institute(self, combo):
268
234
  """New institute chosen."""
@@ -276,12 +242,14 @@ class ReceiveShipments(dbGtkUtils.ITkDBWindow):
276
242
 
277
243
  def query_db(self, *args):
278
244
  """Query for shipments in DB."""
279
- if self.institute is None or self.state == "":
245
+ if self.state == "":
280
246
  return
281
247
 
282
248
  payload = {
283
- "code": self.recipient,
284
- "status": self.state
249
+ "filterMap": {
250
+ "code": self.recipient,
251
+ "status": self.state
252
+ }
285
253
  }
286
254
  shpmts = self.session.get("listShipmentsByInstitution", json=payload)
287
255
 
@@ -290,7 +258,11 @@ class ReceiveShipments(dbGtkUtils.ITkDBWindow):
290
258
  # the tree view.
291
259
  cmb_store = Gtk.ListStore(str, str)
292
260
  for s in shpmts:
293
- if s["recipient"]["code"] == self.recipient and s['sender']['code'] == self.institute:
261
+ valid_sender = True
262
+ if self.institute is not None:
263
+ valid_sender = s['sender']['code'] == self.institute
264
+
265
+ if s["recipient"]["code"] == self.recipient and valid_sender:
294
266
  store = self.get_tree_view_model()
295
267
  cmb_store.append([s['name'], s['id']])
296
268
  items = self.session.get("listShipmentItems", json={"shipment": s["id"]})
@@ -308,35 +280,54 @@ class ReceiveShipments(dbGtkUtils.ITkDBWindow):
308
280
  self.write_message("Could not find any shipment in DB.\n")
309
281
 
310
282
  self.cmb_shipment.set_model(cmb_store)
311
- self.cmb_shipment.set_entry_text_column(0)
312
- self.cmb_shipment.set_active(0)
283
+ if len(cmb_store)>0:
284
+ self.cmb_shipment.set_entry_text_column(0)
285
+ self.cmb_shipment.set_active(0)
286
+ else:
287
+ self.cmb_shipment.set_active(-1)
288
+ self.cmb_shipment.get_child().set_text("")
289
+ self.tree.set_model(Gtk.ListStore(str, str, str, bool))
290
+
291
+ def mark_all_as_delivered(self):
292
+ """Mark all items in current shipment as delivered."""
293
+ if self.store is None:
294
+ return
295
+
296
+ lv_iter = self.store.get_iter_first()
297
+ while lv_iter:
298
+ val = self.store[lv_iter][3]
299
+ self.store[lv_iter][3] = not val
300
+ lv_iter = self.store.iter_next(lv_iter)
313
301
 
314
302
  def receive_items(self, *args):
315
303
  """Receive shipment items."""
316
304
  data = {}
317
305
  names = {}
306
+ if not self.store:
307
+ self.write_message("Empty list of items.\n")
308
+ return
309
+
310
+ if not self.check_all.get_active():
311
+ self.mark_all_as_delivered()
318
312
 
319
313
  # self.store is the model of the tree view
320
- if self.store:
321
- iter = self.store.get_iter_first()
322
- while iter:
323
- shpmnt = self.store.get_value(iter, 2)
324
- if shpmnt not in data:
325
- data[shpmnt] = create_shipment_status(shpmnt)
326
- names[shpmnt] = self.store.get_value(iter, 4)
314
+ lv_iter = self.store.get_iter_first()
315
+ while lv_iter:
316
+ shpmnt = self.store.get_value(lv_iter, 2)
317
+ if shpmnt not in data:
318
+ data[shpmnt] = create_shipment_status(shpmnt)
319
+ names[shpmnt] = self.store.get_value(lv_iter, 4)
327
320
 
328
- item = {
329
- "code": self.store[iter][5],
330
- "delivered": not self.store[iter][3]
331
- }
332
- data[shpmnt]["shipmentItems"].append(item)
321
+ item = {
322
+ "code": self.store[lv_iter][5],
323
+ "delivered": not self.store[lv_iter][3]
324
+ }
325
+ data[shpmnt]["shipmentItems"].append(item)
333
326
 
334
- iter = self.store.iter_next(iter)
327
+ lv_iter = self.store.iter_next(lv_iter)
335
328
 
336
- else:
337
- self.write_message("Empty list of items.\n")
338
329
 
339
- for id, S in data.items():
330
+ for oid, S in data.items():
340
331
  # Check that all items are there
341
332
  nlost = 0
342
333
  for item in S["shipmentItems"]:
@@ -355,7 +346,7 @@ class ReceiveShipments(dbGtkUtils.ITkDBWindow):
355
346
  return
356
347
 
357
348
  # Open dialog to fill-in questions
358
- create_check_list(S["checklist"]["questionList"], names[id])
349
+ create_check_list(S["checklist"]["questionList"], names[oid])
359
350
 
360
351
  # send the update to the DB
361
352
  S['status'] = "delivered"
@@ -371,10 +362,10 @@ class ReceiveShipments(dbGtkUtils.ITkDBWindow):
371
362
  self.write_message("Could not update the shipment status.\n{}\n".foramt(rc))
372
363
 
373
364
  else:
374
- self.write_message("Shipment {} received\n".format(names[id]))
365
+ self.write_message("Shipment {} received\n".format(names[oid]))
375
366
  # Now remove the current shipment
376
- iter = self.cmb_shipment.get_active_iter()
377
- self.cmb_shipment.get_model().remove(iter)
367
+ lv_iter = self.cmb_shipment.get_active_iter()
368
+ self.cmb_shipment.get_model().remove(lv_iter)
378
369
  self.cmb_shipment.set_active(0)
379
370
 
380
371
 
@@ -514,6 +505,8 @@ def create_shipment_status(shpmnt):
514
505
 
515
506
  def main():
516
507
  """Main entry."""
508
+ HELP_LINK="https://itkdb-gtk.docs.cern.ch/receiveShipments.html"
509
+
517
510
  dlg = ITkDBlogin.ITkDBlogin()
518
511
  client = dlg.get_client()
519
512
  if client is None:
@@ -522,7 +515,7 @@ def main():
522
515
  sys.exit()
523
516
 
524
517
  client.user_gui = dlg
525
- IS = ReceiveShipments(client)
518
+ IS = ReceiveShipments(client, help_link=HELP_LINK)
526
519
  IS.set_accept_focus(True)
527
520
  IS.present()
528
521
  IS.connect("destroy", Gtk.main_quit)