ViewVC Help
View File | Revision Log | Show Annotations | View Changeset | Root Listing
root/ns_dev/Python/NinoCode/Active_prgs/SOW_Automator.py
Revision: 597
Committed: Sat Dec 19 03:50:08 2015 UTC (10 years, 3 months ago) by nino.borges
Content type: text/x-python
File size: 22505 byte(s)
Log Message:
Version 1.02. Remade as a notebook and added a pricing section.  Works great.

File Contents

# User Rev Content
1 nino.borges 596 """
2    
3     SOW_Automator
4     Created by
5     Emanuel Borges
6     12.07.2015
7    
8     Class to help automate the process of making and editing those SOWs.
9 nino.borges 597 This program is windows only, since it automates Word and Excel.
10     (also it uses Spinbutton instead of spinControl, which is win only.)
11 nino.borges 596
12    
13     """
14    
15     import RelativityLib,os,shutil,time,WordLib, wx
16 nino.borges 597 import wx.lib.agw.pybusyinfo as PBI
17 nino.borges 596 #from win32com.client import Dispatch
18    
19    
20     class CreateSOW(object):
21 nino.borges 597 version = "1.02"
22 nino.borges 596
23     def __init__(self,salesPersonLastName, clientName, clientOffice, projectName, contractType,workflow):
24     """lastname of the sales person"""
25     #self.salesPersonFirstName = salesPersonFirstName
26     self.contractType = contractType
27     self.workflow = workflow
28     self.salesPersonLastName = salesPersonLastName
29     self.GetAddress()
30     self.salesPersonFullName = "%s, %s"%(salesPersonLastName,self.salesPersonFirstName)
31     self.clientName = clientName
32     self.clientOffice = clientOffice
33     self.projectName = projectName
34     self.tempDir = os.getenv('TEMP')
35     self.userName = os.getenv('USERNAME')
36     if self.userName == "Emanual Borges":
37     self.sowFinalPath = r"C:\Users\Emanual Borges\OneDrive - Advanced Discovery\Documents\SOW"
38     self.sowTemplatePath = r"C:\Users\Emanual Borges\OneDrive - Advanced Discovery\Documents\SOW\_Template"
39     else:
40     self.sowFinalPath = self.userName = os.path.join(os.getenv('USERPROFILE'),'Desktop')
41     self.sowTemplatePath = os.getcwd()
42     #self.proposalTemplateFileName = r"Proposal2.docx"
43     if contractType == "SOW":
44     self.sowTemplateFileName = r"SOW Template2.docx"
45     else:
46     self.sowTemplateFileName = r"Proposal2.docx"
47     #self.wordApp = Dispatch('Word.Application')
48 nino.borges 597 ## some in the init paren and some here?
49     self.dataCollectionCost = None
50     self.consultingServicesCost = None
51     self.forensicAnalysisCost = None
52     self.ecaProcessingCost = None
53     self.nativePromotionCost = None
54     self.ocrCost = None
55     self.flocrCost = None
56     self.analyticsProcessingCost = None
57     self.projectManagementCost = None
58     self.monthlyHostingCost = None
59     self.monthlyUserCost = None
60 nino.borges 596
61    
62    
63     def GetAddress(self):
64     """Returns the full address for the sales person"""
65     #test = RelativityLib.Relativity_Connection()
66     db = RelativityLib.CustomObjectTable('BORGES_01_DEMO','Sales_People')
67     for num, name in db.itemMatrix.iteritems():
68     if self.salesPersonLastName == str(name):
69     salesPersonID = num
70     db.LoadSingleItem(salesPersonID)
71     for i in db.currentItems:
72     self.salesPersonDisplayName = i['Sales_Person_DisplayName']
73     self.salesPersonTitle = i['Title']
74     self.salesPersonStreetAddress = i['Street_Address']
75     self.salesPersonCity = i['City']['Name']
76     self.salesPersonState = i['State']['Name']
77     self.salesPersonZipcode = i['Zipcode']
78     self.salesPersonPhoneNumber = i['Phone_Number']
79     self.salesPersonEmailAddress = i['Email_Address']
80     self.salesPersonFirstName = i['Sales_Person_FirstName']
81    
82     def ProcessSOW(self):
83     """Once everything is ready, this is called to create the actual work"""
84     ## Copy and rename the template, after checking if it already exists.
85     newFileName = "%s%s%s_%s-%s_%s.docx"%(self.salesPersonFirstName[0],
86     self.salesPersonLastName[0],
87     time.strftime("%m%d%Y"),
88     self.clientName,
89     self.clientOffice,
90     self.projectName)
91     if os.path.isfile(os.path.join(self.sowFinalPath,newFileName)):
92     print "ERROR: File Already Exists."
93     else:
94     #shutil.copyfile(os.path.join(self.sowTemplatePath,self.sowTemplateFileName),os.path.join(self.sowFinalPath,newFileName))
95     shutil.copyfile(os.path.join(self.sowTemplatePath,self.sowTemplateFileName),os.path.join(self.tempDir,newFileName))
96     #self.GetAddress()
97     print self.salesPersonDisplayName
98     print self.salesPersonTitle
99     print self.salesPersonStreetAddress
100     print self.salesPersonCity
101     print self.salesPersonState
102     print self.salesPersonZipcode
103     print self.salesPersonPhoneNumber
104     print self.salesPersonEmailAddress
105     #self.search_replace_all(os.path.join(self.sowFinalPath,newFileName), "<<ProjectName>>", self.projectName)
106     ## Open document and start finding and replacing.
107     wa = WordLib.WordConnection(os.path.join(self.tempDir,newFileName))
108     wa.search_replace_all("<<Client>>",self.clientName)
109     wa.search_replace_all("<<ProjectName>>",self.projectName)
110     wa.search_replace_all("<<SalesPersonName>>",self.salesPersonDisplayName)
111     wa.search_replace_all("<<SalesPersonTitle>>",self.salesPersonTitle)
112     wa.search_replace_all("<<SalesPersonAddress>>",self.salesPersonStreetAddress)
113     wa.search_replace_all("<<SalesPersonCityStateZip>>","%s, %s %s"%(self.salesPersonCity, self.salesPersonState, self.salesPersonZipcode))
114     wa.search_replace_all("<<SalesPersonPhone>>",self.salesPersonPhoneNumber)
115     wa.search_replace_all("<<SalesPersonEmail>>",self.salesPersonEmailAddress)
116     wa.search_replace_all("<<FileName>>",os.path.splitext(newFileName)[0])
117     if self.workflow == "Xpress":
118     wa.table_row_delete(2,9)
119     wa.table_row_delete(2,9)
120     wa.table_row_delete(2,9)
121     wa.table_row_delete(3,9)
122     wa.table_row_delete(3,9)
123     wa.table_row_delete(3,9)
124     else:
125     wa.table_row_delete(2,7)
126     wa.table_row_delete(2,7)
127    
128     wa.table_row_delete(3,7)
129     wa.table_row_delete(3,7)
130 nino.borges 597 wa.search_replace_all("<<DataCollectionCost>>",self.dataCollectionCost)
131     wa.search_replace_all("<<ConsultingServicesCost>>",self.consultingServicesCost)
132     wa.search_replace_all("<<ForensicAnalysisCost>>",self.forensicAnalysisCost)
133     wa.search_replace_all("<<EcaProcessingCost>>",self.ecaProcessingCost)
134     wa.search_replace_all("<<NativePromotionCost>>",self.nativePromotionCost)
135     wa.search_replace_all("<<OcrCost>>",self.ocrCost)
136     wa.search_replace_all("<<FlocrCost>>",self.flocrCost)
137     wa.search_replace_all("<<AnalyticsProcessingCost>>",self.analyticsProcessingCost)
138     wa.search_replace_all("<<ProjectManagementCost>>",self.projectManagementCost)
139     wa.search_replace_all("<<MonthlyHostingCost>>",self.monthlyHostingCost)
140     wa.search_replace_all("<<MonthlyUserCost>>",self.monthlyUserCost)
141 nino.borges 596 wa.Save()
142     wa.Close()
143     os.rename(os.path.join(self.tempDir,newFileName),os.path.join(self.sowFinalPath,newFileName))
144    
145    
146     class MyFrame(wx.Frame):
147     def __init__(self, parent, ID, title, pos=wx.DefaultPosition):
148     print "CWD is %s"%os.getcwd()
149 nino.borges 597 wx.Frame.__init__(self, parent, ID, title, pos, size =(400,550))#(550,580))
150 nino.borges 596 self.panel = wx.Panel(self,-1)
151 nino.borges 597 self.notebook = wx.Notebook(self.panel)
152    
153     self.tab1 = MainPage(self.notebook)
154     self.tab2 = PricingPage(self.notebook)
155    
156     self.notebook.AddPage(self.tab1, "Required")
157     self.notebook.AddPage(self.tab2, "Pricing")
158    
159     sizer = wx.BoxSizer()
160     sizer.Add(self.notebook, 1, wx.EXPAND)
161     self.panel.SetSizer(sizer)
162    
163     self.Bind(wx.EVT_BUTTON, self.CloseWindow, self.tab1.cancelButton)
164     self.Bind(wx.EVT_BUTTON, self.OnProcess, self.tab1.oKButton)
165    
166    
167     def CloseWindow(self, event):
168     self.Close(True)
169    
170     def OnProcess(self, event):
171     print self.tab1.clientNameTextBox.GetValue()
172     print self.tab1.projectNameTextBox.GetValue()
173     print self.tab1.officeLocationTextBox.GetValue()
174     print self.tab1.salesPersonChoice.GetStringSelection()
175     if self.tab1.hostedRadio1.GetValue():
176     print "Xpress Selected"
177     workflow = "Xpress"
178     elif self.tab1.hostedRadio2.GetValue():
179     print "NonHosted Selected"
180     workflow = "Non-Hosted"
181     if self.tab1.sowOrProposalRadio1.GetValue():
182     print "SOW Selected"
183     contractType= "SOW"
184     elif self.tab1.sowOrProposalRadio2.GetValue():
185     print "Proposal Selected"
186     contractType = "Proposal"
187    
188     print "Creating SOW ..."
189     message = "Creating your SOW. One moment please..."
190     busy = PBI.PyBusyInfo(message, parent=self, title="System Busy.")
191    
192    
193    
194     t = CreateSOW(self.tab1.salesPersonChoice.GetStringSelection(),
195     self.tab1.clientNameTextBox.GetValue(),
196     self.tab1.officeLocationTextBox.GetValue(),
197     self.tab1.projectNameTextBox.GetValue(), contractType, workflow)
198    
199     t.dataCollectionCost = self.tab2.dataCollectionSpin.GetValue()
200     t.consultingServicesCost = self.tab2.consultingServicesSpin.GetValue()
201     t.forensicAnalysisCost = self.tab2.forensicAnalysisSpin.GetValue()
202     t.ecaProcessingCost = self.tab2.ecaProcessingSpin.GetValue()
203     t.nativePromotionCost = self.tab2.nativePromotionSpin.GetValue()
204     t.ocrCost = self.tab2.ocrSpin.GetValue()
205     t.flocrCost = self.tab2.flocrSpin.GetValue()
206     t.analyticsProcessingCost = self.tab2.analyticsProcessingSpin.GetValue()
207     t.projectManagementCost = self.tab2.projectManagementSpin.GetValue()
208     t.monthlyHostingCost = self.tab2.monthlyHostingSpin.GetValue()
209     t.monthlyUserCost = self.tab2.userFeesSpin.GetValue()
210    
211    
212    
213     self.Show(False)
214     t.ProcessSOW()
215     del busy
216     print "SOW Created."
217     finishedDlg = wx.MessageDialog(self, "A new SOW has been created.", "MCP: Process Complete",wx.OK, wx.DefaultPosition)
218     finishedDlg.ShowModal()
219     self.Destroy()
220    
221     class MainPage(wx.Panel):
222     ''' The main notebook tab'''
223     def __init__(self,parent):
224     wx.Panel.__init__(self, parent)
225     self.parent = parent
226 nino.borges 596 print "Connecting to Relativity..."
227     db = RelativityLib.CustomObjectTable('BORGES_01_DEMO','Sales_People')
228     #print db.itemMatrix.values()
229     salesPersonList = db.itemMatrix.values()
230 nino.borges 597 clientNameLabel = wx.StaticText(self, -1, "Client Name: ")
231     self.clientNameTextBox = wx.TextCtrl(self, -1, "", wx.DefaultPosition, (90,-1))
232     projectNameLabel = wx.StaticText(self, -1, "Project Name: ")
233     self.projectNameTextBox = wx.TextCtrl(self, -1, "", wx.DefaultPosition, (90,-1))
234     officeLocationLabel = wx.StaticText(self, -1, "Office Location: ")
235     self.officeLocationTextBox = wx.TextCtrl(self, -1, "", wx.DefaultPosition, (90,-1))
236     salesPersonLabel = wx.StaticText(self, -1, "Sales Person: ",wx.DefaultPosition)
237     self.salesPersonChoice = wx.Choice(self, -1, wx.DefaultPosition, choices=salesPersonList)
238 nino.borges 596 self.CreateBoxesSection()
239 nino.borges 597 self.sowOrProposalRadio1 = wx.RadioButton(self, -1, 'SOW',style=wx.RB_GROUP)
240     self.sowOrProposalRadio2 = wx.RadioButton(self, -1, 'Proposal')
241     self.hostedRadio1 = wx.RadioButton(self, -1, 'Hosted Using Xpress',style=wx.RB_GROUP)
242     self.hostedRadio2 = wx.RadioButton(self, -1, 'Non-Hosted')
243 nino.borges 596
244 nino.borges 597 sowOrProposalStaticBox = wx.StaticBox(self, -1, 'SOW or Proposal:')
245 nino.borges 596 sowOrProposalStaticBoxSizer = wx.StaticBoxSizer(sowOrProposalStaticBox, wx.HORIZONTAL)
246    
247    
248     requiredSectionSizer = wx.GridBagSizer(10,2)
249     requiredSectionSizer.Add(clientNameLabel,pos = (0,0))
250     requiredSectionSizer.Add(self.clientNameTextBox,pos = (0,1),span=(1,4), flag = wx.EXPAND)
251     requiredSectionSizer.Add(projectNameLabel,pos = (1,0))
252     requiredSectionSizer.Add(self.projectNameTextBox,pos = (1,1))
253     requiredSectionSizer.Add(officeLocationLabel,pos = (2,0))
254     requiredSectionSizer.Add(self.officeLocationTextBox,pos = (2,1))
255     requiredSectionSizer.Add(salesPersonLabel,pos = (3,0))
256     requiredSectionSizer.Add(self.salesPersonChoice,pos = (3,1))
257    
258     mainSizer = wx.BoxSizer(wx.VERTICAL)
259     sowOrProposalStaticBoxSizer.Add(self.sowOrProposalRadio1, 0, wx.ALL|wx.ALIGN_LEFT,20)
260     sowOrProposalStaticBoxSizer.Add(self.sowOrProposalRadio2, 0, wx.ALL|wx.ALIGN_LEFT,20)
261     mainSizer.Add(sowOrProposalStaticBoxSizer,0,wx.ALL, 20)
262     mainSizer.Add(requiredSectionSizer,0, wx.ALL, 20)
263    
264 nino.borges 597 hostedStaticBox = wx.StaticBox(self, -1, 'Hosted or Non-Hosted:')
265 nino.borges 596 hostedStaticBoxSizer = wx.StaticBoxSizer(hostedStaticBox, wx.HORIZONTAL)
266     hostedStaticBoxSizer.Add(self.hostedRadio1, 0, wx.ALL|wx.ALIGN_LEFT,20)
267     hostedStaticBoxSizer.Add(self.hostedRadio2, 0, wx.ALL|wx.ALIGN_LEFT,20)
268     mainSizer.Add(hostedStaticBoxSizer,0,wx.ALL, 20)
269 nino.borges 597
270 nino.borges 596
271     mainSizer.Add(self.buttonSizer,0, wx.ALL|wx.ALIGN_BOTTOM|wx.ALIGN_CENTER, 10)
272    
273 nino.borges 597 self.SetSizer(mainSizer)
274 nino.borges 596
275 nino.borges 597 #self.Bind(wx.EVT_BUTTON, self.CloseWindow, self.cancelButton)
276    
277 nino.borges 596
278     def CreateBoxesSection(self):
279 nino.borges 597 self.oKButton = wx.Button(self, wx.ID_OK)
280 nino.borges 596 self.oKButton.SetDefault()
281     self.oKButton.SetSize(self.oKButton.GetBestSize())
282 nino.borges 597 self.cancelButton = wx.Button(self, wx.ID_CANCEL)
283 nino.borges 596 self.cancelButton.SetSize(self.cancelButton.GetBestSize())
284     self.buttonSizer = wx.BoxSizer(wx.HORIZONTAL)
285     self.buttonSizer.Add(self.oKButton,0,wx.ALL,10)
286     self.buttonSizer.Add(self.cancelButton,0,wx.ALL,10)
287    
288 nino.borges 597
289 nino.borges 596
290 nino.borges 597 class PricingPage(wx.Panel):
291     '''The settings notebook tab'''
292     def __init__(self,parent):
293     wx.Panel.__init__(self, parent)
294     ## Replace this with values from Excel
295     dataCollectionCost = 300
296     consultingServicesCost = 300
297     forensicAnalysisCost = 300
298     ecaProcessingCost = 100
299     nativePromotionCost = 275
300     ocrCost = .08
301     flocrCost = .15
302     analyticsProcessingCost = 100
303     projectManagementCost = 175
304     monthlyHostingCost = 20
305     monthlyUserCost = 100
306    
307     dataCollectionLabel = wx.StaticText(self, -1, "Onsite/Remote Data Collection: ")
308     dataCollectionUnitLabel = wx.StaticText(self, -1, "Hour")
309     self.dataCollectionSpin = wx.SpinCtrl(self,-1, "", wx.DefaultPosition, (80, -1))
310     self.dataCollectionSpin.SetRange(1, 1000)
311     self.dataCollectionSpin.SetValue(dataCollectionCost)
312     consultingServicesLabel = wx.StaticText(self, -1, "Consulting Services: ")
313     consultingServicesUnitLabel = wx.StaticText(self, -1, "Hour")
314     self.consultingServicesSpin = wx.SpinCtrl(self,-1, "", wx.DefaultPosition, (80, -1))
315     self.consultingServicesSpin.SetRange(1, 1000)
316     self.consultingServicesSpin.SetValue(consultingServicesCost)
317     forensicAnalysisLabel = wx.StaticText(self, -1, "Forensic Analysis: ")
318     forensicAnalysisUnitLabel = wx.StaticText(self, -1, "Hour")
319     self.forensicAnalysisSpin = wx.SpinCtrl(self,-1, "", wx.DefaultPosition, (80, -1))
320     self.forensicAnalysisSpin.SetRange(1, 1000)
321     self.forensicAnalysisSpin.SetValue(forensicAnalysisCost)
322 nino.borges 596
323 nino.borges 597 ecaProcessingLabel = wx.StaticText(self, -1, "ECA Processing: ")
324     ecaProcessingUnitLabel = wx.StaticText(self, -1, "GB")
325     self.ecaProcessingSpin = wx.SpinCtrl(self,-1, "", wx.DefaultPosition, (80, -1))
326     self.ecaProcessingSpin.SetRange(1, 1000)
327     self.ecaProcessingSpin.SetValue(ecaProcessingCost)
328     nativePromotionLabel = wx.StaticText(self, -1, "Native Review Promotion: ")
329     nativePromotionUnitLabel = wx.StaticText(self, -1, "GB")
330     self.nativePromotionSpin = wx.SpinCtrl(self,-1, "", wx.DefaultPosition, (80, -1))
331     self.nativePromotionSpin.SetRange(1, 1000)
332     self.nativePromotionSpin.SetValue(nativePromotionCost)
333     ocrLabel = wx.StaticText(self, -1, "Optical Character Recog.: ")
334     ocrUnitLabel = wx.StaticText(self, -1, "Document")
335     self.ocrSpin = wx.SpinCtrlDouble(self,-1, "", wx.DefaultPosition, (80, -1),inc = .01)
336     self.ocrSpin.SetRange(.01, 10)
337     self.ocrSpin.SetValue(ocrCost)
338     flocrLabel = wx.StaticText(self, -1, "OCR Foreign Language: ")
339     flocrUnitLabel = wx.StaticText(self, -1, "Document")
340     self.flocrSpin = wx.SpinCtrlDouble(self,-1, "", wx.DefaultPosition, (80, -1),inc = .01)
341     self.flocrSpin.SetRange(.01, 10)
342     self.flocrSpin.SetValue(flocrCost)
343     analyticsProcessingLabel = wx.StaticText(self, -1, "Analytics Processing: ")
344     analyticsProcessingUnitLabel = wx.StaticText(self, -1, "GB")
345     self.analyticsProcessingSpin = wx.SpinCtrl(self,-1, "", wx.DefaultPosition, (80, -1))
346     self.analyticsProcessingSpin.SetRange(1, 1000)
347     self.analyticsProcessingSpin.SetValue(analyticsProcessingCost)
348    
349     projectManagementLabel = wx.StaticText(self, -1, "Project Management: ")
350     projectManagementUnitLabel = wx.StaticText(self, -1, "Hour")
351     self.projectManagementSpin = wx.SpinCtrl(self,-1, "", wx.DefaultPosition, (80, -1))
352     self.projectManagementSpin.SetRange(1, 1000)
353     self.projectManagementSpin.SetValue(projectManagementCost)
354     monthlyHostingLabel = wx.StaticText(self, -1, "Monthly Hosting : ")
355     monthlyHostingUnitLabel = wx.StaticText(self, -1, "GB/Month")
356     self.monthlyHostingSpin = wx.SpinCtrl(self,-1, "", wx.DefaultPosition, (80, -1))
357     self.monthlyHostingSpin.SetRange(1, 1000)
358     self.monthlyHostingSpin.SetValue(monthlyHostingCost)
359     userFeesLabel = wx.StaticText(self, -1, "Monthly User Fee : ")
360     userFeesUnitLabel = wx.StaticText(self, -1, "User/Month")
361     self.userFeesSpin = wx.SpinCtrl(self,-1, "", wx.DefaultPosition, (80, -1))
362     self.userFeesSpin.SetRange(1, 1000)
363     self.userFeesSpin.SetValue(monthlyUserCost)
364 nino.borges 596
365 nino.borges 597
366     mainSizer = wx.BoxSizer(wx.VERTICAL)
367     forensicsServicesSizer = wx.GridBagSizer(3,3)
368     forensicsServicesSizer.Add(dataCollectionLabel, pos = (0,0))
369     forensicsServicesSizer.Add(self.dataCollectionSpin, pos = (0,1))
370     forensicsServicesSizer.Add(dataCollectionUnitLabel, pos = (0,2))
371 nino.borges 596
372 nino.borges 597 forensicsServicesSizer.Add(consultingServicesLabel, pos = (1,0))
373     forensicsServicesSizer.Add(self.consultingServicesSpin, pos = (1,1))
374     forensicsServicesSizer.Add(consultingServicesUnitLabel, pos = (1,2))
375    
376     forensicsServicesSizer.Add(forensicAnalysisLabel, pos = (2,0))
377     forensicsServicesSizer.Add(self.forensicAnalysisSpin, pos = (2,1))
378     forensicsServicesSizer.Add(forensicAnalysisUnitLabel, pos = (2,2))
379    
380     processingSizer = wx.GridBagSizer(5,3)
381     processingSizer.Add(ecaProcessingLabel, pos = (0,0))
382     processingSizer.Add(self.ecaProcessingSpin, pos = (0,1))
383     processingSizer.Add(ecaProcessingUnitLabel, pos = (0,2))
384     processingSizer.Add(nativePromotionLabel, pos = (1,0))
385     processingSizer.Add(self.nativePromotionSpin, pos = (1,1))
386     processingSizer.Add(nativePromotionUnitLabel, pos = (1,2))
387     processingSizer.Add(ocrLabel, pos = (2,0))
388     processingSizer.Add(self.ocrSpin, pos = (2,1))
389     processingSizer.Add(ocrUnitLabel, pos = (2,2))
390     processingSizer.Add(flocrLabel, pos = (3,0))
391     processingSizer.Add(self.flocrSpin, pos = (3,1))
392     processingSizer.Add(flocrUnitLabel, pos = (3,2))
393     processingSizer.Add(analyticsProcessingLabel, pos = (4,0))
394     processingSizer.Add(self.analyticsProcessingSpin, pos = (4,1))
395     processingSizer.Add(analyticsProcessingUnitLabel, pos = (4,2))
396    
397     recurringFeesSizer = wx.GridBagSizer(3,3)
398     recurringFeesSizer.Add(projectManagementLabel, pos = (0,0))
399     recurringFeesSizer.Add(self.projectManagementSpin, pos = (0,1))
400     recurringFeesSizer.Add(projectManagementUnitLabel, pos = (0,2))
401     recurringFeesSizer.Add(monthlyHostingLabel, pos = (1,0))
402     recurringFeesSizer.Add(self.monthlyHostingSpin, pos = (1,1))
403     recurringFeesSizer.Add(monthlyHostingUnitLabel, pos = (1,2))
404     recurringFeesSizer.Add(userFeesLabel, pos = (2,0))
405     recurringFeesSizer.Add(self.userFeesSpin, pos = (2,1))
406     recurringFeesSizer.Add(userFeesUnitLabel, pos = (2,2))
407    
408    
409     forensicsStaticBox = wx.StaticBox(self, -1, 'Forensics Services')
410     forensicsStaticBoxSizer = wx.StaticBoxSizer(forensicsStaticBox, wx.HORIZONTAL)
411     processingStaticBox = wx.StaticBox(self, -1, 'Processing/Review Services')
412     processingStaticBoxSizer = wx.StaticBoxSizer(processingStaticBox, wx.HORIZONTAL)
413     recurringFeesStaticBox = wx.StaticBox(self, -1, 'Recurring Fees')
414     recurringFeesStaticBoxSizer = wx.StaticBoxSizer(recurringFeesStaticBox, wx.HORIZONTAL)
415    
416     forensicsStaticBoxSizer.Add(forensicsServicesSizer, 0, wx.ALL|wx.ALIGN_LEFT,18)
417     processingStaticBoxSizer.Add(processingSizer, 0, wx.ALL|wx.ALIGN_LEFT,18)
418     recurringFeesStaticBoxSizer.Add(recurringFeesSizer, 0, wx.ALL|wx.ALIGN_LEFT,18)
419    
420     mainSizer.Add(forensicsStaticBoxSizer,0,wx.ALL, 5)
421     mainSizer.Add(processingStaticBoxSizer,0,wx.ALL, 5)
422     mainSizer.Add(recurringFeesStaticBoxSizer,0,wx.ALL, 5)
423    
424    
425     self.SetSizer(mainSizer)
426    
427 nino.borges 596 class MyApp(wx.App):
428     def OnInit(self):
429     self.frame = MyFrame(None, -1, "SOW Creator v %s"%CreateSOW.version)
430     self.frame.Show(True)
431     self.SetTopWindow(self.frame)
432     return True
433    
434    
435     if __name__ == '__main__':
436     app = MyApp(0)
437     app.MainLoop()