├── 103
├── 104
├── 105
├── 106
├── 107
├── 108
├── 116
├── README.md
├── __pycache__
├── TextCtrlAutoComplete.cpython-36.pyc
├── accountsByFolio.cpython-36.pyc
├── cart.cpython-36.pyc
├── connectToDb.cpython-36.pyc
├── controlAccountPanel.cpython-36.pyc
├── convertQuotation.cpython-36.pyc
├── customerInfoPanel.cpython-36.pyc
├── gLedgerFunctions.cpython-36.pyc
├── incomeStatementPanel.cpython-36.pyc
├── invoiceInfoPanel.cpython-36.pyc
├── invoiceMaker.cpython-36.pyc
├── invoicePanel.cpython-36.pyc
├── journal.cpython-36.pyc
├── manualJournalEntryPanel.cpython-36.pyc
├── newCust.cpython-36.pyc
├── newProd.cpython-36.pyc
├── purchaseInfoPanel.cpython-36.pyc
├── purchasePanel.cpython-36.pyc
├── quotationPanel.cpython-36.pyc
├── quoteInfoPanel.cpython-36.pyc
├── saleInfoPanel.cpython-36.pyc
├── salesPanel.cpython-36.pyc
├── salesTerminal.cpython-36.pyc
├── stockLevelsPanel.cpython-36.pyc
├── supplierInfoPanel.cpython-36.pyc
├── terminalFrontEnd.cpython-36.pyc
├── updateInvoiceMoney.cpython-36.pyc
└── updatePurchaseMoney.cpython-36.pyc
├── accountsByFolio.py
├── autocomplete.py
├── cart.py
├── connectToDb.py
├── controlAccountPanel.py
├── convertQuotation.py
├── customerInfoPanel.py
├── databaseCreation.sql
├── gLedgerFunctions.py
├── incomeStatementPanel.py
├── invoiceInfoPanel.py
├── invoiceMaker.py
├── invoicePanel.py
├── journal.py
├── mainInterface.py
├── manualJournalEntryPanel.py
├── newCust.py
├── newProd.py
├── printer.py
├── purchaseInfoPanel.py
├── purchasePanel.py
├── quotationPanel.py
├── quoteInfoPanel.py
├── requirements.txt
├── saleInfoPanel.py
├── salesPanel.py
├── salesPanel2.py
├── salesTerminal(archived).py
├── stockLevelsPanel.py
├── supplierInfoPanel.py
├── terminalFrontEnd.py
├── updateInvoiceMoney.py
├── updatePurchaseMoney.py
└── validators.py
/103:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/104H/Open-Source-Python-POS-and-Accounting-Software/c13bb91d14470265807d05c0ac2e1ea3afa281dd/103
--------------------------------------------------------------------------------
/104:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/104H/Open-Source-Python-POS-and-Accounting-Software/c13bb91d14470265807d05c0ac2e1ea3afa281dd/104
--------------------------------------------------------------------------------
/105:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/104H/Open-Source-Python-POS-and-Accounting-Software/c13bb91d14470265807d05c0ac2e1ea3afa281dd/105
--------------------------------------------------------------------------------
/106:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/104H/Open-Source-Python-POS-and-Accounting-Software/c13bb91d14470265807d05c0ac2e1ea3afa281dd/106
--------------------------------------------------------------------------------
/107:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/104H/Open-Source-Python-POS-and-Accounting-Software/c13bb91d14470265807d05c0ac2e1ea3afa281dd/107
--------------------------------------------------------------------------------
/108:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/104H/Open-Source-Python-POS-and-Accounting-Software/c13bb91d14470265807d05c0ac2e1ea3afa281dd/108
--------------------------------------------------------------------------------
/116:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/104H/Open-Source-Python-POS-and-Accounting-Software/c13bb91d14470265807d05c0ac2e1ea3afa281dd/116
--------------------------------------------------------------------------------
/README.md:
--------------------------------------------------------------------------------
1 | # This project has moved here.
2 | # Open Source Python POS and Accounting Software
3 |
4 |
Description
5 |
6 |
7 | - Screenshots
8 | - This software is written using Python 3 and powered by MySQL.
9 | - It has so far been tested on Linux.
10 |
11 |
12 | Features
13 |
14 | Point of Sale
15 |
16 |
17 | - Functionality to query and add products by Barcode Number, Name and Code Name.
18 | - Associate customer with each sale and purchase using their unique contact mobile phone number.
19 | - Apply discount of individual products and the entire sale.
20 | - Sale with cash (full payment), cheque (credit sale), purchase and return both sales and purchase.
21 | - Update cash collected/paid against credit sales/purchase with cheque numbers.
22 |
23 |
24 | Accounting
25 |
26 |
27 | - Make automated General Journal Entries with each sale, purchase and returns of both. These entries are made in Sale, Purchase, Cash, Accounts Recievable and Accounts Payable of Individual Customers.
28 | - Make manual General Journal Entries
29 | - Edit existing entries
30 | - Display accounts of each Head of Account
31 | - Maintain Accounts Recievable and Payable of each customer
32 | - Create Control Account
33 | - Create Income Statement
34 | - All accounts mentioned above can be viewed for any date range
35 |
36 |
37 | Future Plans
38 |
39 |
40 | - Add ERP functionality to control access rights of employees
41 | - Add Depreciation and Inventory Valuation
42 | - Include BI Dashboard
43 |
44 |
45 | Development and Technicalities
46 |
47 | I have built this software using Python3. It uses PyMySQL and WxPython.
48 |
49 | To understand the design start following the code starting from mainInterface.py.
50 |
--------------------------------------------------------------------------------
/__pycache__/TextCtrlAutoComplete.cpython-36.pyc:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/104H/Open-Source-Python-POS-and-Accounting-Software/c13bb91d14470265807d05c0ac2e1ea3afa281dd/__pycache__/TextCtrlAutoComplete.cpython-36.pyc
--------------------------------------------------------------------------------
/__pycache__/accountsByFolio.cpython-36.pyc:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/104H/Open-Source-Python-POS-and-Accounting-Software/c13bb91d14470265807d05c0ac2e1ea3afa281dd/__pycache__/accountsByFolio.cpython-36.pyc
--------------------------------------------------------------------------------
/__pycache__/cart.cpython-36.pyc:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/104H/Open-Source-Python-POS-and-Accounting-Software/c13bb91d14470265807d05c0ac2e1ea3afa281dd/__pycache__/cart.cpython-36.pyc
--------------------------------------------------------------------------------
/__pycache__/connectToDb.cpython-36.pyc:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/104H/Open-Source-Python-POS-and-Accounting-Software/c13bb91d14470265807d05c0ac2e1ea3afa281dd/__pycache__/connectToDb.cpython-36.pyc
--------------------------------------------------------------------------------
/__pycache__/controlAccountPanel.cpython-36.pyc:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/104H/Open-Source-Python-POS-and-Accounting-Software/c13bb91d14470265807d05c0ac2e1ea3afa281dd/__pycache__/controlAccountPanel.cpython-36.pyc
--------------------------------------------------------------------------------
/__pycache__/convertQuotation.cpython-36.pyc:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/104H/Open-Source-Python-POS-and-Accounting-Software/c13bb91d14470265807d05c0ac2e1ea3afa281dd/__pycache__/convertQuotation.cpython-36.pyc
--------------------------------------------------------------------------------
/__pycache__/customerInfoPanel.cpython-36.pyc:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/104H/Open-Source-Python-POS-and-Accounting-Software/c13bb91d14470265807d05c0ac2e1ea3afa281dd/__pycache__/customerInfoPanel.cpython-36.pyc
--------------------------------------------------------------------------------
/__pycache__/gLedgerFunctions.cpython-36.pyc:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/104H/Open-Source-Python-POS-and-Accounting-Software/c13bb91d14470265807d05c0ac2e1ea3afa281dd/__pycache__/gLedgerFunctions.cpython-36.pyc
--------------------------------------------------------------------------------
/__pycache__/incomeStatementPanel.cpython-36.pyc:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/104H/Open-Source-Python-POS-and-Accounting-Software/c13bb91d14470265807d05c0ac2e1ea3afa281dd/__pycache__/incomeStatementPanel.cpython-36.pyc
--------------------------------------------------------------------------------
/__pycache__/invoiceInfoPanel.cpython-36.pyc:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/104H/Open-Source-Python-POS-and-Accounting-Software/c13bb91d14470265807d05c0ac2e1ea3afa281dd/__pycache__/invoiceInfoPanel.cpython-36.pyc
--------------------------------------------------------------------------------
/__pycache__/invoiceMaker.cpython-36.pyc:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/104H/Open-Source-Python-POS-and-Accounting-Software/c13bb91d14470265807d05c0ac2e1ea3afa281dd/__pycache__/invoiceMaker.cpython-36.pyc
--------------------------------------------------------------------------------
/__pycache__/invoicePanel.cpython-36.pyc:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/104H/Open-Source-Python-POS-and-Accounting-Software/c13bb91d14470265807d05c0ac2e1ea3afa281dd/__pycache__/invoicePanel.cpython-36.pyc
--------------------------------------------------------------------------------
/__pycache__/journal.cpython-36.pyc:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/104H/Open-Source-Python-POS-and-Accounting-Software/c13bb91d14470265807d05c0ac2e1ea3afa281dd/__pycache__/journal.cpython-36.pyc
--------------------------------------------------------------------------------
/__pycache__/manualJournalEntryPanel.cpython-36.pyc:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/104H/Open-Source-Python-POS-and-Accounting-Software/c13bb91d14470265807d05c0ac2e1ea3afa281dd/__pycache__/manualJournalEntryPanel.cpython-36.pyc
--------------------------------------------------------------------------------
/__pycache__/newCust.cpython-36.pyc:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/104H/Open-Source-Python-POS-and-Accounting-Software/c13bb91d14470265807d05c0ac2e1ea3afa281dd/__pycache__/newCust.cpython-36.pyc
--------------------------------------------------------------------------------
/__pycache__/newProd.cpython-36.pyc:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/104H/Open-Source-Python-POS-and-Accounting-Software/c13bb91d14470265807d05c0ac2e1ea3afa281dd/__pycache__/newProd.cpython-36.pyc
--------------------------------------------------------------------------------
/__pycache__/purchaseInfoPanel.cpython-36.pyc:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/104H/Open-Source-Python-POS-and-Accounting-Software/c13bb91d14470265807d05c0ac2e1ea3afa281dd/__pycache__/purchaseInfoPanel.cpython-36.pyc
--------------------------------------------------------------------------------
/__pycache__/purchasePanel.cpython-36.pyc:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/104H/Open-Source-Python-POS-and-Accounting-Software/c13bb91d14470265807d05c0ac2e1ea3afa281dd/__pycache__/purchasePanel.cpython-36.pyc
--------------------------------------------------------------------------------
/__pycache__/quotationPanel.cpython-36.pyc:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/104H/Open-Source-Python-POS-and-Accounting-Software/c13bb91d14470265807d05c0ac2e1ea3afa281dd/__pycache__/quotationPanel.cpython-36.pyc
--------------------------------------------------------------------------------
/__pycache__/quoteInfoPanel.cpython-36.pyc:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/104H/Open-Source-Python-POS-and-Accounting-Software/c13bb91d14470265807d05c0ac2e1ea3afa281dd/__pycache__/quoteInfoPanel.cpython-36.pyc
--------------------------------------------------------------------------------
/__pycache__/saleInfoPanel.cpython-36.pyc:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/104H/Open-Source-Python-POS-and-Accounting-Software/c13bb91d14470265807d05c0ac2e1ea3afa281dd/__pycache__/saleInfoPanel.cpython-36.pyc
--------------------------------------------------------------------------------
/__pycache__/salesPanel.cpython-36.pyc:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/104H/Open-Source-Python-POS-and-Accounting-Software/c13bb91d14470265807d05c0ac2e1ea3afa281dd/__pycache__/salesPanel.cpython-36.pyc
--------------------------------------------------------------------------------
/__pycache__/salesTerminal.cpython-36.pyc:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/104H/Open-Source-Python-POS-and-Accounting-Software/c13bb91d14470265807d05c0ac2e1ea3afa281dd/__pycache__/salesTerminal.cpython-36.pyc
--------------------------------------------------------------------------------
/__pycache__/stockLevelsPanel.cpython-36.pyc:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/104H/Open-Source-Python-POS-and-Accounting-Software/c13bb91d14470265807d05c0ac2e1ea3afa281dd/__pycache__/stockLevelsPanel.cpython-36.pyc
--------------------------------------------------------------------------------
/__pycache__/supplierInfoPanel.cpython-36.pyc:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/104H/Open-Source-Python-POS-and-Accounting-Software/c13bb91d14470265807d05c0ac2e1ea3afa281dd/__pycache__/supplierInfoPanel.cpython-36.pyc
--------------------------------------------------------------------------------
/__pycache__/terminalFrontEnd.cpython-36.pyc:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/104H/Open-Source-Python-POS-and-Accounting-Software/c13bb91d14470265807d05c0ac2e1ea3afa281dd/__pycache__/terminalFrontEnd.cpython-36.pyc
--------------------------------------------------------------------------------
/__pycache__/updateInvoiceMoney.cpython-36.pyc:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/104H/Open-Source-Python-POS-and-Accounting-Software/c13bb91d14470265807d05c0ac2e1ea3afa281dd/__pycache__/updateInvoiceMoney.cpython-36.pyc
--------------------------------------------------------------------------------
/__pycache__/updatePurchaseMoney.cpython-36.pyc:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/104H/Open-Source-Python-POS-and-Accounting-Software/c13bb91d14470265807d05c0ac2e1ea3afa281dd/__pycache__/updatePurchaseMoney.cpython-36.pyc
--------------------------------------------------------------------------------
/accountsByFolio.py:
--------------------------------------------------------------------------------
1 | # -*- coding: utf-8 -*-
2 |
3 | ###########################################################################
4 | ## Python code generated with wxFormBuilder (version Mar 6 2018)
5 | ## http://www.wxformbuilder.org/
6 | ##
7 | ## PLEASE DO *NOT* EDIT THIS FILE!
8 | ###########################################################################
9 |
10 | import wx
11 | import wx.xrc
12 | import wx.grid
13 | import wx.adv
14 | import re
15 |
16 | from connectToDb import connectToDB
17 |
18 | conn = connectToDB()
19 |
20 | ###########################################################################
21 | ## Class MyFrame1
22 | ###########################################################################
23 |
24 | class folioAccountsPanel ( wx.Panel ):
25 |
26 | def __init__( self, parent ):
27 | self.selectedFolio = 'Cash'
28 |
29 | wx.Panel.__init__ ( self, parent, wx.ID_ANY, wx.DefaultPosition, wx.DefaultSize, wx.TAB_TRAVERSAL )
30 |
31 | bSizerMain = wx.BoxSizer( wx.VERTICAL )
32 |
33 | bSizerDate = wx.BoxSizer( wx.HORIZONTAL )
34 | bSizerGrid = wx.BoxSizer( wx.HORIZONTAL )
35 |
36 | ########### Combo Box Start
37 | self.folios = self.fetchFolios()
38 |
39 | self.m_folioCombo = wx.ComboBox(self, size=wx.DefaultSize, choices= list(self.folios.keys()) )
40 | ########### Combo Box End
41 | bSizerDate.Add (self.m_folioCombo, 1, wx.ALL|wx.EXPAND, 5 )
42 |
43 | ########### Date Picker Start
44 | self.m_startDate = wx.adv.DatePickerCtrl(self, size=(60,-1), style = wx.adv.DP_DROPDOWN | wx.adv.DP_SHOWCENTURY | wx.adv.DP_ALLOWNONE)
45 | self.m_endDate = wx.adv.DatePickerCtrl(self, size=(60,-1), style = wx.adv.DP_DROPDOWN | wx.adv.DP_SHOWCENTURY | wx.adv.DP_ALLOWNONE)
46 | ########### Date Picker End
47 |
48 | bSizerDate.Add (self.m_startDate, 1, wx.ALL|wx.EXPAND, 5 )
49 | bSizerDate.Add (self.m_endDate, 1, wx.ALL|wx.EXPAND, 5 )
50 |
51 | ########### Cart Grid Start
52 | self.m_journalGrid = wx.grid.Grid( self, wx.ID_ANY, wx.DefaultPosition, wx.Size( -1,-1 ), 0 )
53 | self.m_journalGrid.CreateGrid( 500, 10 )
54 | self.m_journalGrid.EnableEditing( False )
55 | self.m_journalGrid.EnableGridLines( True )
56 | self.m_journalGrid.EnableDragGridSize( False )
57 | self.m_journalGrid.SetMargins( 0, 0 )
58 | self.m_journalGrid.SetRowLabelSize( 1 )
59 | #self.m_journalGrid.AutoSizeColLabelSize( True )
60 |
61 | '''
62 | self.m_journalGrid.SetColSize( 0, 20 )
63 | self.m_journalGrid.SetColSize( 1, 40 )
64 | self.m_journalGrid.SetColSize( 2, 60 )
65 | self.m_journalGrid.SetColSize( 3, 80 )
66 | self.m_journalGrid.SetColSize( 4, 90 )
67 | self.m_journalGrid.SetColSize( 5, 110 )
68 | self.m_journalGrid.SetColSize( 6, 130 )
69 | self.m_journalGrid.SetColSize( 7, 150 )
70 | self.m_journalGrid.SetColSize( 8, 170 )
71 | '''
72 |
73 | self.m_journalGrid.SetColSize( 0, 30 )
74 | self.m_journalGrid.SetColSize( 1, 60 )
75 | self.m_journalGrid.SetColSize( 2, 90 )
76 | self.m_journalGrid.SetColSize( 3, 120 )
77 | self.m_journalGrid.SetColSize( 4, 150 )
78 | self.m_journalGrid.SetColSize( 5, 180 )
79 | self.m_journalGrid.SetColSize( 6, 210 )
80 | self.m_journalGrid.SetColSize( 7, 240 )
81 | self.m_journalGrid.SetColSize( 8, 270 )
82 | self.m_journalGrid.SetColSize( 9, 300 )
83 |
84 | self.m_journalGrid.SetColLabelValue( 0, u"ID" )
85 | self.m_journalGrid.SetColLabelValue( 1, u"Date" )
86 | self.m_journalGrid.SetColLabelValue( 2, u"Time" )
87 | self.m_journalGrid.SetColLabelValue( 3, u"Head of A/C" )
88 | self.m_journalGrid.SetColLabelValue( 4, u"Folio Number" )
89 | self.m_journalGrid.SetColLabelValue( 5, u"Transaction ID" )
90 | self.m_journalGrid.SetColLabelValue( 6, u"Cheque Number" )
91 | self.m_journalGrid.SetColLabelValue( 7, u"Debit" )
92 | self.m_journalGrid.SetColLabelValue( 8, u"Credit" )
93 | self.m_journalGrid.SetColLabelValue( 9, u"Balance" )
94 |
95 | self.m_journalGrid.SetColLabelAlignment( wx.ALIGN_CENTRE, wx.ALIGN_CENTRE )
96 | self.m_journalGrid.SetRowLabelAlignment( wx.ALIGN_CENTRE, wx.ALIGN_CENTRE )
97 |
98 | self.populateTable()
99 | ########### Cart Grid End
100 |
101 | bSizerGrid.Add (self.m_journalGrid, 1, wx.ALL|wx.EXPAND, 5 )
102 |
103 | bSizerMain.Add( bSizerDate, 1, wx.ALL|wx.EXPAND, 5 )
104 | bSizerMain.Add( bSizerGrid, 1, wx.ALL|wx.EXPAND, 5 )
105 |
106 | self.SetSizer( bSizerMain )
107 | self.Layout()
108 | bSizerMain.Fit( self )
109 |
110 | self.m_startDate.Bind(wx.adv.EVT_DATE_CHANGED, self.dateChangeHandler)
111 | self.m_endDate.Bind(wx.adv.EVT_DATE_CHANGED, self.dateChangeHandler)
112 | self.m_folioCombo.Bind(wx.EVT_COMBOBOX, self.folioChangeHandler)
113 |
114 | def folioChangeHandler (self, event):
115 | self.selectedFolio = self.m_folioCombo.GetValue()
116 | self.reloadJournal()
117 |
118 | def dateChangeHandler (self, event):
119 | self.reloadJournal()
120 |
121 | def reloadJournal (self):
122 | self.m_journalGrid.DeleteRows(numRows=self.m_journalGrid.GetNumberRows())
123 | self.m_journalGrid.InsertRows(numRows=500)
124 |
125 | self.populateTable()
126 |
127 | def fetchFolios (self):
128 | qry = 'SELECT id, description FROM headOfAccounts'
129 | curs = conn.cursor()
130 | curs.execute(qry)
131 | r = curs.fetchall()
132 |
133 | folios = {}
134 | for x in r:
135 | folios.update({x['description'] : x['id']})
136 | return folios
137 |
138 | def populateTable (self):
139 | #print(type(self.m_startDate.GetValue()))
140 | #print(type(self.m_endDate.GetValue().Format("%F")))
141 | if (self.selectedFolio[:8] == "Customer" and self.selectedFolio[-1:] == "R"):
142 | computation = "SUM(Debit) - SUM(Credit)"
143 | elif (self.selectedFolio[:8] == "Supplier" and self.selectedFolio[-1:] == "P"):
144 | computation = "SUM(Credit) - SUM(Debit)"
145 | elif (self.selectedFolio == "Purchase"):
146 | computation = "SUM(Debit) - SUM(Credit)"
147 | elif (self.selectedFolio == "Sale"):
148 | computation = "SUM(Credit) - SUM(Debit)"
149 | elif (self.selectedFolio == "Cash"):
150 | computation = "SUM(Debit) - SUM(Credit)"
151 | elif (self.selectedFolio == "Bank"):
152 | computation = "SUM(Debit) - SUM(Credit)"
153 | elif (self.selectedFolio == "SalesDiscount"):
154 | computation = "SUM(Debit) - SUM(Credit)"
155 | elif (self.selectedFolio == "PurchaseDiscount"):
156 | computation = "SUM(Credit) - SUM(Debit)"
157 | elif (self.selectedFolio == "SalesReturn"):
158 | computation = "SUM(Debit) - SUM(Credit)"
159 | elif (self.selectedFolio == "PurchaseReturn"):
160 | computation = "SUM(Credit) - SUM(Debit)"
161 | else:
162 | computation = "SUM(Credit) - SUM(Debit)"
163 |
164 | qry = 'SELECT gl.id, gl.dateTime, hoa.description, gl.headOfAc, gl.transactionType, gl.chequeNo, gl.Debit, gl.Credit, ( SELECT %s FROM generalLedger WHERE id <= gl.id and headOfAc = "%s") AS Balance FROM generalLedger gl, headOfAccounts hoa where gl.headOfAc = hoa.id AND gl.dateTime BETWEEN "%s" AND "%s" AND hoa.description = "%s" LIMIT 500' % ( computation, self.folios[self.selectedFolio], self.m_startDate.GetValue().Format("%F") + " 00:00:00", self.m_endDate.GetValue().Format("%F") + " 23:59:59", self.selectedFolio)
165 |
166 | con = connectToDB()
167 | curs = con.cursor()
168 | curs.execute(qry)
169 |
170 | row = 0
171 | while (1):
172 | r = curs.fetchone()
173 | if (r is not None):
174 | x = re.search ("(?<=Customer)[0-9]*", r['description'])
175 | if x is not None:
176 | q = 'SELECT name FROM customer WHERE id = %s' % (x.group(0))
177 | c = con.cursor()
178 | c.execute(q)
179 | cust = c.fetchone()
180 | r['description'] = cust['name'] + " A/C Recievable"
181 |
182 | x = re.search ("(?<=Supplier)[0-9]*", r['description'])
183 | if x is not None:
184 | q = 'SELECT name FROM supplier WHERE id = %s' % (x.group(0))
185 | c = con.cursor()
186 | c.execute(q)
187 | cust = c.fetchone()
188 | r['description'] = cust['name'] + " A/C Payable"
189 |
190 | self.m_journalGrid.SetCellValue(row, 0, str(r['id']))
191 | self.m_journalGrid.SetCellValue(row, 1, str(r['dateTime'])[:11])
192 | self.m_journalGrid.SetCellValue(row, 2, str(r['dateTime'])[11:])
193 |
194 | if (r['Credit'] > 0):
195 | self.m_journalGrid.SetCellValue(row, 3, " "+r['description'])
196 | self.m_journalGrid.SetCellValue(row, 8, str(r['Credit']))
197 | else:
198 | self.m_journalGrid.SetCellValue(row, 3, r['description'])
199 | self.m_journalGrid.SetCellValue(row, 7, str(r['Debit']))
200 | self.m_journalGrid.SetCellValue(row, 4, str(r['headOfAc']))
201 | self.m_journalGrid.SetCellValue(row, 5, r['transactionType'])
202 | if (r['chequeNo'] is not None):
203 | self.m_journalGrid.SetCellValue(row, 6, r['chequeNo'])
204 | #self.m_journalGrid.SetCellValue(row, 7, str(r['Debit']))
205 | #self.m_journalGrid.SetCellValue(row, 8, str(r['Credit']))
206 | self.m_journalGrid.SetCellValue(row, 9, str(r['Balance']))
207 |
208 | row = row+1
209 | else:
210 | break
211 |
--------------------------------------------------------------------------------
/autocomplete.py:
--------------------------------------------------------------------------------
1 | # -*- coding: utf-8 -*-
2 | __license__ = """Copyright (c) 2008-2010, Toni Ruža, All rights reserved.
3 |
4 | Redistribution and use in source and binary forms, with or without modification,
5 | are permitted provided that the following conditions are met:
6 |
7 | * Redistributions of source code must retain the above copyright notice,
8 | this list of conditions and the following disclaimer.
9 | * Redistributions in binary form must reproduce the above copyright notice,
10 | this list of conditions and the following disclaimer in the documentation
11 | and/or other materials provided with the distribution.
12 |
13 | THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS 'AS IS'
14 | AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
15 | IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
16 | ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
17 | LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
18 | CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
19 | SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
20 | INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
21 | CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
22 | ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
23 | POSSIBILITY OF SUCH DAMAGE."""
24 |
25 | __author__ = u"Toni Ruža "
26 | __url__ = "http://bitbucket.org/raz/wxautocompletectrl"
27 |
28 |
29 | import wx
30 |
31 |
32 | class SuggestionsPopup(wx.Frame):
33 | def __init__(self, parent):
34 | wx.Frame.__init__(
35 | self, parent,
36 | style=wx.FRAME_NO_TASKBAR|wx.FRAME_FLOAT_ON_PARENT|wx.STAY_ON_TOP
37 | )
38 | self._suggestions = self._listbox(self)
39 | self._suggestions.SetItemCount(0)
40 | self._unformated_suggestions = None
41 |
42 | self.Sizer = wx.BoxSizer()
43 | self.Sizer.Add(self._suggestions, 1, wx.EXPAND)
44 |
45 | class _listbox(wx.HtmlListBox):
46 | items = None
47 |
48 | def OnGetItem(self, n):
49 | return self.items[n]
50 |
51 | def SetSuggestions(self, suggestions, unformated_suggestions):
52 | self._suggestions.items = suggestions
53 | self._suggestions.SetItemCount(len(suggestions))
54 | self._suggestions.SetSelection(0)
55 | self._suggestions.Refresh()
56 | self._unformated_suggestions = unformated_suggestions
57 |
58 | def CursorUp(self):
59 | selection = self._suggestions.GetSelection()
60 | if selection > 0:
61 | self._suggestions.SetSelection(selection - 1)
62 |
63 | def CursorDown(self):
64 | selection = self._suggestions.GetSelection()
65 | last = self._suggestions.GetItemCount() - 1
66 | if selection < last:
67 | self._suggestions.SetSelection(selection + 1)
68 |
69 | def CursorHome(self):
70 | if self.IsShown():
71 | self._suggestions.SetSelection(0)
72 |
73 | def CursorEnd(self):
74 | if self.IsShown():
75 | self._suggestions.SetSelection(self._suggestions.GetItemCount() - 1)
76 |
77 | def GetSelectedSuggestion(self):
78 | return self._unformated_suggestions[self._suggestions.GetSelection()]
79 |
80 | def GetSuggestion(self, n):
81 | return self._unformated_suggestions[n]
82 |
83 |
84 | class AutocompleteTextCtrl(wx.TextCtrl):
85 | def __init__(
86 | self, parent,
87 | height=300, completer=None,
88 | multiline=False, frequency=250
89 | ):
90 | style = wx.TE_PROCESS_ENTER
91 | if multiline:
92 | style = style | wx.TE_MULTILINE
93 | wx.TextCtrl.__init__(self, parent, style=style)
94 | self.height = height
95 | self.frequency = frequency
96 | if completer:
97 | self.SetCompleter(completer)
98 | self.queued_popup = False
99 | self.skip_event = False
100 |
101 | def SetCompleter(self, completer):
102 | """
103 | Initializes the autocompletion. The 'completer' has to be a function
104 | with one argument (the current value of the control, ie. the query)
105 | and it has to return two lists: formated (html) and unformated
106 | suggestions.
107 | """
108 | self.completer = completer
109 |
110 | frame = self.Parent
111 | while not isinstance(frame, wx.Frame):
112 | frame = frame.Parent
113 |
114 | self.popup = SuggestionsPopup(frame)
115 |
116 | frame.Bind(wx.EVT_MOVE, self.OnMove)
117 | self.Bind(wx.EVT_TEXT, self.OnTextUpdate)
118 | self.Bind(wx.EVT_SIZE, self.OnSizeChange)
119 | self.Bind(wx.EVT_KEY_DOWN, self.OnKeyDown)
120 | self.popup._suggestions.Bind(wx.EVT_LEFT_DOWN, self.OnSuggestionClicked)
121 | self.popup._suggestions.Bind(wx.EVT_KEY_DOWN, self.OnSuggestionKeyDown)
122 |
123 | def AdjustPopupPosition(self):
124 | self.popup.Move(self.ClientToScreen((0, self.Size.height)).Get())
125 | self.popup.Layout()
126 | self.popup.Refresh()
127 |
128 | def OnMove(self, event):
129 | self.AdjustPopupPosition()
130 | event.Skip()
131 |
132 | def OnTextUpdate(self, event):
133 | if self.skip_event:
134 | self.skip_event = False
135 | elif not self.queued_popup:
136 | wx.CallLater(self.frequency, self.AutoComplete)
137 | self.queued_popup = True
138 | event.Skip()
139 |
140 | def AutoComplete(self):
141 | self.queued_popup = False
142 | if self.Value != "":
143 | formated, unformated = self.completer(self.Value)
144 | if len(formated) > 0:
145 | self.popup.SetSuggestions(formated, unformated)
146 | self.AdjustPopupPosition()
147 | self.Unbind(wx.EVT_KILL_FOCUS)
148 | self.popup.ShowWithoutActivating()
149 | self.SetFocus()
150 | self.Bind(wx.EVT_KILL_FOCUS, self.OnKillFocus)
151 | else:
152 | self.popup.Hide()
153 | else:
154 | self.popup.Hide()
155 |
156 | def OnSizeChange(self, event):
157 | self.popup.Size = (self.Size[0], self.height)
158 | event.Skip()
159 |
160 | def OnKeyDown(self, event):
161 | key = event.GetKeyCode()
162 |
163 | if key == wx.WXK_UP:
164 | self.popup.CursorUp()
165 | return
166 |
167 | elif key == wx.WXK_DOWN:
168 | self.popup.CursorDown()
169 | return
170 |
171 | elif key in (wx.WXK_RETURN, wx.WXK_NUMPAD_ENTER) and self.popup.Shown:
172 | self.skip_event = True
173 | self.SetValue(self.popup.GetSelectedSuggestion())
174 | self.SetInsertionPointEnd()
175 | self.popup.Hide()
176 | return
177 |
178 | elif key == wx.WXK_HOME:
179 | self.popup.CursorHome()
180 |
181 | elif key == wx.WXK_END:
182 | self.popup.CursorEnd()
183 |
184 | elif event.ControlDown() and unichr(key).lower() == "a":
185 | self.SelectAll()
186 |
187 | elif key == wx.WXK_ESCAPE:
188 | self.popup.Hide()
189 | return
190 |
191 | event.Skip()
192 |
193 | def OnSuggestionClicked(self, event):
194 | self.skip_event = True
195 | n = self.popup._suggestions.HitTest(event.Position)
196 | self.Value = self.popup.GetSuggestion(n)
197 | self.SetInsertionPointEnd()
198 | wx.CallAfter(self.SetFocus)
199 | event.Skip()
200 |
201 | def OnSuggestionKeyDown(self, event):
202 | key = event.GetKeyCode()
203 | if key in (wx.WXK_RETURN, wx.WXK_NUMPAD_ENTER):
204 | self.skip_event = True
205 | self.SetValue(self.popup.GetSelectedSuggestion())
206 | self.SetInsertionPointEnd()
207 | self.popup.Hide()
208 | event.Skip()
209 |
210 | def OnKillFocus(self, event):
211 | if not self.popup.IsActive():
212 | self.popup.Hide()
213 | event.Skip()
214 |
--------------------------------------------------------------------------------
/cart.py:
--------------------------------------------------------------------------------
1 | from connectToDb import connectToDB
2 | import time as t
3 | import gLedgerFunctions as af
4 | import invoiceMaker as im
5 | #import printer as pr
6 |
7 | class product:
8 | def __init__ (self, pid, name, qty, price):
9 | self.pid = pid
10 | self.name = name
11 | self.qty = qty
12 | self.price = price
13 | self.origPrice = price
14 |
15 | class cart:
16 | def __init__ (self):
17 | self.products = []
18 |
19 | def __repr__ (self):
20 | return self.products
21 |
22 | def addProduct (self, pid, name, qty, sellingPrice):
23 | prod = product(pid, name, qty, sellingPrice)
24 | self.products.append(prod)
25 |
26 | def removeProduct (self, prod):
27 | c = 0
28 | for x in self.products:
29 | if x == prod:
30 | del self.products[c]
31 | c = c +1
32 |
33 | def makeEmpty(self):
34 | self.products = []
35 |
36 | def computeTotalBill (self):
37 | bill = 0
38 | for p in self.products:
39 | bill = bill + ( p.price * p.qty )
40 | return bill
41 |
42 | def computeTotalDiscount (self):
43 | discount = 0
44 | for p in self.products:
45 | discount = discount + ( p.qty * ( p.origPrice - p.price ) )
46 | return discount
47 |
48 | class terminal:
49 | def __init__ (self):
50 | self.conn = connectToDB()
51 | self.cart = cart()
52 |
53 | self.customerId = 0
54 | self.customerName = ''
55 | self.customerContact = ''
56 |
57 | self.supplierId = 0
58 | self.supplierName = ''
59 |
60 | self.operatorId = 0
61 |
62 | def getCart (self):
63 | return self.cart
64 |
65 | def getCartProducts (self):
66 | return self.cart.products
67 |
68 | def numberOfItems (self):
69 | return len(self.cart.products)
70 |
71 | def refresh (self):
72 | self.customerId = 0
73 | self.supplierId = 0
74 | self.cart.makeEmpty()
75 |
76 | def commitInsertQuery (self, qry):
77 | curs = self.conn.cursor()
78 | curs.execute(qry)
79 | insertId = self.conn.insert_id()
80 | self.conn.commit()
81 | return insertId
82 |
83 | def findProduct(self, productIdentifier, qty):
84 | qry = 'SELECT p.id FROM products p where p.codeName LIKE "%s"' % (productIdentifier)
85 | curs = self.conn.cursor()
86 | curs.execute(qry)
87 | r = curs.fetchone()
88 |
89 | if (r is None):
90 | qry = 'SELECT p.id FROM products p where p.barcode LIKE "%s"' % (productIdentifier)
91 | curs.execute(qry)
92 | r = curs.fetchone()
93 |
94 | if r is not None:
95 | for p in self.cart.products:
96 | if r['id'] == p.pid:
97 | return False
98 |
99 | x = self.scanProduct(r['id'], qty)
100 | return x
101 |
102 | def scanProduct (self, pid, qty):
103 | qry = 'SELECT ci.productId, ci.quantity, p.name, p.sellingPrice from currentinventory ci, products p where ci.productId = %d and ci.productId = p.id' % pid
104 | curs = self.conn.cursor()
105 | curs.execute(qry)
106 | r = curs.fetchone()
107 |
108 | if (r['quantity'] < qty):
109 | return r['quantity']
110 | else:
111 | qry = 'UPDATE `currentinventory` SET `quantity`=%d WHERE `productId` = %s' % (int(r['quantity'])-int(qty), r['productId'])
112 | curs.execute(qry)
113 | self.conn.commit()
114 |
115 | self.addToCart(pid, r['name'], qty, r['sellingPrice'])
116 | return True
117 |
118 | def addToCart (self, pid, name, qty, sellingPrice):
119 | self.cart.addProduct(pid, name, qty, sellingPrice)
120 |
121 | def removeFromCart (self, pid):
122 | self.cart.removeProduct(pid)
123 |
124 | def computeTotalBill(self):
125 | return self.cart.computeTotalBill()
126 |
127 | def computeTotalDiscount(self):
128 | return self.cart.computeTotalDiscount()
129 |
130 | '''
131 | # this version of the function changed stock levels as products were punched into the cart
132 | # but this was removed and simpler version was deployed after the client as for negative stock levels
133 | def increaseQty (self, pid, qty):
134 | qry = 'SELECT quantity from currentinventory where productId = %d' % pid
135 | curs = self.conn.cursor()
136 | curs.execute(qry)
137 | r = curs.fetchone()
138 |
139 | if (r['quantity'] < qty):
140 | return r['quantity']
141 | else:
142 | qry = 'UPDATE `currentinventory` SET `quantity`=`quantity`-%d WHERE `productId` = %s' % (int(qty), str(pid))
143 | self.commitInsertQuery(qry)
144 |
145 | c = 0
146 | for p in self.cart.products:
147 | if (pid == p.pid):
148 | self.cart.products[c].qty = self.cart.products[c].qty + qty
149 | c = c + 1
150 | return True
151 | '''
152 |
153 | def increaseQty (self, pid, qty):
154 | c = 0
155 | for p in self.cart.products:
156 | if (pid == p.pid):
157 | self.cart.products[c].qty = self.cart.products[c].qty + qty
158 | c = c + 1
159 | return True
160 |
161 | def fetchCustomerId (self, contact):
162 | qry = "SELECT id, name from customer WHERE contact = '%s'" % str( contact )
163 | curs = self.conn.cursor()
164 | curs.execute(qry)
165 | r = curs.fetchone()
166 |
167 | if r is not None:
168 | self.customerId = r['id']
169 | self.customerName = r['name']
170 | self.customerContact = str(contact)
171 | return True
172 | return False
173 |
174 | def registerNewCustomer (self, name, contact):
175 | qry = "INSERT INTO customer (name, contact) VALUES ('%s', '%s')" % (cName, cust)
176 | self.customerId = self.commitInsertQuery(qry)
177 |
178 | def fetchSupplierId (self, contact):
179 | qry = "SELECT id, name from supplier WHERE contact = '%s'" % str( contact )
180 | curs = self.conn.cursor()
181 | curs.execute(qry)
182 | r = curs.fetchone()
183 |
184 | if r is not None:
185 | self.supplierId = r['id']
186 | self.supplierName = r['name']
187 | return True
188 | return False
189 |
190 | def registerNewSupplier (self, name, contact):
191 | qry = "INSERT INTO supplier (name, contact) VALUES ('%s', '%s')" % (cName, cust)
192 | self.supplierId = self.commitInsertQuery(qry)
193 |
194 | # ========== Cash Sale =================================
195 | def checkout (self):
196 | if (len(self.cart.products) == 0):
197 | return
198 |
199 | bill = self.computeTotalBill()
200 | discount = self.computeTotalDiscount()
201 |
202 | saleId = self.recordSale(bill, discount)
203 | self.recordProductsInSale(saleId)
204 | self.cashSaleJournalEntry(saleId, bill, discount)
205 | #printInvoice(t.strftime("%d-%m-%y", t.localtime()), i)
206 | self.refresh()
207 |
208 | def recordSale (self, bill, discount):
209 | qry = 'INSERT INTO `sales` (customer, totalBill, discount, preparedBy) VALUES (%d, %d, %d, %s)' % (self.customerId, bill, discount, self.operatorId)
210 | return self.commitInsertQuery(qry)
211 |
212 |
213 | def recordProductsInSale (self, saleId):
214 | for p in self.cart.products:
215 | qry = 'INSERT INTO productsale (saleId, product, quantity, price, discount) VALUES (%s, %s, %s, %s, %s)' % (saleId, p.pid, p.qty, p.price, p.origPrice - p.price )
216 | self.commitInsertQuery(qry)
217 |
218 | qry = 'UPDATE `currentinventory` SET `quantity`=`quantity`-%s WHERE `productId` = %s' % (p.qty, p.pid)
219 | return self.commitInsertQuery(qry)
220 |
221 |
222 | def cashSaleJournalEntry (self, saleId, bill, discount):
223 | af.cashSaleEntry(bill, discount, saleId)
224 |
225 | def returnProducts (self):
226 | if (len(self.cart.products) == 0):
227 | return
228 |
229 | bill = self.computeTotalBill()
230 | discount = self.computeTotalDiscount()
231 |
232 | returnId = self.recordReturn(bill, discount)
233 | self.recordProductsInReturn(returnId)
234 | self.returnJournalEntry(returnId, bill, discount)
235 | self.refresh()
236 |
237 | def recordReturn (self, bill, discount):
238 | qry = 'INSERT INTO `refunds` (customer, totalBill, discount, preparedBy) VALUES (%d, %d, %d, %s)' % (self.customerId, bill, discount, self.operatorId)
239 | return self.commitInsertQuery(qry)
240 |
241 | def recordProductsInReturn (self, saleId):
242 | for p in self.cart.products:
243 | qry = 'INSERT INTO productrefund (refundId, product, quantity, price, discount) VALUES (%s, %s, %s, %s, %s)' % (saleId, p.pid, p.qty, p.price, p.origPrice - p.price )
244 | self.commitInsertQuery(qry)
245 |
246 | def returnJournalEntry (self, returnId, bill, discount):
247 | af.returnEntry(bill, discount, returnId)
248 | # ========== Cash Sale =================================
249 |
250 | # ========== Invoice =================================
251 | def prepareInvoice (self, amtRecieved):
252 | if (len(self.cart.products) == 0):
253 | return
254 |
255 | bill = self.computeTotalBill()
256 | discount = self.computeTotalDiscount()
257 |
258 | invoiceId = self.recordInvoice(amtRecieved, bill, discount)
259 | self.recordProductsInInvoice(invoiceId)
260 | self.makeInvoice(invoiceId)
261 | self.invoiceSaleJournalEntry(invoiceId, bill, discount, amtRecieved)
262 | self.refresh()
263 |
264 | def recordInvoice (self, amtRecieved, bill, discount):
265 | qry = 'INSERT INTO invoice (employeeId, amount, amountRecieved, discount, buyerId) VALUES (%d, %d, "%s", %d, %d)' % (self.operatorId, bill, amtRecieved, discount, self.customerId)
266 | return self.commitInsertQuery(qry)
267 |
268 | def recordProductsInInvoice (self, invoiceId):
269 | for p in self.cart.products:
270 | qry = 'INSERT INTO productinvoice (invoiceId, product, quantity, price, discount) VALUES (%s, %s, %s, %s, %s)' % (invoiceId, p.pid, p.qty, p.price, p.origPrice - p.price )
271 | self.commitInsertQuery(qry)
272 |
273 | qry = 'UPDATE `currentinventory` SET `quantity`=`quantity`-%s WHERE `productId` = %s' % (p.qty, p.pid)
274 | return self.commitInsertQuery(qry)
275 |
276 |
277 | def invoiceSaleJournalEntry (self, invoiceId, bill, discount, amtRecieved):
278 | af.invoiceEntry (bill, discount, amtRecieved, self.customerId, invoiceId, cheque=1)
279 |
280 | def makeInvoice (self, invoiceId):
281 | prods = []
282 | for x in range(len(self.cart.products)):
283 | prods.append([self.cart.products[x].name, '', self.cart.products[x].qty, self.cart.products[x].price])
284 | im.imaker(str(invoiceId), invoiceId, self.operatorId, self.customerId, self.customerName, self.customerContact, prods, discountNo=0)
285 | # ========== Invoice =================================
286 |
287 | # ========== Quotation =================================
288 | def saveQuote (self, expDate):
289 | if (len(self.cart.products) == 0):
290 | return
291 |
292 | bill = self.computeTotalBill()
293 | discount = self.computeTotalDiscount()
294 |
295 | quoteId = self.recordQuote(bill, discount, expDate)
296 | self.recordProductsInQuotation(quoteId)
297 |
298 | self.refresh()
299 |
300 | def recordQuote (self, bill, discount, expDate):
301 | qry = 'INSERT INTO `quotations` (customer, totalBill, discount, preparedBy, expiryDate) VALUES (%s, %d, %d, %s, "%s")' % (self.customerId, bill, discount, self.operatorId, expDate)
302 | return self.commitInsertQuery(qry)
303 |
304 | def recordProductsInQuotation (self, quoteId):
305 | for p in self.cart.products:
306 | qry = 'INSERT INTO productquotes (quoteId, product, quantity, price, discount) VALUES (%s, %s, %s, %s, %s)' % (quoteId, p.pid, p.qty, p.price, p.origPrice - p.price)
307 | self.commitInsertQuery(qry)
308 | # ========== Quotation =================================
309 |
310 | # ========== Purchase =================================
311 | def purchaseItems (self, amountPaid):
312 | if (len(self.cart.products) == 0):
313 | return
314 |
315 | bill = self.computeTotalBill()
316 | discount = self.computeTotalDiscount()
317 |
318 | purchaseId = self.recordPurchase(amountPaid, bill, discount)
319 | self.recordProductsInPurchase(purchaseId)
320 | self.purchaseJournalEntry (bill, discount, amountPaid, purchaseId)
321 | self.refresh()
322 |
323 | def recordPurchase (self, amountPaid, bill, discount):
324 | qry = 'INSERT INTO `purchase` (supplier, totalBill, discount, amountPaid, preparedBy) VALUES (%s, %s, %s, %s, %s)' % (self.supplierId, bill, discount, amountPaid, self.operatorId)
325 | return self.commitInsertQuery(qry)
326 |
327 | def recordProductsInPurchase (self, purchaseId):
328 | for p in self.cart.products:
329 | qry = 'INSERT INTO productpurchase (purchaseId, product, quantity, price, discount) VALUES (%s, %s, %s, %s, %s)' % (purchaseId, p.pid, p.qty, p.price, p.origPrice - p.price)
330 |
331 | qry = 'UPDATE `currentinventory` SET `quantity`=`quantity`+%s WHERE `productId` = %s' % (p.qty, p.pid)
332 |
333 | self.commitInsertQuery(qry)
334 |
335 | def purchaseJournalEntry (self, bill, discount, amountPaid, purchaseId):
336 | af.purchaseEntry (bill, discount, amountPaid, self.supplierId, purchaseId)
337 | # ========== Purchase =================================
338 |
339 |
340 |
341 |
342 |
343 |
--------------------------------------------------------------------------------
/connectToDb.py:
--------------------------------------------------------------------------------
1 | import pymysql.cursors
2 |
3 |
4 | # Connect to the database
5 | def connectToDB():
6 | connection = pymysql.connect(host='localhost',
7 | user='root',
8 | password='',
9 | db='salmanwholeseller',
10 | charset='utf8mb4',
11 | cursorclass=pymysql.cursors.DictCursor)
12 | return connection
13 |
--------------------------------------------------------------------------------
/controlAccountPanel.py:
--------------------------------------------------------------------------------
1 | # -*- coding: utf-8 -*-
2 |
3 | ###########################################################################
4 | ## Python code generated with wxFormBuilder (version Mar 6 2018)
5 | ## http://www.wxformbuilder.org/
6 | ##
7 | ## PLEASE DO *NOT* EDIT THIS FILE!
8 | ###########################################################################
9 |
10 | import wx
11 | import wx.xrc
12 | import wx.grid
13 | import wx.adv
14 | import re
15 |
16 | from connectToDb import connectToDB
17 |
18 | conn = connectToDB()
19 |
20 | ###########################################################################
21 | ## Class MyFrame1
22 | ###########################################################################
23 |
24 | class controlAccountPanel ( wx.Panel ):
25 |
26 | def __init__( self, parent ):
27 |
28 | wx.Panel.__init__ ( self, parent, wx.ID_ANY, wx.DefaultPosition, wx.DefaultSize, wx.TAB_TRAVERSAL )
29 |
30 | bSizerMain = wx.BoxSizer( wx.VERTICAL )
31 |
32 | bSizerDate = wx.BoxSizer( wx.HORIZONTAL )
33 | bSizerGrid = wx.BoxSizer( wx.HORIZONTAL )
34 |
35 | ########### Date Picker Start
36 | self.m_startDate = wx.adv.DatePickerCtrl(self, size=(60,-1), style = wx.adv.DP_DROPDOWN | wx.adv.DP_SHOWCENTURY | wx.adv.DP_ALLOWNONE)
37 | self.m_endDate = wx.adv.DatePickerCtrl(self, size=(60,-1), style = wx.adv.DP_DROPDOWN | wx.adv.DP_SHOWCENTURY | wx.adv.DP_ALLOWNONE)
38 | ########### Date Picker End
39 |
40 | bSizerDate.Add (self.m_startDate, 1, wx.ALL|wx.EXPAND, 5 )
41 | bSizerDate.Add (self.m_endDate, 1, wx.ALL|wx.EXPAND, 5 )
42 |
43 | ########### Cart Grid Start
44 | self.m_journalGrid = wx.grid.Grid( self, wx.ID_ANY, wx.DefaultPosition, wx.Size( -1,-1 ), 0 )
45 | self.m_journalGrid.CreateGrid( 50, 2 )
46 | self.m_journalGrid.EnableEditing( False )
47 | self.m_journalGrid.EnableGridLines( True )
48 | self.m_journalGrid.EnableDragGridSize( False )
49 | self.m_journalGrid.SetMargins( 0, 0 )
50 | self.m_journalGrid.SetRowLabelSize( 1 )
51 | #self.m_journalGrid.AutoSizeColLabelSize( True )
52 |
53 | '''
54 | self.m_journalGrid.SetColSize( 0, 20 )
55 | self.m_journalGrid.SetColSize( 1, 40 )
56 | self.m_journalGrid.SetColSize( 2, 60 )
57 | self.m_journalGrid.SetColSize( 3, 80 )
58 | self.m_journalGrid.SetColSize( 4, 90 )
59 | self.m_journalGrid.SetColSize( 5, 110 )
60 | self.m_journalGrid.SetColSize( 6, 130 )
61 | self.m_journalGrid.SetColSize( 7, 150 )
62 | self.m_journalGrid.SetColSize( 8, 170 )
63 |
64 | self.m_journalGrid.SetColSize( 0, 30 )
65 | self.m_journalGrid.SetColSize( 1, 60 )
66 | self.m_journalGrid.SetColSize( 2, 90 )
67 | self.m_journalGrid.SetColSize( 3, 120 )
68 | self.m_journalGrid.SetColSize( 4, 150 )
69 | self.m_journalGrid.SetColSize( 5, 180 )
70 | self.m_journalGrid.SetColSize( 6, 210 )
71 | self.m_journalGrid.SetColSize( 7, 240 )
72 | self.m_journalGrid.SetColSize( 8, 270 )
73 | self.m_journalGrid.SetColSize( 9, 300 )
74 | '''
75 |
76 | self.m_journalGrid.SetColSize( 0, 50 )
77 | self.m_journalGrid.SetColSize( 1, 100 )
78 |
79 | self.m_journalGrid.SetColLabelValue( 0, u"Head Of Account" )
80 | self.m_journalGrid.SetColLabelValue( 1, u"Amount" )
81 |
82 | self.m_journalGrid.SetColLabelAlignment( wx.ALIGN_CENTRE, wx.ALIGN_CENTRE )
83 | self.m_journalGrid.SetRowLabelAlignment( wx.ALIGN_CENTRE, wx.ALIGN_CENTRE )
84 |
85 | self.populateTable()
86 | ########### Cart Grid End
87 |
88 | bSizerGrid.Add (self.m_journalGrid, 1, wx.ALL|wx.EXPAND, 5 )
89 |
90 | bSizerMain.Add( bSizerDate, 1, wx.ALL|wx.EXPAND, 5 )
91 | bSizerMain.Add( bSizerGrid, 1, wx.ALL|wx.EXPAND, 5 )
92 |
93 | self.SetSizer( bSizerMain )
94 | self.Layout()
95 | bSizerMain.Fit( self )
96 |
97 | self.m_startDate.Bind(wx.adv.EVT_DATE_CHANGED, self.dateChangeHandler)
98 | self.m_endDate.Bind(wx.adv.EVT_DATE_CHANGED, self.dateChangeHandler)
99 |
100 | def dateChangeHandler (self, event):
101 | self.reloadJournal()
102 |
103 | def reloadJournal (self):
104 | self.m_journalGrid.DeleteRows(numRows=self.m_journalGrid.GetNumberRows())
105 | self.m_journalGrid.InsertRows(numRows=500)
106 |
107 | self.populateTable()
108 |
109 | def populateTable (self):
110 | row = 0
111 | # 1 -- debit - credit
112 | # 0 -- credit - debit
113 | for x in range(2):
114 | if x == 0:
115 | computation = "SUM(gl.Credit) - SUM(gl.Debit)"
116 | elif x == 1:
117 | computation = "SUM(gl.Debit) - SUM(gl.Credit)"
118 |
119 | qry = 'SELECT hoa.description, %s as amt FROM generalLedger gl, headOfAccounts hoa WHERE gl.headOfAc = hoa.id AND gl.dateTime BETWEEN "%s" AND "%s" AND hoa.computation = %s GROUP BY gl.headOfAc' % (computation, self.m_startDate.GetValue().Format("%F") + " 00:00:00", self.m_endDate.GetValue().Format("%F") + " 23:59:59", str(x))
120 | curs = conn.cursor()
121 | curs.execute(qry)
122 |
123 | while (1):
124 | r = curs.fetchone()
125 | if (r is not None):
126 | self.m_journalGrid.SetCellValue(row, 0, r['description'])
127 | self.m_journalGrid.SetCellValue(row, 1, str(r['amt']))
128 | row = row + 1
129 | else:
130 | break
131 |
132 |
133 |
134 |
135 |
--------------------------------------------------------------------------------
/convertQuotation.py:
--------------------------------------------------------------------------------
1 | from connectToDb import connectToDB
2 |
3 | conn = connectToDB()
4 |
5 | import wx
6 | import wx.xrc
7 | import gLedgerFunctions as af
8 |
9 | class GetData(wx.Dialog):
10 | def __init__(self, parent, iid):
11 | self.iid = iid
12 | wx.Dialog.__init__(self, parent, wx.ID_ANY, "Quotation "+self.iid, size= (650,320))
13 | self.panel = wx.Panel(self,wx.ID_ANY)
14 |
15 | self.m_cartDV = wx.dataview.DataViewListCtrl( self.panel, wx.ID_ANY, (20,20), wx.Size( 600, 180 ), 0 )
16 | self.m_cartDV.SetMinSize( wx.Size( -1,400 ) )
17 |
18 | self.m_cartDV.AppendTextColumn('Name')
19 | self.m_cartDV.AppendTextColumn('Quantity')
20 | self.m_cartDV.AppendTextColumn('Price')
21 | self.m_cartDV.AppendTextColumn('Total Price')
22 |
23 | qry = 'select p.name, pq.quantity, pq.price from products p, productquotes pq, quotations q where p.id = pq.product and q.id = pq.quoteId and pq.quoteId = %s' % (iid)
24 | curs = conn.cursor()
25 | curs.execute(qry)
26 | r = curs.fetchone()
27 | while (1):
28 | if r is not None:
29 | self.m_cartDV.AppendItem([ r['name'], str(r['quantity']), str(r['price']), str(int(r['quantity']) * int(r['price'])) ])
30 | r = curs.fetchone()
31 | else:
32 | break
33 |
34 | self.lblRecMoney = wx.StaticText(self.panel, label="Recieved Money", pos=(20,220))
35 | self.recMoney = wx.TextCtrl(self.panel, value="", pos=(130,220), size=(90,-1))
36 |
37 | self.convertButton =wx.Button(self.panel, label="Convert to Invoice", pos=(110,260))
38 | self.closeButton =wx.Button(self.panel, label="Cancel", pos=(250,260))
39 |
40 | self.convertButton.Bind(wx.EVT_BUTTON, self.convertToInvoice)
41 | #self.convertButton.Bind(wx.EVT_BUTTON, self.asd)
42 | self.closeButton.Bind(wx.EVT_BUTTON, self.OnQuit)
43 |
44 | self.Bind(wx.EVT_CLOSE, self.OnQuit)
45 |
46 | self.Show()
47 |
48 | def OnQuit(self, event):
49 | self.result_name = None
50 | self.Destroy()
51 |
52 | def setToConverted (self):
53 | qry = 'UPDATE `quotations` SET converted = 1 WHERE id = %s' % (self.iid)
54 | curs = conn.cursor()
55 | curs.execute(qry)
56 | conn.commit()
57 |
58 | def saveInvoice (self):
59 | qry = 'select customer, preparedBy, totalBill, discount from quotations where id = %s' % (self.iid)
60 | curs = conn.cursor()
61 | curs.execute(qry)
62 | r = curs.fetchone()
63 |
64 | #amountRecieved = self.makePopUp("Enter Recieved Amount", "Convert to Invoice")
65 | amountRecieved = self.recMoney.GetValue()
66 |
67 | qry = 'INSERT INTO invoice (employeeId, amount, amountRecieved, discount, buyerId) VALUES (%d, "%d", "%s", %s, "%d")' % (r['preparedBy'], r['totalBill'], amountRecieved, r['discount'], r['customer'])
68 | curs.execute(qry)
69 | iId = conn.insert_id()
70 | print(iId)
71 | conn.commit()
72 |
73 | af.invoiceEntry (r['totalBill'], r['discount'], amountRecieved, r['customer'], iId) #save discount in quotations and pass it here
74 |
75 | qry = 'select pq.product, pq.quantity, pq.price from products p, productquotes pq, quotations q where p.id = pq.product and q.id = pq.quoteId and pq.quoteId = %s' % (self.iid)
76 | curs = conn.cursor()
77 | curs.execute(qry)
78 | r = curs.fetchone()
79 |
80 | insCurs = conn.cursor()
81 |
82 | while (1):
83 | if r is not None:
84 | insQry = 'INSERT INTO productinvoice (invoiceId, product, quantity, price) values (%s, %s, %s, %s)' % (iId, r['product'], r['quantity'], r['price'])
85 | insCurs.execute(insQry)
86 | r = curs.fetchone()
87 | else:
88 | break
89 | #im.imaker(str(iId), iId, '0', clientId, c['name'], c['contact'], prods, discountNo=0) print invoice
90 | conn.commit()
91 |
92 | def convertToInvoice(self, event):
93 | self.setToConverted()
94 | self.saveInvoice()
95 | self.Destroy()
96 |
97 | def makePopUp(self, prompt, title):
98 | pp = wx.TextEntryDialog(self, prompt, title)
99 | pp.ShowModal()
100 | r = pp.GetValue()
101 | pp.Destroy()
102 | pp.Show()
103 | return r
104 |
105 |
--------------------------------------------------------------------------------
/customerInfoPanel.py:
--------------------------------------------------------------------------------
1 | # 26th May, 2018 5:05pm
2 |
3 | import wx
4 | import wx.grid
5 | import wx.xrc
6 | import wx.dataview
7 |
8 | from connectToDb import connectToDB
9 |
10 | class customerInfoPanel ( wx.Panel ):
11 |
12 | def __init__( self, parent ):
13 | wx.Panel.__init__( self, parent, wx.ID_ANY, wx.DefaultPosition, wx.DefaultSize, wx.TAB_TRAVERSAL )
14 |
15 | bSizer11 = wx.BoxSizer( wx.VERTICAL )
16 |
17 | self.m_custInfoGrid = wx.grid.Grid( self, wx.ID_ANY, wx.DefaultPosition, wx.Size( -1,700 ), 0 )
18 |
19 | p = self.populateTable()
20 | lenP = len(p)
21 |
22 | # Grid
23 | self.m_custInfoGrid.CreateGrid( lenP, 5 )
24 | self.m_custInfoGrid.EnableEditing( False )
25 | self.m_custInfoGrid.EnableGridLines( True )
26 | self.m_custInfoGrid.EnableDragGridSize( False )
27 | self.m_custInfoGrid.SetMargins( 0, 0 )
28 |
29 | # Populate Table
30 | col=0
31 | for x in p:
32 | row=0
33 | # if amount of invoice is smaller than the amount recieved yet, colour the cell red
34 | if float(x['balance']) > 0:
35 | self.m_custInfoGrid.SetCellTextColour(row, 4, wx.Colour(255, 128, 128))
36 | for y in list(x.values()):
37 | self.m_custInfoGrid.SetCellValue(col, row, str(y))
38 | row = row+1
39 | col = col+1
40 |
41 | # Columns
42 | self.m_custInfoGrid.SetColSize( 0, 30 )
43 | self.m_custInfoGrid.SetColSize( 1, 100 )
44 | self.m_custInfoGrid.SetColSize( 2, 120 )
45 | self.m_custInfoGrid.SetColSize( 3, 140 )
46 | #self.m_custInfoGrid.AutoSizeColumns()
47 | self.m_custInfoGrid.EnableDragColMove( True )
48 | self.m_custInfoGrid.EnableDragColSize( True )
49 | self.m_custInfoGrid.SetColLabelSize( 30 )
50 | self.m_custInfoGrid.SetColLabelValue( 0, u"ID" )
51 | self.m_custInfoGrid.SetColLabelValue( 1, u"Name" )
52 | self.m_custInfoGrid.SetColLabelValue( 2, u"Contact" )
53 | self.m_custInfoGrid.SetColLabelValue( 3, u"Address" )
54 | self.m_custInfoGrid.SetColLabelValue( 4, u"Balance" )
55 | self.m_custInfoGrid.SetColLabelAlignment( wx.ALIGN_CENTRE, wx.ALIGN_CENTRE )
56 |
57 | # Rows
58 | self.m_custInfoGrid.EnableDragRowSize( False )
59 | self.m_custInfoGrid.SetRowLabelSize( 1 )
60 | self.m_custInfoGrid.SetRowLabelAlignment( wx.ALIGN_CENTRE, wx.ALIGN_CENTRE )
61 |
62 | # Label Appearance
63 |
64 | # Cell Defaults
65 | self.m_custInfoGrid.SetDefaultCellAlignment( wx.ALIGN_CENTRE, wx.ALIGN_TOP )
66 | bSizer11.Add( self.m_custInfoGrid, 0, wx.ALIGN_CENTRE|wx.ALL, 5 )
67 |
68 | self.SetSizer( bSizer11 )
69 | self.Layout()
70 | bSizer11.Fit( self )
71 |
72 | #self.m_custInfoGrid.Bind( wx.grid.EVT_GRID_CELL_LEFT_CLICK, self.updateCollectedMoney )
73 |
74 | def populateTable (self):
75 | qry = 'select c.id, c.name, c.contact, c.address, sum(i.amount - i.amountRecieved) as balance from customer c, invoice i where i.buyerId = c.id group by c.id'
76 |
77 | con = connectToDB()
78 | curs = con.cursor()
79 | curs.execute(qry)
80 |
81 | inv = []
82 |
83 | while (1):
84 | r = curs.fetchone()
85 | if (r is not None):
86 | inv.append(r)
87 | else:
88 | return inv
89 |
90 | def updateCustomers (self):
91 | self.m_custInfoGrid.DeleteRows(numRows=self.m_custInfoGrid.GetNumberRows())
92 |
93 | p = self.populateTable()
94 | lenP = len(p)
95 |
96 | self.m_custInfoGrid.InsertRows(numRows=lenP)
97 |
98 | # Populate Table
99 | col=0
100 | for x in p:
101 | row=0
102 | x = list(x.values())
103 | if float(x[4]) > 0:
104 | self.m_custInfoGrid.SetCellBackgroundColour(x[0], 4, wx.Colour(255, 128, 128))
105 | for y in x:
106 | self.m_custInfoGrid.SetCellValue(col, row, str(y))
107 | row = row+1
108 | col = col+1
109 |
110 | def updateCollectedMoney (self, event):
111 | iid = self.m_custInfoGrid.GetCellValue(event.GetRow(), 0)
112 | dlg = uim.GetData(self, iid)
113 | dlg.ShowModal()
114 | self.updateInvoices()
115 |
--------------------------------------------------------------------------------
/gLedgerFunctions.py:
--------------------------------------------------------------------------------
1 | # all functions defined make entries in the general journal
2 |
3 | '''
4 | 1 A/C Recievable
5 | 2 A/C Payable
6 | 3 Purchase
7 | 4 Sale
8 | 5 Cash
9 | 6 Bank
10 | 21 SalesDiscount
11 | 22 PurchaseDiscount
12 | 23 SalesReturn
13 | 24 PurchaseReturn
14 | '''
15 |
16 | from connectToDb import connectToDB
17 |
18 | conn = connectToDB()
19 |
20 | def determineCustHoA (cust, typ):
21 | qry = 'SELECT id FROM headOfAccounts WHERE description = "%s"' % ('Customer'+str(cust)+'-'+typ)
22 | curs = conn.cursor()
23 | curs.execute(qry)
24 | r = curs.fetchone()
25 | return r['id']
26 |
27 | def determineSuppHoA (cust, typ):
28 | qry = 'SELECT id FROM headOfAccounts WHERE description = "%s"' % ('Supplier'+str(cust)+'-'+typ)
29 | curs = conn.cursor()
30 | curs.execute(qry)
31 | r = curs.fetchone()
32 | return r['id']
33 |
34 | def cashSaleEntry (amt, discount, saleId):
35 | saleId = "Sle-" + str(saleId)
36 | qry = 'INSERT INTO generalLedger (headOfAc, transactionType, Debit, Credit) VALUES (5, "%s", %s, 0), (21, "%s", %s, 0), (4, "%s", 0, %s)' % (saleId, amt, saleId, discount, saleId, str( int(amt) + int(discount) ))
37 | curs = conn.cursor()
38 | curs.execute(qry)
39 | conn.commit()
40 |
41 | def invoiceEntry (amt, discount, amtRecieved, cust, invoiceId, cheque=1):
42 | #compute hoa using cust number from argument
43 | hoa = determineCustHoA(cust, 'R')
44 | invoiceId = 'Inv-'+str(invoiceId)
45 |
46 | c='6'
47 | if not(cheque):
48 | c = '5'
49 |
50 | qry = 'INSERT INTO generalLedger (headOfAc, transactionType, Debit, Credit) VALUES (%s, "%s", %s, 0), (21, "%s", %s, 0), (%s, "%s", %s, 0), (4, "%s", 0, %s)' % (c, invoiceId, amtRecieved, invoiceId, discount, hoa, invoiceId, str(int(amt) - int(amtRecieved)), invoiceId, str( int(amt)+int(discount) ))
51 |
52 | curs = conn.cursor()
53 | curs.execute(qry)
54 | conn.commit()
55 |
56 | '''
57 | curs = conn.cursor()
58 | qry = 'INSERT INTO generalLedger (headOfAc, Debit, Credit) VALUES (%s, %s, 0)' % (c, amt)
59 | curs.execute(qry)
60 | conn.commit()
61 |
62 | curs = conn.cursor()
63 | qry = 'INSERT INTO generalLedger (headOfAc, Debit, Credit) VALUES (%s, %s, 0)' % (str(hoa), str(int(amt) - int(amtRecieved)))
64 | curs.execute(qry)
65 | conn.commit()
66 |
67 | curs = conn.cursor()
68 | qry = 'INSERT INTO generalLedger (headOfAc, Debit, Credit) VALUES (4, 0, %s)' % (amtRecieved)
69 | curs.execute(qry)
70 | conn.commit()
71 | '''
72 |
73 | def invoiceMoneyUpdateEntry (amt, cust, invoiceId, chequeNo, cheque=1):
74 | #compute hoa using cust number from argument
75 | hoa = determineCustHoA(cust, 'R')
76 | invoiceId = 'Inv-'+str(invoiceId)
77 |
78 | curs = conn.cursor()
79 |
80 | c=6
81 | if not(cheque):
82 | c = '5'
83 |
84 | qry = 'INSERT INTO generalLedger (headOfAc, transactionType, chequeNo, Debit, Credit) VALUES (%s, "%s", "%s", %s, 0), (%s, "%s", "%s", 0, %s)' % (c, invoiceId, chequeNo, amt, hoa, invoiceId, chequeNo, amt)
85 | curs.execute(qry)
86 | conn.commit()
87 |
88 |
89 | def purchaseEntry (amt, discount, amtPaid, sup, purchaseId, cheque=1):
90 | #compute hoa using cust number from argument
91 | hoa = determineSuppHoA(sup, 'P')
92 | purchaseId = 'Pur-'+str(purchaseId)
93 |
94 | curs = conn.cursor()
95 |
96 | c=6
97 | if not(cheque):
98 | c = '5'
99 |
100 | qry = 'INSERT INTO generalLedger (headOfAc, transactionType, Debit, Credit) VALUES (3, "%s", %s, 0), (%s, "%s", 0, %s), (%s, "%s", 0, %s), (22, "%s", 0, %s)' % (purchaseId, str( int(amt)+int(discount) ), c, purchaseId, amtPaid, hoa, purchaseId, str( int(amt) - int(amtPaid) ), purchaseId, discount)
101 | curs.execute(qry)
102 | conn.commit()
103 |
104 |
105 | def purchaseMoneyUpdateEntry (amt, cust, purchaseId, chequeNo, cheque=1):
106 | #compute hoa using cust number from argument
107 | hoa = determineSuppHoA(cust, 'P')
108 | purchaseId = 'Pur-'+str(purchaseId)
109 |
110 | curs = conn.cursor()
111 |
112 | c=6
113 | if not(cheque):
114 | c = '5'
115 |
116 | qry = 'INSERT INTO generalLedger (headOfAc, transactionType, chequeNo, Debit, Credit) VALUES (%s, "%s", "%s", %s, 0), (%s, "%s", "%s", 0, %s)' % (hoa, purchaseId, chequeNo, amt, c, purchaseId, chequeNo, amt)
117 | print('here')
118 | curs.execute(qry)
119 | conn.commit()
120 |
121 | def returnEntry (amt, discount, refundId):
122 | # cash sale return
123 | refundId = "Rfd-" + str(refundId)
124 | qry = 'INSERT INTO generalLedger (headOfAc, transactionType, Debit, Credit) VALUES (23, "%s", %s, 0), (5, "%s", 0, %s), (21, "%s", 0, %s)' % (refundId, str( int(amt) + int(discount) ), refundId, amt, refundId, discount)
125 | curs = conn.cursor()
126 | curs.execute(qry)
127 | conn.commit()
128 |
129 |
130 | def invoiceReturnEntry (invoiceId, refundId):
131 | invoiceId = "Inv-" + str(invoiceId)
132 | refundId = "Rfd-"+str(refundId)
133 |
134 | qry = 'INSERT INTO generalLedger (headOfAc, transactionType, Debit, Credit) SELECT IF (headOfAc = 4, 23, headOfAc), "%s", Credit, Debit FROM generalLedger WHERE transactionType = "%s" ORDER BY id DESC' % (refundId, invoiceId)
135 |
136 | curs = conn.cursor()
137 | curs.execute(qry)
138 | conn.commit()
139 |
140 |
141 | def purchaseReturnEntry (purchaseId):
142 | # called by return prod
143 | refundId = "RPr-"+str(purchaseId)
144 | purchaseId = "Pur-" + str(purchaseId)
145 |
146 | qry = 'INSERT INTO generalLedger (headOfAc, transactionType, Debit, Credit) SELECT IF (headOfAc = 3, 24, headOfAc), "%s", Credit, Debit FROM generalLedger WHERE transactionType = "%s" ORDER BY id DESC' % (refundId, purchaseId)
147 |
148 | curs = conn.cursor()
149 | curs.execute(qry)
150 | conn.commit()
151 |
152 | def manualEntry (hoa, transcType, cheque, debit, credit):
153 | qry = 'INSERT INTO generalLedger (headOfAc, transactionType, chequeNo, Debit, Credit) VALUES ("%s", "%s", "%s", "%s", "%s")' % (hoa, transcType, cheque, debit, credit)
154 |
155 | curs = conn.cursor()
156 | curs.execute(qry)
157 | conn.commit()
158 |
--------------------------------------------------------------------------------
/incomeStatementPanel.py:
--------------------------------------------------------------------------------
1 | # -*- coding: utf-8 -*-
2 |
3 | ###########################################################################
4 | ## Python code generated with wxFormBuilder (version Mar 6 2018)
5 | ## http://www.wxformbuilder.org/
6 | ##
7 | ## PLEASE DO *NOT* EDIT THIS FILE!
8 | ###########################################################################
9 |
10 | import wx
11 | import wx.xrc
12 | import wx.grid
13 | import wx.adv
14 | import re
15 |
16 | from connectToDb import connectToDB
17 |
18 | conn = connectToDB()
19 |
20 | ###########################################################################
21 | ## Class MyFrame1
22 | ###########################################################################
23 |
24 | class incomeStatementPanel ( wx.Panel ):
25 |
26 | def __init__( self, parent ):
27 |
28 | wx.Panel.__init__ ( self, parent, wx.ID_ANY, wx.DefaultPosition, wx.DefaultSize, wx.TAB_TRAVERSAL )
29 |
30 | bSizerMain = wx.BoxSizer( wx.VERTICAL )
31 |
32 | bSizerDate = wx.BoxSizer( wx.HORIZONTAL )
33 | bSizerGrid = wx.BoxSizer( wx.HORIZONTAL )
34 |
35 | ########### Date Picker Start
36 | self.m_startDate = wx.adv.DatePickerCtrl(self, size=(60,-1), style = wx.adv.DP_DROPDOWN | wx.adv.DP_SHOWCENTURY | wx.adv.DP_ALLOWNONE)
37 | self.m_endDate = wx.adv.DatePickerCtrl(self, size=(60,-1), style = wx.adv.DP_DROPDOWN | wx.adv.DP_SHOWCENTURY | wx.adv.DP_ALLOWNONE)
38 | ########### Date Picker End
39 |
40 | bSizerDate.Add (self.m_startDate, 1, wx.ALL|wx.EXPAND, 5 )
41 | bSizerDate.Add (self.m_endDate, 1, wx.ALL|wx.EXPAND, 5 )
42 |
43 | ########### Cart Grid Start
44 | self.m_journalGrid = wx.grid.Grid( self, wx.ID_ANY, wx.DefaultPosition, wx.Size( -1,-1 ), 0 )
45 | self.m_journalGrid.CreateGrid( 50, 2 )
46 | self.m_journalGrid.EnableEditing( False )
47 | self.m_journalGrid.EnableGridLines( True )
48 | self.m_journalGrid.EnableDragGridSize( False )
49 | self.m_journalGrid.SetMargins( 0, 0 )
50 | self.m_journalGrid.SetRowLabelSize( 1 )
51 | #self.m_journalGrid.AutoSizeColLabelSize( True )
52 |
53 | '''
54 | self.m_journalGrid.SetColSize( 0, 20 )
55 | self.m_journalGrid.SetColSize( 1, 40 )
56 | self.m_journalGrid.SetColSize( 2, 60 )
57 | self.m_journalGrid.SetColSize( 3, 80 )
58 | self.m_journalGrid.SetColSize( 4, 90 )
59 | self.m_journalGrid.SetColSize( 5, 110 )
60 | self.m_journalGrid.SetColSize( 6, 130 )
61 | self.m_journalGrid.SetColSize( 7, 150 )
62 | self.m_journalGrid.SetColSize( 8, 170 )
63 |
64 | self.m_journalGrid.SetColSize( 0, 30 )
65 | self.m_journalGrid.SetColSize( 1, 60 )
66 | self.m_journalGrid.SetColSize( 2, 90 )
67 | self.m_journalGrid.SetColSize( 3, 120 )
68 | self.m_journalGrid.SetColSize( 4, 150 )
69 | self.m_journalGrid.SetColSize( 5, 180 )
70 | self.m_journalGrid.SetColSize( 6, 210 )
71 | self.m_journalGrid.SetColSize( 7, 240 )
72 | self.m_journalGrid.SetColSize( 8, 270 )
73 | self.m_journalGrid.SetColSize( 9, 300 )
74 | '''
75 |
76 | self.m_journalGrid.SetColSize( 0, 50 )
77 | self.m_journalGrid.SetColSize( 1, 100 )
78 |
79 | #self.m_journalGrid.SetColLabelValue( 0, u"Head Of Account" )
80 | #self.m_journalGrid.SetColLabelValue( 1, u"Amount" )
81 |
82 | self.m_journalGrid.SetColLabelAlignment( wx.ALIGN_CENTRE, wx.ALIGN_CENTRE )
83 | self.m_journalGrid.SetRowLabelAlignment( wx.ALIGN_CENTRE, wx.ALIGN_CENTRE )
84 |
85 | self.populateTable()
86 | ########### Cart Grid End
87 |
88 | bSizerGrid.Add (self.m_journalGrid, 1, wx.ALL|wx.EXPAND, 5 )
89 |
90 | bSizerMain.Add( bSizerDate, 1, wx.ALL|wx.EXPAND, 5 )
91 | bSizerMain.Add( bSizerGrid, 1, wx.ALL|wx.EXPAND, 5 )
92 |
93 | self.SetSizer( bSizerMain )
94 | self.Layout()
95 | bSizerMain.Fit( self )
96 |
97 | self.m_startDate.Bind(wx.adv.EVT_DATE_CHANGED, self.dateChangeHandler)
98 | self.m_endDate.Bind(wx.adv.EVT_DATE_CHANGED, self.dateChangeHandler)
99 |
100 | def dateChangeHandler (self, event):
101 | self.reloadJournal()
102 |
103 | def reloadJournal (self):
104 | self.m_journalGrid.DeleteRows(numRows=self.m_journalGrid.GetNumberRows())
105 | self.m_journalGrid.InsertRows(numRows=500)
106 |
107 | self.populateTable()
108 |
109 | def populateTable (self):
110 | curs = conn.cursor()
111 |
112 | ##### Sales
113 | qry = 'SELECT SUM(Credit) - SUM(Debit) as sales from generalLedger WHERE headOfAc = 4'
114 | curs.execute(qry)
115 | sales = curs.fetchone()['sales']
116 |
117 | qry = 'SELECT SUM(Debit) - SUM(Credit) as salesDisc from generalLedger WHERE headOfAc = 21'
118 | curs.execute(qry)
119 | salesDisc = curs.fetchone()['salesDisc']
120 |
121 | qry = 'SELECT SUM(Debit) - SUM(Credit) as salesReturn from generalLedger WHERE headOfAc = 23'
122 | curs.execute(qry)
123 | salesReturn = curs.fetchone()['salesReturn']
124 |
125 | netSales = sales - salesDisc - salesReturn
126 |
127 | qry = 'SELECT SUM(Debit) - SUM(Credit) as expenses from generalLedger WHERE headOfAc = 25'
128 | curs.execute(qry)
129 | expn = curs.fetchone()['expenses']
130 |
131 | qry = 'SELECT SUM(Debit) - SUM(Credit) as tax from generalLedger WHERE headOfAc = 26'
132 | curs.execute(qry)
133 | tax = curs.fetchone()['tax']
134 |
135 | ###### Cost of Goods
136 | qry = 'SELECT inventory from inventoryVal WHERE dateTime BETWEEN "%s" AND "%s"' % (self.m_startDate.GetValue().Format("%F") + " 00:00:00", self.m_startDate.GetValue().Format("%F") + " 23:59:59")
137 | curs.execute(qry)
138 | openInv = curs.fetchone()['inventory']
139 |
140 | qry = 'SELECT inventory from inventoryVal WHERE dateTime BETWEEN "%s" AND "%s"' % (self.m_endDate.GetValue().Format("%F") + " 00:00:00", self.m_endDate.GetValue().Format("%F") + " 23:59:59")
141 | curs.execute(qry)
142 | clsInv = curs.fetchone()['inventory']
143 |
144 | ####### Purchases
145 | qry = 'SELECT SUM(Debit) - SUM(Credit) as purchase from generalLedger WHERE headOfAc = 3'
146 | curs.execute(qry)
147 | purchase = curs.fetchone()['purchase']
148 |
149 | qry = 'SELECT SUM(Credit) - SUM(Debit) as purcDisc from generalLedger WHERE headOfAc = 22'
150 | curs.execute(qry)
151 | purchaseDisc = curs.fetchone()['purcDisc']
152 |
153 | qry = 'SELECT SUM(Credit) - SUM(Debit) as purcReturn from generalLedger WHERE headOfAc = 24'
154 | curs.execute(qry)
155 | purchaseReturn = curs.fetchone()['purcReturn']
156 |
157 | netPurchase = purchase - purchaseDisc - purchaseReturn
158 |
159 | ##### Cost of Goods Sold
160 | cogs = openInv + netPurchase - clsInv
161 |
162 | grossProfit = sales - cogs
163 |
164 | netProfit = grossProfit - expn
165 |
166 | profitAfterTax = netProfit - tax
167 |
168 | ###### Displaying in Grid
169 | self.m_journalGrid.SetCellValue(0, 0, "Sales")
170 | self.m_journalGrid.SetCellValue(0, 1, str( sales ))
171 |
172 | self.m_journalGrid.SetCellValue(2, 0, "Cost of Goods Sold")
173 | self.m_journalGrid.SetCellValue(2, 1, str( cogs ))
174 |
175 | self.m_journalGrid.SetCellValue(4, 0, "Gross Profit")
176 | self.m_journalGrid.SetCellValue(4, 1, str( grossProfit ))
177 |
178 | self.m_journalGrid.SetCellValue(6, 0, "Less")
179 | self.m_journalGrid.SetCellValue(7, 0, " Expenses")
180 | self.m_journalGrid.SetCellValue(7, 1, str( expn ))
181 |
182 | self.m_journalGrid.SetCellValue(9, 0, "Net Profit")
183 | self.m_journalGrid.SetCellValue(9, 1, str( netProfit ))
184 |
185 | self.m_journalGrid.SetCellValue(11, 0, "Tax")
186 | self.m_journalGrid.SetCellValue(11, 1, str( tax ))
187 |
188 | self.m_journalGrid.SetCellValue(13, 0, "Profit After Tax")
189 | self.m_journalGrid.SetCellValue(13, 1, str( profitAfterTax ))
190 |
191 | #self.m_journalGrid.SetCellValue(, 0, "")
192 | #self.m_journalGrid.SetCellValue(, 1, str( ))
193 |
194 |
195 |
196 |
197 |
--------------------------------------------------------------------------------
/invoiceInfoPanel.py:
--------------------------------------------------------------------------------
1 | # 26th May, 2018 5:05pm
2 |
3 | import wx
4 | import wx.grid
5 | import wx.xrc
6 | import wx.dataview
7 |
8 | from connectToDb import connectToDB
9 | import updateInvoiceMoney as uim
10 |
11 | class invoiceInfoPanel ( wx.Panel ):
12 |
13 | def __init__( self, parent ):
14 | wx.Panel.__init__( self, parent, wx.ID_ANY, wx.DefaultPosition, wx.DefaultSize, wx.TAB_TRAVERSAL )
15 |
16 | bSizer11 = wx.BoxSizer( wx.VERTICAL )
17 |
18 | self.m_invoiceGrid = wx.grid.Grid( self, wx.ID_ANY, wx.DefaultPosition, wx.Size( -1,700 ), 0 )
19 |
20 | p = self.populateTable()
21 | lenP = len(p)
22 |
23 | # Grid
24 | self.m_invoiceGrid.CreateGrid( lenP, 10 )
25 | self.m_invoiceGrid.EnableEditing( False )
26 | self.m_invoiceGrid.EnableGridLines( True )
27 | self.m_invoiceGrid.EnableDragGridSize( False )
28 | self.m_invoiceGrid.SetMargins( 0, 0 )
29 |
30 | # Populate Table
31 | col=0
32 | for x in p:
33 | row=0
34 | # if amount of invoice is smaller than the amount recieved yet, colour the cell red
35 | if float(x['amount']) > float(x['amountRecieved']):
36 | self.m_invoiceGrid.SetCellTextColour(row, 4, wx.Colour(255, 128, 128))
37 | for y in list(x.values()):
38 | self.m_invoiceGrid.SetCellValue(col, row, str(y))
39 | row = row+1
40 | col = col+1
41 |
42 | # Columns
43 | self.m_invoiceGrid.SetColSize( 0, 30 )
44 | self.m_invoiceGrid.SetColSize( 1, 100 )
45 | self.m_invoiceGrid.SetColSize( 2, 120 )
46 | self.m_invoiceGrid.SetColSize( 3, 140 )
47 | self.m_invoiceGrid.SetColSize( 4, 160 )
48 | self.m_invoiceGrid.SetColSize( 5, 210 )
49 | self.m_invoiceGrid.SetColSize( 6, 230 )
50 | self.m_invoiceGrid.SetColSize( 7, 250 )
51 | self.m_invoiceGrid.SetColSize( 8, 270 )
52 | self.m_invoiceGrid.SetColSize( 9, 300 )
53 | #self.m_invoiceGrid.AutoSizeColumns()
54 | self.m_invoiceGrid.EnableDragColMove( True )
55 | self.m_invoiceGrid.EnableDragColSize( True )
56 | self.m_invoiceGrid.SetColLabelSize( 30 )
57 | self.m_invoiceGrid.SetColLabelValue( 0, u"ID" )
58 | self.m_invoiceGrid.SetColLabelValue( 1, u"Date" )
59 | self.m_invoiceGrid.SetColLabelValue( 2, u"Time" )
60 | self.m_invoiceGrid.SetColLabelValue( 3, u"Amount" )
61 | self.m_invoiceGrid.SetColLabelValue( 4, u"Amount Recieved" )
62 | self.m_invoiceGrid.SetColLabelValue( 5, u"Bilty" )
63 | self.m_invoiceGrid.SetColLabelValue( 6, u"Agency" )
64 | self.m_invoiceGrid.SetColLabelValue( 7, u"Customer ID" )
65 | self.m_invoiceGrid.SetColLabelValue( 8, u"Customer Name" )
66 | self.m_invoiceGrid.SetColLabelValue( 9, u"Customer Contact" )
67 | self.m_invoiceGrid.SetColLabelAlignment( wx.ALIGN_CENTRE, wx.ALIGN_CENTRE )
68 |
69 | # Rows
70 | self.m_invoiceGrid.EnableDragRowSize( False )
71 | self.m_invoiceGrid.SetRowLabelSize( 1 )
72 | self.m_invoiceGrid.SetRowLabelAlignment( wx.ALIGN_CENTRE, wx.ALIGN_CENTRE )
73 |
74 | # Label Appearance
75 |
76 | # Cell Defaults
77 | self.m_invoiceGrid.SetDefaultCellAlignment( wx.ALIGN_CENTRE, wx.ALIGN_TOP )
78 | bSizer11.Add( self.m_invoiceGrid, 0, wx.ALIGN_CENTRE|wx.ALL, 5 )
79 |
80 | self.SetSizer( bSizer11 )
81 | self.Layout()
82 | bSizer11.Fit( self )
83 |
84 | self.m_invoiceGrid.Bind( wx.grid.EVT_GRID_CELL_LEFT_CLICK, self.updateCollectedMoney )
85 |
86 | def populateTable (self):
87 | qry = 'select i.id, SUBSTRING(i.timeStamp, 1, 11), SUBSTRING(i.timeStamp, 12), i.amount, i.amountRecieved, i.transportKey, i.transportAgency, c.id, c.name, c.contact from customer c, invoice i where i.buyerId = c.id ORDER BY i.id'
88 |
89 | con = connectToDB()
90 | curs = con.cursor()
91 | curs.execute(qry)
92 |
93 | inv = []
94 |
95 | while (1):
96 | r = curs.fetchone()
97 | if (r is not None):
98 | inv.append(r)
99 | else:
100 | return inv
101 |
102 | def updateInvoices (self):
103 | self.m_invoiceGrid.DeleteRows(numRows=self.m_invoiceGrid.GetNumberRows())
104 |
105 | p = self.populateTable()
106 | lenP = len(p)
107 |
108 | self.m_invoiceGrid.InsertRows(numRows=lenP)
109 |
110 | # Populate Table
111 | col=0
112 | for x in p:
113 | row=0
114 | x = list(x.values())
115 | if float(x[3]) > float(x[4]):
116 | self.m_invoiceGrid.SetCellBackgroundColour(x[0], 4, wx.Colour(255, 128, 128))
117 | for y in x:
118 | self.m_invoiceGrid.SetCellValue(col, row, str(y))
119 | row = row+1
120 | col = col+1
121 |
122 | def updateCollectedMoney (self, event):
123 | iid = self.m_invoiceGrid.GetCellValue(event.GetRow(), 0)
124 | cid = self.m_invoiceGrid.GetCellValue(event.GetRow(), 6)
125 | dlg = uim.GetData(self, iid, cid)
126 | dlg.ShowModal()
127 | self.updateInvoices()
128 |
--------------------------------------------------------------------------------
/invoiceMaker.py:
--------------------------------------------------------------------------------
1 | from datetime import datetime, date
2 | from pyinvoice.models import InvoiceInfo, ServiceProviderInfo, ClientInfo, Item, Transaction
3 | from pyinvoice.templates import SimpleInvoice
4 |
5 | def imaker(fName, id, duedate, clientId, clientName, clientMobileNumber, prods, discountNo):
6 |
7 | #fname: filename
8 | #id: invoice id, type: str or int or unicode
9 | #duedate: invoice duedate: str or int or unicode
10 | #clientId: passed in client_info. type: str or int or unicode
11 | #clientName: type is str ot unicode
12 | #clientMobileNumber. type: int or str or unicode
13 | #prods is a list which makes the item table
14 | #prods -> name, description price, quantity
15 | #discountNo: passes into the function which sets the discount rate. type: int
16 |
17 |
18 | doc = SimpleInvoice(fName)
19 |
20 | # Paid stamp, optional
21 | doc.is_paid = False
22 |
23 | doc.invoice_info = InvoiceInfo(id, datetime.now(), duedate) # Invoice info, optional
24 |
25 | # Service Provider Info, optional
26 | doc.service_provider_info = ServiceProviderInfo(
27 | name='Salman Wholeseller',
28 | mobileNumber= '03362510211'
29 |
30 |
31 | )
32 |
33 | # Client info, optional
34 | doc.client_info = ClientInfo(
35 | client_id = clientId,
36 | name = clientName,
37 | mobileNumber = clientMobileNumber,
38 |
39 |
40 | )
41 |
42 | # Add Item
43 | for x in prods:
44 | doc.add_item(Item(x[0], x[1], x[2], x[3]))
45 |
46 |
47 | # Tax rate, optional
48 |
49 | doc.set_item_discount_rate(discountNo) # 20%
50 |
51 |
52 | doc.finish()
53 | #test run
54 | #imaker('sabih5.pdf','12356', '12-13-1997', '1234', 'john Doe', '03312097073', [['toothpick', 'tooth desc', 1.1, 3] ,['brush', 'brush desc', 2.2, 3] ,['brush', 'brush desc', 2.2, 3] ,['brush', 'brush desc', 2.2, 3] ,['brush', 'brush desc', 2.2, 3] ,['brush', 'brush desc', 2.2, 3] ,['brush', 'brush desc', 2.2, 3] ,['brush', 'brush desc', 2.2, 3] ,['brush', 'brush desc', 2.2, 3] ,['brush', 'brush desc', 2.2, 3] ,['brush', 'brush desc', 2.2, 3] ,['brush', 'brush desc', 2.2, 3] ,['brush', 'brush desc', 2.2, 3] ,['brush', 'brush desc', 2.2, 3] ,['brush', 'brush desc', 2.2, 3] ,['brush', 'brush desc', 2.2, 3] ,['brush', 'brush desc', 2.2, 3] ,['brush', 'brush desc', 2.2, 3] ,['brush', 'brush desc', 2.2, 3] ,['brush', 'brush desc', 2.2, 3] ,['brush', 'brush desc', 2.2, 3] ,['brush', 'brush desc', 2.2, 3] ,['brush', 'brush desc', 2.2, 3] ,['brush', 'brush desc', 2.2, 3]], 20)
55 |
--------------------------------------------------------------------------------
/invoicePanel.py:
--------------------------------------------------------------------------------
1 |
2 | from terminalFrontEnd import terminalPanel
3 | import newCust as nc
4 |
5 | class invoiceSalePanel (terminalPanel):
6 | def __init__ (self, parent, transactionButtonName):
7 | terminalPanel.__init__(self, parent, transactionButtonName)
8 | #self.returnButton.Hide()
9 |
10 | def CheckOutFunc( self, event ):
11 | amt = self.makePopUp("Enter Recieved Amount", "Amount Recieved")
12 | self.clearCartGrid()
13 | self.t.prepareInvoice(amt)
14 |
15 | def refundFunc( self, event ):
16 | self.clearCartGrid()
17 | self.t.returnProducts()
18 |
--------------------------------------------------------------------------------
/journal.py:
--------------------------------------------------------------------------------
1 |
2 | import wx
3 | import wx.xrc
4 | import wx.grid
5 | import wx.adv
6 | import re
7 |
8 | import manualJournalEntryPanel as mjep
9 | from connectToDb import connectToDB
10 | conn = connectToDB()
11 |
12 | class journalPanel ( wx.Panel ):
13 |
14 | def __init__( self, parent ):
15 |
16 | wx.Panel.__init__ ( self, parent, wx.ID_ANY, wx.DefaultPosition, wx.DefaultSize, wx.TAB_TRAVERSAL )
17 |
18 | bSizerMain = wx.BoxSizer( wx.VERTICAL )
19 |
20 | bSizerDate = wx.BoxSizer( wx.HORIZONTAL )
21 | bSizerGrid = wx.BoxSizer( wx.HORIZONTAL )
22 |
23 | ########### Date Picker Start
24 | self.m_startDate = wx.adv.DatePickerCtrl(self, size=(60,-1), style = wx.adv.DP_DROPDOWN | wx.adv.DP_SHOWCENTURY | wx.adv.DP_ALLOWNONE)
25 | self.m_endDate = wx.adv.DatePickerCtrl(self, size=(60,-1), style = wx.adv.DP_DROPDOWN | wx.adv.DP_SHOWCENTURY | wx.adv.DP_ALLOWNONE)
26 |
27 | self.m_manEntryB = wx.Button( self, wx.ID_ANY, u"New Entry", wx.DefaultPosition, wx.DefaultSize, 0 )
28 | self.m_manEntryB.Bind(wx.EVT_BUTTON, self.manEntry)
29 | ########### Date Picker End
30 |
31 | bSizerDate.Add (self.m_startDate, 1, wx.ALL|wx.EXPAND, 5 )
32 | bSizerDate.Add (self.m_endDate, 1, wx.ALL|wx.EXPAND, 5 )
33 | bSizerDate.Add (self.m_manEntryB, 1, wx.ALL|wx.EXPAND, 5 )
34 |
35 | ########### Cart Grid Start
36 | self.m_journalGrid = wx.grid.Grid( self, wx.ID_ANY, wx.DefaultPosition, wx.Size( -1,-1 ), 0 )
37 | self.m_journalGrid.CreateGrid( 500, 9 )
38 | self.m_journalGrid.EnableEditing( True )
39 | self.m_journalGrid.EnableGridLines( True )
40 | self.m_journalGrid.EnableDragGridSize( False )
41 | self.m_journalGrid.SetMargins( 0, 0 )
42 | self.m_journalGrid.SetRowLabelSize( 1 )
43 | #self.m_journalGrid.AutoSizeColLabelSize( True )
44 |
45 | '''
46 | self.m_journalGrid.SetColSize( 0, 20 )
47 | self.m_journalGrid.SetColSize( 1, 40 )
48 | self.m_journalGrid.SetColSize( 2, 60 )
49 | self.m_journalGrid.SetColSize( 3, 80 )
50 | self.m_journalGrid.SetColSize( 4, 90 )
51 | self.m_journalGrid.SetColSize( 5, 110 )
52 | self.m_journalGrid.SetColSize( 6, 130 )
53 | self.m_journalGrid.SetColSize( 7, 150 )
54 | self.m_journalGrid.SetColSize( 8, 170 )
55 | '''
56 |
57 | self.m_journalGrid.SetColSize( 0, 30 )
58 | self.m_journalGrid.SetColSize( 1, 60 )
59 | self.m_journalGrid.SetColSize( 2, 90 )
60 | self.m_journalGrid.SetColSize( 3, 120 )
61 | self.m_journalGrid.SetColSize( 4, 150 )
62 | self.m_journalGrid.SetColSize( 5, 180 )
63 | self.m_journalGrid.SetColSize( 6, 210 )
64 | self.m_journalGrid.SetColSize( 7, 240 )
65 | self.m_journalGrid.SetColSize( 8, 270 )
66 |
67 | self.m_journalGrid.SetColLabelValue( 0, u"ID" )
68 | self.m_journalGrid.SetColLabelValue( 1, u"Date" )
69 | self.m_journalGrid.SetColLabelValue( 2, u"Time" )
70 | self.m_journalGrid.SetColLabelValue( 3, u"Head of A/C" )
71 | self.m_journalGrid.SetColLabelValue( 4, u"Folio Number" )
72 | self.m_journalGrid.SetColLabelValue( 5, u"Transaction ID" )
73 | self.m_journalGrid.SetColLabelValue( 6, u"Cheque Number" )
74 | self.m_journalGrid.SetColLabelValue( 7, u"Debit" )
75 | self.m_journalGrid.SetColLabelValue( 8, u"Credit" )
76 |
77 | self.m_journalGrid.SetColLabelAlignment( wx.ALIGN_CENTRE, wx.ALIGN_CENTRE )
78 | self.m_journalGrid.SetRowLabelAlignment( wx.ALIGN_CENTRE, wx.ALIGN_CENTRE )
79 |
80 | self.populateTable()
81 | ########### Cart Grid End
82 |
83 | bSizerGrid.Add (self.m_journalGrid, 1, wx.ALL|wx.EXPAND, 5 )
84 |
85 | bSizerMain.Add( bSizerDate, 1, wx.ALL|wx.EXPAND, 5 )
86 | bSizerMain.Add( bSizerGrid, 1, wx.ALL|wx.EXPAND, 5 )
87 |
88 | self.SetSizer( bSizerMain )
89 | self.Layout()
90 | bSizerMain.Fit( self )
91 |
92 | self.m_startDate.Bind(wx.adv.EVT_DATE_CHANGED, self.dateChangeHandler)
93 | self.m_endDate.Bind(wx.adv.EVT_DATE_CHANGED, self.dateChangeHandler)
94 | self.m_journalGrid.Bind(wx.grid.EVT_GRID_CELL_CHANGED, self.journalChange)
95 |
96 | def journalChange (self, event):
97 | r = event.GetRow()
98 |
99 | qry = 'UPDATE `generalLedger` SET dateTime = "%s", headOfAc = "%s", transactionType = "%s", chequeNo = "%s", Debit = "%s", Credit = "%s" WHERE id = %s' % (self.m_journalGrid.GetCellValue(r, 1) + " " + self.m_journalGrid.GetCellValue(r, 2), self.m_journalGrid.GetCellValue(r, 4), self.m_journalGrid.GetCellValue(r, 5), self.m_journalGrid.GetCellValue(r, 6), self.m_journalGrid.GetCellValue(r, 7), self.m_journalGrid.GetCellValue(r, 8), self.m_journalGrid.GetCellValue(r, 0))
100 | print(qry)
101 | curs = conn.cursor()
102 | curs.execute(qry)
103 | conn.commit()
104 |
105 | #self.reloadJournal()
106 |
107 | def manEntry (self, event):
108 | dlg = mjep.GetData(self)
109 | dlg.ShowModal()
110 |
111 | self.reloadJournal()
112 |
113 | def dateChangeHandler (self, event):
114 | self.reloadJournal()
115 |
116 | def reloadJournal (self):
117 | self.m_journalGrid.DeleteRows(numRows=self.m_journalGrid.GetNumberRows())
118 | self.m_journalGrid.InsertRows(numRows=500)
119 |
120 | self.populateTable()
121 |
122 | def populateTable (self):
123 | #print(type(self.m_startDate.GetValue()))
124 | #print(type(self.m_endDate.GetValue().Format("%F")))
125 | qry = 'SELECT gl.id, gl.dateTime, hoa.description, gl.headOfAc, gl.transactionType, gl.chequeNo, gl.Debit, gl.Credit FROM generalLedger gl, headOfAccounts hoa where gl.headOfAc = hoa.id and gl.dateTime BETWEEN "%s" AND "%s" ORDER BY gl.dateTime LIMIT 500' % ( self.m_startDate.GetValue().Format("%F") + " 00:00:00", self.m_endDate.GetValue().Format("%F") + " 23:59:59")
126 | curs = conn.cursor()
127 | curs.execute(qry)
128 |
129 | row = 0
130 | while (1):
131 | r = curs.fetchone()
132 | if (r is not None):
133 | x = re.search ("(?<=Customer)[0-9]*", r['description'])
134 | if x is not None:
135 | q = 'SELECT name FROM customer WHERE id = %s' % (x.group(0))
136 | c = conn.cursor()
137 | c.execute(q)
138 | cust = c.fetchone()
139 | r['description'] = cust['name'] + " A/C Recievable"
140 |
141 | x = re.search ("(?<=Supplier)[0-9]*", r['description'])
142 | if x is not None:
143 | q = 'SELECT name FROM supplier WHERE id = %s' % (x.group(0))
144 | c = conn.cursor()
145 | c.execute(q)
146 | cust = c.fetchone()
147 | r['description'] = cust['name'] + " A/C Payable"
148 |
149 | self.m_journalGrid.SetCellValue(row, 0, str(r['id']))
150 | self.m_journalGrid.SetCellValue(row, 1, str(r['dateTime'])[:10])
151 | self.m_journalGrid.SetCellValue(row, 2, str(r['dateTime'])[11:])
152 |
153 | if (r['Credit'] > 0):
154 | self.m_journalGrid.SetCellValue(row, 3, " "+r['description'])
155 | self.m_journalGrid.SetCellValue(row, 8, str(r['Credit']))
156 | else:
157 | self.m_journalGrid.SetCellValue(row, 3, r['description'])
158 | self.m_journalGrid.SetCellValue(row, 7, str(r['Debit']))
159 | self.m_journalGrid.SetCellValue(row, 4, str(r['headOfAc']))
160 | self.m_journalGrid.SetCellValue(row, 5, r['transactionType'])
161 | if (r['chequeNo'] is not None):
162 | self.m_journalGrid.SetCellValue(row, 6, r['chequeNo'])
163 | #self.m_journalGrid.SetCellValue(row, 7, str(r['Debit']))
164 | #self.m_journalGrid.SetCellValue(row, 8, str(r['Credit']))
165 |
166 | row = row+1
167 | else:
168 | break
169 |
--------------------------------------------------------------------------------
/mainInterface.py:
--------------------------------------------------------------------------------
1 |
2 | import wx
3 | import wx.xrc
4 |
5 | from salesPanel import cashSalePanel
6 | from invoicePanel import invoiceSalePanel
7 | from quotationPanel import quotationPanel
8 | from purchasePanel import purchasePanel
9 | from stockLevelsPanel import stockLevelsPanel
10 | from saleInfoPanel import saleInfoPanel
11 | from invoiceInfoPanel import invoiceInfoPanel
12 | from purchaseInfoPanel import purchaseInfoPanel
13 | from customerInfoPanel import customerInfoPanel
14 | from supplierInfoPanel import supplierInfoPanel
15 | from quoteInfoPanel import quoteInfoPanel
16 | from journal import journalPanel
17 | from accountsByFolio import folioAccountsPanel
18 | from controlAccountPanel import controlAccountPanel
19 | from incomeStatementPanel import incomeStatementPanel
20 |
21 | class mainInterface ( wx.Frame ):
22 |
23 | def __init__( self, parent ):
24 | wx.Frame.__init__ ( self, parent, id = wx.ID_ANY, title = u"POS and ERP", pos = wx.DefaultPosition, size = wx.Size( 676,460 ), style = wx.DEFAULT_FRAME_STYLE|wx.MAXIMIZE|wx.TAB_TRAVERSAL )
25 |
26 | self.SetSizeHints( wx.DefaultSize, wx.DefaultSize )
27 |
28 | bSizer1 = wx.BoxSizer( wx.VERTICAL )
29 |
30 | self.m_notebook1 = wx.Notebook( self, wx.ID_ANY, wx.DefaultPosition, wx.DefaultSize, 0 )
31 |
32 | self.m_salesPanel = cashSalePanel( self.m_notebook1, "Cash Sale" )
33 | self.m_notebook1.AddPage( self.m_salesPanel, u"Sales", True )
34 |
35 | self.m_invoicePanel = invoiceSalePanel( self.m_notebook1, "Print Invoice" )
36 | self.m_notebook1.AddPage( self.m_invoicePanel, u"Invoice", False )
37 |
38 | self.m_quotePanel = quotationPanel( self.m_notebook1, "Print Quotation" )
39 | self.m_notebook1.AddPage( self.m_quotePanel, u"Quotation", False )
40 |
41 | self.m_purchasePanel = purchasePanel( self.m_notebook1, "Purchase" )
42 | self.m_notebook1.AddPage( self.m_purchasePanel, u"GPN", False )
43 |
44 | self.m_stockLevelsPanel = stockLevelsPanel( self.m_notebook1 )
45 | self.m_notebook1.AddPage( self.m_stockLevelsPanel, u"Stock Levels", False )
46 |
47 | self.m_salesInfoPanel = saleInfoPanel(self.m_notebook1)
48 | self.m_notebook1.AddPage( self.m_salesInfoPanel, u"Sale Info", False )
49 |
50 | self.m_invoiceInfoPanel = invoiceInfoPanel(self.m_notebook1)
51 | self.m_notebook1.AddPage( self.m_invoiceInfoPanel, u"Invoice Info", False )
52 |
53 | self.m_purchaseInfoPanel = purchaseInfoPanel(self.m_notebook1)
54 | self.m_notebook1.AddPage( self.m_purchaseInfoPanel, u"GPN Info", False )
55 |
56 | self.m_quoteInfoPanel = quoteInfoPanel(self.m_notebook1)
57 | self.m_notebook1.AddPage( self.m_quoteInfoPanel, u"Quotation Info", False )
58 |
59 | self.m_customerInfoPanel = customerInfoPanel(self.m_notebook1)
60 | self.m_notebook1.AddPage( self.m_customerInfoPanel, u"Customer Info", False )
61 |
62 | self.m_supplierInfoPanel = supplierInfoPanel(self.m_notebook1)
63 | self.m_notebook1.AddPage( self.m_supplierInfoPanel, u"Supplier Info", False )
64 |
65 | self.m_journalPanel = journalPanel(self.m_notebook1)
66 | self.m_notebook1.AddPage( self.m_journalPanel, u"Journal", False )
67 |
68 | self.m_folioAccountsPanel = folioAccountsPanel(self.m_notebook1)
69 | self.m_notebook1.AddPage( self.m_folioAccountsPanel, u"Accounts", False )
70 |
71 | self.m_controlAccountPanel = controlAccountPanel(self.m_notebook1)
72 | self.m_notebook1.AddPage( self.m_controlAccountPanel, u"Control Account", False )
73 |
74 | self.m_incomeStatementPanel = incomeStatementPanel(self.m_notebook1)
75 | self.m_notebook1.AddPage( self.m_incomeStatementPanel, u"Income Statement", False )
76 |
77 |
78 | bSizer1.Add( self.m_notebook1, 1, wx.EXPAND |wx.ALL, 5 )
79 |
80 | self.SetSizer( bSizer1 )
81 | self.Layout()
82 |
83 | self.Centre( wx.BOTH )
84 |
85 | self.m_notebook1.Bind( wx.EVT_NOTEBOOK_PAGE_CHANGED, self.refreshStockLevels)
86 |
87 | def __del__( self ):
88 | pass
89 | def refreshStockLevels (self, event):
90 | self.m_stockLevelsPanel.updateStocks()
91 | self.m_invoiceInfoPanel.updateInvoices()
92 | self.m_purchaseInfoPanel.updatePurchases()
93 | self.m_customerInfoPanel.updateCustomers()
94 | self.m_supplierInfoPanel.updateSuppliers()
95 | self.m_quoteInfoPanel.updateQuotes()
96 | self.m_journalPanel.reloadJournal()
97 | self.m_folioAccountsPanel.reloadJournal()
98 | self.m_controlAccountPanel.reloadJournal()
99 |
100 | def main():
101 | app = wx.App()
102 | mainInterface(None).Show()
103 |
104 | app.MainLoop()
105 |
106 | main()
107 |
--------------------------------------------------------------------------------
/manualJournalEntryPanel.py:
--------------------------------------------------------------------------------
1 | from connectToDb import connectToDB
2 |
3 | conn = connectToDB()
4 |
5 | import wx
6 | import wx.xrc
7 |
8 | import gLedgerFunctions as af
9 |
10 | class GetData(wx.Dialog):
11 | def __init__(self, parent):
12 |
13 | wx.Dialog.__init__(self, parent, wx.ID_ANY, "Manual Entry", size= (650,400))
14 | self.panel = wx.Panel(self,wx.ID_ANY)
15 |
16 | self.folios = self.fetchFolios()
17 | self.lblFolio = wx.StaticText(self.panel, label="Folio", pos=(20,70))
18 | #self.m_folioCombo = wx.ComboBox(self, size=wx.DefaultSize, choices= list(self.folios.keys()), pos=(130,70), size=(90,-1))
19 | self.folio = wx.TextCtrl(self.panel, value="", pos=(130,70), size=(90,-1))
20 |
21 | self.lblTransaction = wx.StaticText(self.panel, label="Transaction Type", pos=(20,120))
22 | self.transaction = wx.TextCtrl(self.panel, value="", pos=(130,120), size=(90,-1))
23 |
24 | self.lblChequeNo = wx.StaticText(self.panel, label="Cheque Number", pos=(20,170))
25 | self.chequeNo = wx.TextCtrl(self.panel, value="", pos=(130,170), size=(90,-1))
26 |
27 | self.lblDebit = wx.StaticText(self.panel, label="Debit", pos=(20,220))
28 | self.debit = wx.TextCtrl(self.panel, value="", pos=(130,220), size=(90,-1))
29 |
30 | self.lblCredit = wx.StaticText(self.panel, label="Credit", pos=(20,270))
31 | self.credit = wx.TextCtrl(self.panel, value="", pos=(130,270), size=(90,-1))
32 |
33 | self.saveButton =wx.Button(self.panel, label="Save", pos=(110,320))
34 | self.closeButton =wx.Button(self.panel, label="Cancel", pos=(250,320))
35 | self.returnButton =wx.Button(self.panel, label="Return", pos=(390,320))
36 |
37 | self.saveButton.Bind(wx.EVT_BUTTON, self.SaveConnString)
38 | self.closeButton.Bind(wx.EVT_BUTTON, self.OnQuit)
39 | self.returnButton.Bind(wx.EVT_BUTTON, self.OnReturn)
40 |
41 | self.Bind(wx.EVT_CLOSE, self.OnQuit)
42 |
43 | self.Show()
44 |
45 | def fetchFolios (self):
46 | qry = 'SELECT id, description FROM headOfAccounts'
47 | curs = conn.cursor()
48 | curs.execute(qry)
49 | r = curs.fetchall()
50 |
51 | folios = {}
52 | for x in r:
53 | folios.update({x['description'] : x['id']})
54 | return folios
55 |
56 | def OnReturn (self, event):
57 | f.returnPurchase(self.iid)
58 | self.Destroy()
59 |
60 | def OnQuit(self, event):
61 | self.result_name = None
62 | self.Destroy()
63 |
64 | def SaveConnString(self, event):
65 | #hoa = self.m_folioCombo.GetValue()
66 | hoa = self.folio.GetValue()
67 | tran = self.transaction.GetValue()
68 | cheque = self.chequeNo.GetValue()
69 | debit = self.debit.GetValue()
70 | credit = self.credit.GetValue()
71 |
72 | if ( hoa != "" and (debit != "" or credit != "") ):
73 | af.manualEntry (hoa, tran, cheque, debit, credit)
74 |
75 | self.Destroy()
76 |
77 |
--------------------------------------------------------------------------------
/newCust.py:
--------------------------------------------------------------------------------
1 | from connectToDb import connectToDB
2 |
3 | conn = connectToDB()
4 |
5 | import wx
6 | import wx.xrc
7 |
8 | class GetData(wx.Dialog):
9 | def __init__(self, parent, terminalObj):
10 | self.t = terminalObj
11 |
12 | wx.Dialog.__init__(self, parent, wx.ID_ANY, "Name Input", size= (650,260))
13 | self.panel = wx.Panel(self,wx.ID_ANY)
14 |
15 | self.lblName = wx.StaticText(self.panel, label="Name", pos=(20,20))
16 | self.name = wx.TextCtrl(self.panel, value="", pos=(110,20), size=(500,-1))
17 |
18 | self.lblPhone = wx.StaticText(self.panel, label="Phone", pos=(20,60))
19 | self.phone = wx.TextCtrl(self.panel, value="", pos=(110,60), size=(500,-1))
20 |
21 | self.lblAdd = wx.StaticText(self.panel, label="Address", pos=(20,100))
22 | self.address = wx.TextCtrl(self.panel, value="", pos=(110,100), size=(500,-1))
23 |
24 | self.lblPrevB = wx.StaticText(self.panel, label="Previous Balance\n(if any)", pos=(20,140))
25 | self.previousBal = wx.TextCtrl(self.panel, value="", pos=(110,140), size=(500,-1))
26 |
27 | self.saveButton =wx.Button(self.panel, label="Save", pos=(110,200))
28 | self.closeButton =wx.Button(self.panel, label="Cancel", pos=(250,200))
29 |
30 | self.saveButton.Bind(wx.EVT_BUTTON, self.SaveConnString)
31 | self.closeButton.Bind(wx.EVT_BUTTON, self.OnQuit)
32 |
33 | self.Bind(wx.EVT_CLOSE, self.OnQuit)
34 | self.phone.Bind(wx.EVT_TEXT, self.findInfo)
35 |
36 | self.phone.SetFocus()
37 |
38 | self.Show()
39 |
40 | def findInfo (self, event):
41 | if self.t.fetchCustomerId(self.phone.GetValue()):
42 | self.name.SetValue(self.t.customerName)
43 | self.name.SetEditable(False)
44 | self.saveButton.Disable()
45 | #self.customerContact.SetLabel(self.t.customerContact)
46 | else:
47 | self.name.SetValue("")
48 | self.name.SetEditable(True)
49 | self.saveButton.Enable()
50 | self.t.customerId = 0
51 |
52 | def OnQuit(self, event):
53 | self.result_name = None
54 | self.Destroy()
55 |
56 | def SaveConnString(self, event):
57 | name = self.name.GetValue()
58 | phone = self.phone.GetValue()
59 | add = self.address.GetValue()
60 | bal = self.previousBal.GetValue()
61 |
62 | if bal == "":
63 | bal = 0
64 |
65 | qry = "INSERT INTO `customer` (name, contact, address, balance) VALUES ('%s', '%s', '%s', '%s')" % (name, phone, add, bal)
66 | conn.cursor().execute(qry)
67 |
68 | qry = "INSERT INTO `headOfAccounts` (description, computation) VALUES ('Customer%s-R', '1')" % (conn.insert_id())
69 | conn.cursor().execute(qry)
70 | conn.commit()
71 |
72 | self.Destroy()
73 |
74 |
--------------------------------------------------------------------------------
/newProd.py:
--------------------------------------------------------------------------------
1 | from connectToDb import connectToDB
2 |
3 | conn = connectToDB()
4 |
5 | import wx
6 | import wx.xrc
7 |
8 | class GetData(wx.Dialog):
9 | def __init__(self, parent, bc):
10 | wx.Dialog.__init__(self, parent, wx.ID_ANY, "New Product", size= (650,320))
11 | self.panel = wx.Panel(self,wx.ID_ANY)
12 |
13 | self.lblName = wx.StaticText(self.panel, label="Name", pos=(20,20))
14 | self.name = wx.TextCtrl(self.panel, value="", pos=(110,20), size=(500,-1))
15 |
16 | self.lblBarcode = wx.StaticText(self.panel, label="Barcode", pos=(20,60))
17 | self.barcode = wx.TextCtrl(self.panel, value="", pos=(110,60), size=(500,-1))
18 | self.barcode.SetValue(str(bc))
19 |
20 | self.lblCP = wx.StaticText(self.panel, label="Cost Price", pos=(20,100))
21 | self.costPrice = wx.TextCtrl(self.panel, value="", pos=(110,100), size=(500,-1))
22 |
23 | self.lblSP = wx.StaticText(self.panel, label="Selling Price", pos=(20,140))
24 | self.sellingPrice = wx.TextCtrl(self.panel, value="", pos=(110,140), size=(500,-1))
25 |
26 | self.lblQty = wx.StaticText(self.panel, label="Quantity", pos=(20,180))
27 | self.qty = wx.TextCtrl(self.panel, value="", pos=(110,180), size=(500,-1))
28 |
29 | self.lblmlvl = wx.StaticText(self.panel, label="Minimum Level", pos=(20,220))
30 | self.minLvl = wx.TextCtrl(self.panel, value="", pos=(110,220), size=(500,-1))
31 |
32 |
33 | self.saveButton =wx.Button(self.panel, label="Save", pos=(110,260))
34 | self.closeButton =wx.Button(self.panel, label="Cancel", pos=(250,260))
35 |
36 | self.saveButton.Bind(wx.EVT_BUTTON, self.SaveConnString)
37 | self.closeButton.Bind(wx.EVT_BUTTON, self.OnQuit)
38 |
39 | self.Bind(wx.EVT_CLOSE, self.OnQuit)
40 |
41 | self.Show()
42 |
43 | def OnQuit(self, event):
44 | self.result_name = None
45 | self.Destroy()
46 |
47 | def SaveConnString(self, event):
48 | name = self.name.GetValue()
49 | bc = self.barcode.GetValue()
50 | cp = self.costPrice.GetValue()
51 | sp = self.sellingPrice.GetValue()
52 | qty = self.qty.GetValue()
53 | minLvl = self.minLvl.GetValue()
54 |
55 | qry = "INSERT INTO `products` (name, type, costPrice, sellingPrice, minLevel, barcode) VALUES ('%s', '3', '%s', '%s', '%s', '%s')" % (name, cp, sp, minLvl, bc)
56 |
57 | conn.cursor().execute(qry)
58 |
59 | i = conn.insert_id()
60 |
61 | qry = "INSERT INTO `currentinventory` (productId, quantity) VALUES ('%s', '%s')" % (i, qty)
62 |
63 | conn.cursor().execute(qry)
64 |
65 | conn.commit()
66 |
67 | self.Destroy()
68 |
69 |
--------------------------------------------------------------------------------
/printer.py:
--------------------------------------------------------------------------------
1 | from escpos.printer import Usb
2 |
3 | import usb.core
4 | import usb.util
5 |
6 | '''
7 | def connectToPrinter():
8 | return Usb(0x0416, 0x5011, in_ep=81, out_ep=3)
9 | '''
10 | p = Usb(0x0416, 0x5011, in_ep=81, out_ep=3)
11 | def printReciept(cart, date, invoiceId):
12 | #p = connectToPrinter()
13 |
14 | p.set(align='center', bold=True, double_height=True, double_width=True)
15 | p.textln('Salman Wholeseller')
16 |
17 | p.set(align='center', bold=True, double_height=False, double_width=False)
18 | p.textln('Chhadi Lane, Karachi')
19 | p.textln('Phone: 0336 2510211')
20 | #p.textln('-------------------------------------------')
21 | p.textln('===============================================')
22 | p.ln(1)
23 | p.textln('Invoice ID: '+str(invoiceId)+' Date: '+ str(date))
24 | p.ln(2)
25 |
26 | p.set(align='center', bold=True, double_height=False, double_width=False)
27 |
28 | # width of paper -> 48 chars
29 | # Product
30 | p.textln("ID |Product |Qty |Price |Total Price ")
31 | p.textln("------------------------------------------------")
32 |
33 | for x in range(len(cart['pid'])):
34 | p.textln(prepareLine(cart['pid'][x], cart['name'][x], cart['qty'][x], cart['price'][x], cart['totalPrice'][x]))
35 | #p.textln(prepareLine(4, 'Brush', 10, 200, 10000))
36 |
37 | '''
38 | p.textln("2 | Toothpick | 50 | 20 | 1000 ")
39 | p.textln("578 | Battery | 10 | 100 | 1000 ")
40 | p.textln("89 | Brush | 5 | 40 | 200 ")
41 | '''
42 |
43 | p.textln("------------------------------------------------")
44 | p.textln(" Total: "+ str(sum(cart['totalPrice'])))
45 |
46 | p.ln(9)
47 |
48 | p.textln("------------------------------------------------")
49 | p.textln(" Notes ")
50 |
51 | p.ln(2)
52 |
53 | p.set(align='center', bold=False, double_height=False, double_width=False)
54 | p.textln("Ganyani, Kirmani and Allahwala IT Consulting")
55 |
56 | #p.image("logo.gif")
57 | #p.barcode('3422323', 'EAN13', 64, 2, '', '')
58 |
59 | p.cut(mode='PART')
60 |
61 | def prepareLine (pid, name, qty, price, tPrice):
62 | ln = ''
63 | pid = str(pid)
64 | ln = ln + preparePhrase(pid, 4)
65 | ln = ln + preparePhrase(name, 14)
66 | ln = ln + preparePhrase(qty, 5)
67 | ln = ln + preparePhrase(price, 9)
68 | ln = ln + preparePhrase(tPrice, 11)
69 |
70 | return ln
71 |
72 | def preparePhrase (itm, l):
73 | itm = str(itm)
74 | return itm + ' '*(l-len(itm)) + '|'
75 |
76 | #p = connectToPrinter()
77 | #printReciept(p)
78 |
--------------------------------------------------------------------------------
/purchaseInfoPanel.py:
--------------------------------------------------------------------------------
1 | # 26th May, 2018 5:05pm
2 |
3 | import wx
4 | import wx.grid
5 | import wx.xrc
6 | import wx.dataview
7 |
8 | from connectToDb import connectToDB
9 | import updatePurchaseMoney as upm
10 |
11 | class purchaseInfoPanel ( wx.Panel ):
12 |
13 | def __init__( self, parent ):
14 | wx.Panel.__init__( self, parent, wx.ID_ANY, wx.DefaultPosition, wx.DefaultSize, wx.TAB_TRAVERSAL )
15 |
16 | bSizer11 = wx.BoxSizer( wx.VERTICAL )
17 |
18 | self.m_purchaseGrid = wx.grid.Grid( self, wx.ID_ANY, wx.DefaultPosition, wx.Size( -1,700 ), 0 )
19 |
20 | p = self.populateTable()
21 | lenP = len(p)
22 |
23 | # Grid
24 | self.m_purchaseGrid.CreateGrid( lenP, 9 )
25 | self.m_purchaseGrid.EnableEditing( False )
26 | self.m_purchaseGrid.EnableGridLines( True )
27 | self.m_purchaseGrid.EnableDragGridSize( False )
28 | self.m_purchaseGrid.SetMargins( 0, 0 )
29 |
30 | # Populate Table
31 | col=0
32 | for x in p:
33 | row=0
34 | # if amount of invoice is smaller than the amount recieved yet, colour the cell red
35 | if float(x['totalBill']) > float(x['amountPaid']):
36 | self.m_purchaseGrid.SetCellBackgroundColour(row, 4, wx.Colour(255, 128, 128))
37 | for y in list(x.values()):
38 | self.m_purchaseGrid.SetCellValue(col, row, str(y))
39 | row = row+1
40 | col = col+1
41 |
42 | # Columns
43 | self.m_purchaseGrid.SetColSize( 0, 30 )
44 | self.m_purchaseGrid.SetColSize( 1, 100 )
45 | self.m_purchaseGrid.SetColSize( 2, 120 )
46 | self.m_purchaseGrid.SetColSize( 3, 140 )
47 | self.m_purchaseGrid.SetColSize( 4, 160 )
48 | self.m_purchaseGrid.SetColSize( 5, 210 )
49 | self.m_purchaseGrid.SetColSize( 6, 230 )
50 | self.m_purchaseGrid.SetColSize( 7, 250 )
51 | self.m_purchaseGrid.SetColSize( 8, 270 )
52 | #self.m_purchaseGrid.AutoSizeColumns()
53 | self.m_purchaseGrid.EnableDragColMove( True )
54 | self.m_purchaseGrid.EnableDragColSize( True )
55 | self.m_purchaseGrid.SetColLabelSize( 30 )
56 | self.m_purchaseGrid.SetColLabelValue( 0, u"ID" )
57 | self.m_purchaseGrid.SetColLabelValue( 1, u"Date Time" )
58 | self.m_purchaseGrid.SetColLabelValue( 2, u"Amount" )
59 | self.m_purchaseGrid.SetColLabelValue( 3, u"Amount Paid" )
60 | self.m_purchaseGrid.SetColLabelValue( 4, u"Supplier ID" )
61 | self.m_purchaseGrid.SetColLabelValue( 5, u"Supplier Name" )
62 | self.m_purchaseGrid.SetColLabelValue( 6, u"Supplier Contact" )
63 | self.m_purchaseGrid.SetColLabelValue( 7, u"Supplier Address" )
64 | self.m_purchaseGrid.SetColLabelValue( 8, u"Supplier IBAN" )
65 | self.m_purchaseGrid.SetColLabelAlignment( wx.ALIGN_CENTRE, wx.ALIGN_CENTRE )
66 |
67 | # Rows
68 | self.m_purchaseGrid.EnableDragRowSize( False )
69 | self.m_purchaseGrid.SetRowLabelSize( 1 )
70 | self.m_purchaseGrid.SetRowLabelAlignment( wx.ALIGN_CENTRE, wx.ALIGN_CENTRE )
71 |
72 | # Label Appearance
73 |
74 | # Cell Defaults
75 | self.m_purchaseGrid.SetDefaultCellAlignment( wx.ALIGN_CENTRE, wx.ALIGN_TOP )
76 | bSizer11.Add( self.m_purchaseGrid, 0, wx.ALIGN_CENTRE|wx.ALL, 5 )
77 |
78 | self.SetSizer( bSizer11 )
79 | self.Layout()
80 | bSizer11.Fit( self )
81 |
82 | self.m_purchaseGrid.Bind( wx.grid.EVT_GRID_CELL_LEFT_CLICK, self.updateCollectedMoney )
83 |
84 | def populateTable (self):
85 | qry = 'SELECT p.id, p.dateTime, p.totalBill, p.amountPaid, s.id, s.name, s.contact, s.iban FROM purchase p, supplier s where s.id=p.supplier ORDER BY p.id'
86 |
87 | con = connectToDB()
88 | curs = con.cursor()
89 | curs.execute(qry)
90 |
91 | inv = []
92 |
93 | while (1):
94 | r = curs.fetchone()
95 | if (r is not None):
96 | inv.append(r)
97 | else:
98 | return inv
99 |
100 | def updatePurchases (self):
101 | self.m_purchaseGrid.DeleteRows(numRows=self.m_purchaseGrid.GetNumberRows())
102 |
103 | p = self.populateTable()
104 | lenP = len(p)
105 |
106 | self.m_purchaseGrid.InsertRows(numRows=lenP)
107 |
108 | # Populate Table
109 | col=0
110 | for x in p:
111 | row=0
112 | x = list(x.values())
113 | if x[3] > x[4]:
114 | self.m_purchaseGrid.SetCellBackgroundColour(row, 4, wx.Colour(255, 128, 128))
115 | for y in x:
116 | self.m_purchaseGrid.SetCellValue(col, row, str(y))
117 | row = row+1
118 | col = col+1
119 |
120 | def updateCollectedMoney (self, event):
121 | iid = self.m_purchaseGrid.GetCellValue(event.GetRow(), 0)
122 | sid = self.m_purchaseGrid.GetCellValue(event.GetRow(), 4)
123 | dlg = upm.GetData(self, iid, sid)
124 | dlg.ShowModal()
125 | self.updatePurchases()
126 |
--------------------------------------------------------------------------------
/purchasePanel.py:
--------------------------------------------------------------------------------
1 |
2 | from terminalFrontEnd import terminalPanel
3 | import newCust as nc
4 |
5 | class purchasePanel (terminalPanel):
6 | def __init__ (self, parent, transactionButtonName):
7 | terminalPanel.__init__(self, parent, transactionButtonName)
8 | #self.returnButton.Hide()
9 |
10 | def identifyParty (self, inS):
11 | if self.t.fetchSupplierId(inS):
12 | self.customerName.SetLabel(self.t.supplierName)
13 | self.customerContact.SetLabel(self.t.supplierContact)
14 | else:
15 | dlg = nc.GetData(parent = self.m_papa)
16 | dlg.ShowModal()
17 |
18 | def CheckOutFunc( self, event ):
19 | amtPaid = self.makePopUpDate("Enter Amount Paid", "Amount Paid")
20 | self.clearCartGrid()
21 | self.t.purchaseItems(amtPaid)
22 | '''
23 | def refundFunc( self, event ):
24 | self.clearCartGrid()
25 | self.t.returnPurchase()
26 | self.m_balanceST.SetFocus()
27 | '''
28 |
--------------------------------------------------------------------------------
/quotationPanel.py:
--------------------------------------------------------------------------------
1 |
2 | from terminalFrontEnd import terminalPanel
3 | import newCust as nc
4 |
5 | class quotationPanel (terminalPanel):
6 | def __init__ (self, parent, transactionButtonName):
7 | terminalPanel.__init__(self, parent, transactionButtonName)
8 | self.returnButton.Hide()
9 |
10 | def CheckOutFunc( self, event ):
11 | expDate = self.makePopUpDate("Enter Expiry Date", "Expiry Date")
12 | self.clearCartGrid()
13 | self.t.saveQuote(expDate)
14 |
15 | def refundFunc( self, event ):
16 | self.clearCartGrid()
17 | self.t.returnProducts()
18 |
--------------------------------------------------------------------------------
/quoteInfoPanel.py:
--------------------------------------------------------------------------------
1 | # 26th May, 2018 5:05pm
2 |
3 | import wx
4 | import wx.grid
5 | import wx.xrc
6 | import wx.dataview
7 |
8 | from connectToDb import connectToDB
9 | import convertQuotation as cq
10 |
11 | class quoteInfoPanel ( wx.Panel ):
12 |
13 | def __init__( self, parent ):
14 | wx.Panel.__init__( self, parent, wx.ID_ANY, wx.DefaultPosition, wx.DefaultSize, wx.TAB_TRAVERSAL )
15 |
16 | bSizer11 = wx.BoxSizer( wx.VERTICAL )
17 |
18 | self.m_quoteInfoGrid = wx.grid.Grid( self, wx.ID_ANY, wx.DefaultPosition, wx.Size( -1,700 ), 0 )
19 |
20 | p = self.populateTable()
21 | lenP = len(p)
22 |
23 | # Grid
24 | self.m_quoteInfoGrid.CreateGrid( lenP, 10 )
25 | self.m_quoteInfoGrid.EnableEditing( False )
26 | self.m_quoteInfoGrid.EnableGridLines( True )
27 | self.m_quoteInfoGrid.EnableDragGridSize( False )
28 | self.m_quoteInfoGrid.SetMargins( 0, 0 )
29 |
30 | # Populate Table
31 | col=0
32 | for x in p:
33 | row=0
34 | # if amount of invoice is smaller than the amount recieved yet, colour the cell red
35 | #if float(x['amount']) > float(x['amountRecieved']):
36 | # self.m_quoteInfoGrid.SetCellTextColour(row, 4, wx.Colour(255, 128, 128))
37 | for y in list(x.values()):
38 | self.m_quoteInfoGrid.SetCellValue(col, row, str(y))
39 | row = row+1
40 | col = col+1
41 |
42 | # Columns
43 | self.m_quoteInfoGrid.SetColSize( 0, 30 )
44 | self.m_quoteInfoGrid.SetColSize( 1, 100 )
45 | self.m_quoteInfoGrid.SetColSize( 2, 120 )
46 | self.m_quoteInfoGrid.SetColSize( 3, 140 )
47 | self.m_quoteInfoGrid.SetColSize( 4, 160 )
48 | self.m_quoteInfoGrid.SetColSize( 5, 180 )
49 | self.m_quoteInfoGrid.SetColSize( 6, 200 )
50 | self.m_quoteInfoGrid.SetColSize( 7, 220 )
51 | self.m_quoteInfoGrid.SetColSize( 8, 240 )
52 | self.m_quoteInfoGrid.SetColSize( 9, 300 )
53 | #self.m_quoteInfoGrid.AutoSizeColumns()
54 | self.m_quoteInfoGrid.EnableDragColMove( True )
55 | self.m_quoteInfoGrid.EnableDragColSize( True )
56 | self.m_quoteInfoGrid.SetColLabelSize( 30 )
57 | self.m_quoteInfoGrid.SetColLabelValue( 0, u"ID" )
58 | self.m_quoteInfoGrid.SetColLabelValue( 1, u"Date" )
59 | self.m_quoteInfoGrid.SetColLabelValue( 2, u"Time" )
60 | self.m_quoteInfoGrid.SetColLabelValue( 3, u"Amount" )
61 | self.m_quoteInfoGrid.SetColLabelValue( 4, u"Expiry Date" )
62 | self.m_quoteInfoGrid.SetColLabelValue( 5, u"Converted" )
63 | self.m_quoteInfoGrid.SetColLabelValue( 6, u"Customer Name" )
64 | self.m_quoteInfoGrid.SetColLabelValue( 7, u"Customer Contact" )
65 | self.m_quoteInfoGrid.SetColLabelValue( 8, u"Customer Address" )
66 | self.m_quoteInfoGrid.SetColLabelValue( 9, u"Customer Balance" )
67 | self.m_quoteInfoGrid.SetColLabelAlignment( wx.ALIGN_CENTRE, wx.ALIGN_CENTRE )
68 |
69 | # Rows
70 | self.m_quoteInfoGrid.EnableDragRowSize( False )
71 | self.m_quoteInfoGrid.SetRowLabelSize( 1 )
72 | self.m_quoteInfoGrid.SetRowLabelAlignment( wx.ALIGN_CENTRE, wx.ALIGN_CENTRE )
73 |
74 | # Label Appearance
75 |
76 | # Cell Defaults
77 | self.m_quoteInfoGrid.SetDefaultCellAlignment( wx.ALIGN_CENTRE, wx.ALIGN_TOP )
78 | bSizer11.Add( self.m_quoteInfoGrid, 0, wx.ALIGN_CENTRE|wx.ALL, 5 )
79 |
80 | self.SetSizer( bSizer11 )
81 | self.Layout()
82 | bSizer11.Fit( self )
83 |
84 | self.m_quoteInfoGrid.Bind( wx.grid.EVT_GRID_CELL_LEFT_CLICK, self.updateCollectedMoney )
85 |
86 | def populateTable (self):
87 | qry = 'SELECT q.id, SUBSTRING(q.dateTime, 1, 11), SUBSTRING(q.dateTime, 12), q.totalBill, q.expiryDate, q.converted, c.name, c.contact, c.address, c.balance from quotations q, customer c WHERE q.customer=c.id'
88 |
89 | con = connectToDB()
90 | curs = con.cursor()
91 | curs.execute(qry)
92 |
93 | inv = []
94 |
95 | while (1):
96 | r = curs.fetchone()
97 | if (r is not None):
98 | inv.append(r)
99 | else:
100 | return inv
101 |
102 | def updateQuotes (self):
103 | self.m_quoteInfoGrid.DeleteRows(numRows=self.m_quoteInfoGrid.GetNumberRows())
104 |
105 | p = self.populateTable()
106 | lenP = len(p)
107 |
108 | self.m_quoteInfoGrid.InsertRows(numRows=lenP)
109 |
110 | # Populate Table
111 | col=0
112 | for x in p:
113 | row=0
114 | x = list(x.values())
115 | #if float(x[3]) > float(x[4]):
116 | #print((x, row))
117 | #self.m_quoteInfoGrid.SetCellBackgroundColour(x[0], 4, wx.Colour(255, 128, 128))
118 | for y in x:
119 | self.m_quoteInfoGrid.SetCellValue(col, row, str(y))
120 | row = row+1
121 | col = col+1
122 |
123 | def updateCollectedMoney (self, event):
124 | qid = self.m_quoteInfoGrid.GetCellValue(event.GetRow(), 0)
125 | dlg = cq.GetData(self, qid)
126 | dlg.ShowModal()
127 | self.updateQuotes()
128 |
--------------------------------------------------------------------------------
/requirements.txt:
--------------------------------------------------------------------------------
1 | Open-Source-Python-POS-and-Accounting-Software
2 | wxPython==4.0.2a1.dev3699+c55bce4
3 | PyMySQL==0.8.0
4 | PyInvoice==0.1.0
5 |
--------------------------------------------------------------------------------
/saleInfoPanel.py:
--------------------------------------------------------------------------------
1 | # 26th May, 2018 5:05pm
2 |
3 | import wx
4 | import wx.grid
5 | import wx.xrc
6 | import wx.dataview
7 |
8 | from connectToDb import connectToDB
9 |
10 | class saleInfoPanel ( wx.Panel ):
11 |
12 | def __init__( self, parent ):
13 | wx.Panel.__init__( self, parent, wx.ID_ANY, wx.DefaultPosition, wx.DefaultSize, wx.TAB_TRAVERSAL )
14 |
15 | bSizer11 = wx.BoxSizer( wx.VERTICAL )
16 |
17 | self.m_invoiceGrid = wx.grid.Grid( self, wx.ID_ANY, wx.DefaultPosition, wx.Size( -1,-1 ), 0 )
18 |
19 | p = self.populateTable()
20 | lenP = len(p)
21 |
22 | # Grid
23 | self.m_invoiceGrid.CreateGrid( lenP, 8 )
24 | self.m_invoiceGrid.EnableEditing( False )
25 | self.m_invoiceGrid.EnableGridLines( True )
26 | self.m_invoiceGrid.EnableDragGridSize( False )
27 | self.m_invoiceGrid.SetMargins( 0, 0 )
28 |
29 | # Populate Table
30 | col=0
31 | for x in p:
32 | row=0
33 | for y in list(x.values()):
34 | self.m_invoiceGrid.SetCellValue(col, row, str(y))
35 | row = row+1
36 | col = col+1
37 |
38 | # Columns
39 | self.m_invoiceGrid.SetColSize( 0, 30 )
40 | self.m_invoiceGrid.SetColSize( 1, 60 )
41 | self.m_invoiceGrid.SetColSize( 2, 90 )
42 | #self.m_invoiceGrid.AutoSizeColumns()
43 | self.m_invoiceGrid.EnableDragColMove( True )
44 | self.m_invoiceGrid.EnableDragColSize( True )
45 | self.m_invoiceGrid.SetColLabelSize( 30 )
46 | self.m_invoiceGrid.SetColLabelValue( 0, u"ID" )
47 | self.m_invoiceGrid.SetColLabelValue( 1, u"Date Time" )
48 | self.m_invoiceGrid.SetColLabelValue( 2, u"Amount" )
49 | self.m_invoiceGrid.SetColLabelValue( 3, u"Employee ID" )
50 | self.m_invoiceGrid.SetColLabelValue( 4, u"Refund" )
51 | self.m_invoiceGrid.SetColLabelValue( 5, u"Customer Name" )
52 | self.m_invoiceGrid.SetColLabelValue( 6, u"Customer Contact" )
53 | self.m_invoiceGrid.SetColLabelValue( 7, u"Customer Address" )
54 | self.m_invoiceGrid.SetColLabelAlignment( wx.ALIGN_CENTRE, wx.ALIGN_CENTRE )
55 |
56 | # Rows
57 | self.m_invoiceGrid.EnableDragRowSize( False )
58 | self.m_invoiceGrid.SetRowLabelSize( 1 )
59 | self.m_invoiceGrid.SetRowLabelAlignment( wx.ALIGN_CENTRE, wx.ALIGN_CENTRE )
60 |
61 | # Label Appearance
62 |
63 | # Cell Defaults
64 | self.m_invoiceGrid.SetDefaultCellAlignment( wx.ALIGN_CENTRE, wx.ALIGN_TOP )
65 | bSizer11.Add( self.m_invoiceGrid, 0, wx.ALIGN_CENTRE|wx.ALL, 5 )
66 |
67 | self.SetSizer( bSizer11 )
68 | self.Layout()
69 | bSizer11.Fit( self )
70 |
71 | def populateTable (self):
72 | qry = 'select s.id, s.dateTime, s.totalBill, s.preparedBy, s.refund, c.name, c.contact, c.address from sales s, customer c where s.customer = c.id'
73 |
74 | con = connectToDB()
75 | curs = con.cursor()
76 | curs.execute(qry)
77 |
78 | inv = []
79 |
80 | while (1):
81 | r = curs.fetchone()
82 | if (r is not None):
83 | inv.append(r)
84 | else:
85 | return inv
86 |
87 | def updateStocks (self):
88 | self.m_invoiceGrid.DeleteRows(numRows=self.m_invoiceGrid.GetNumberRows())
89 |
90 | p = self.populateTable()
91 | lenP = len(p)
92 |
93 | self.m_invoiceGrid.InsertRows(numRows=lenP)
94 |
95 | # Populate Table
96 | col=0
97 | for x in p:
98 | row=0
99 | for y in list(x.values()):
100 | self.m_invoiceGrid.SetCellValue(col, row, str(y))
101 | row = row+1
102 | col = col+1
103 |
104 | def refundSale (self, event):
105 | iid = self.m_custInfoGrid.GetCellValue(event.GetRow(), 0)
106 | dlg = uim.GetData(self, iid)
107 | dlg.ShowModal()
108 | self.updateInvoices()
109 |
--------------------------------------------------------------------------------
/salesPanel.py:
--------------------------------------------------------------------------------
1 |
2 | from terminalFrontEnd import terminalPanel
3 | import newCust as nc
4 |
5 | class cashSalePanel (terminalPanel):
6 | def __init__ (self, parent, transactionButtonName):
7 | terminalPanel.__init__(self, parent, transactionButtonName)
8 |
9 | def CheckOutFunc( self, event ):
10 | self.clearCartGrid()
11 | self.t.checkout()
12 | #self.m_balanceST.SetFocus()
13 |
14 | def refundFunc( self, event ):
15 | self.clearCartGrid()
16 | self.t.returnProducts()
17 | #self.m_balanceST.SetFocus()
18 |
--------------------------------------------------------------------------------
/salesPanel2.py:
--------------------------------------------------------------------------------
1 | # -*- coding: utf-8 -*-
2 |
3 | ###########################################################################
4 | ## Python code generated with wxFormBuilder (version Mar 6 2018)
5 | ## http://www.wxformbuilder.org/
6 | ##
7 | ## PLEASE DO *NOT* EDIT THIS FILE!
8 | ###########################################################################
9 |
10 | import wx
11 | import wx.xrc
12 | import wx.grid
13 |
14 | import functions as f
15 | #import bcr as bcr
16 | #import printer as pr
17 | import newCust as nc
18 | import newProd as np
19 |
20 | ###########################################################################
21 | ## Class MyFrame1
22 | ###########################################################################
23 |
24 | class salesPanel ( wx.Panel ):
25 |
26 | def __init__( self, parent ):
27 | # input stream
28 | self.inputStream = ''
29 | self.cartItems = 0
30 | self.custNo = 0
31 |
32 | wx.Panel.__init__ ( self, parent, wx.ID_ANY, wx.DefaultPosition, wx.DefaultSize, wx.TAB_TRAVERSAL )
33 |
34 | self.SetSizeHints( wx.Size( -1,-1 ), wx.DefaultSize )
35 | self.SetForegroundColour( wx.SystemSettings.GetColour( wx.SYS_COLOUR_CAPTIONTEXT ) )
36 |
37 | bSizerMyFrame1 = wx.BoxSizer( wx.VERTICAL )
38 |
39 | self.m_papa = wx.Panel( self, wx.ID_ANY, wx.DefaultPosition, wx.DefaultSize, wx.TAB_TRAVERSAL)
40 |
41 | bSizer231 = wx.BoxSizer( wx.VERTICAL )
42 |
43 | bSizer5 = wx.BoxSizer( wx.VERTICAL )
44 |
45 | bSizer5.SetMinSize( wx.Size( 150,20 ) )
46 | bSizer13 = wx.BoxSizer( wx.HORIZONTAL )
47 |
48 | bSizer13.SetMinSize( wx.Size( 150,5 ) )
49 | bSizer15 = wx.BoxSizer( wx.VERTICAL )
50 |
51 | self.m_customerST = wx.StaticText( self.m_papa, wx.ID_ANY, u"", wx.DefaultPosition, wx.DefaultSize, 0 )
52 | self.m_customerST.Wrap( -1 )
53 | self.m_customerST.SetFont( wx.Font( 24, wx.FONTFAMILY_SWISS, wx.FONTSTYLE_NORMAL, wx.FONTWEIGHT_NORMAL, False, "Arial" ) )
54 | self.m_customerST.SetForegroundColour( wx.SystemSettings.GetColour( wx.SYS_COLOUR_INACTIVECAPTIONTEXT ) )
55 |
56 | bSizer15.Add( self.m_customerST, 0, wx.ALL|wx.EXPAND, 5 )
57 |
58 |
59 | bSizer13.Add( bSizer15, 1, wx.ALL|wx.EXPAND, 5 )
60 |
61 | bSizer16 = wx.BoxSizer( wx.VERTICAL )
62 |
63 | self.m_balanceST = wx.StaticText( self.m_papa, wx.ID_ANY, u"", wx.DefaultPosition, wx.DefaultSize, 0 )
64 | self.m_balanceST.Wrap( -1 )
65 | self.m_balanceST.SetFont( wx.Font( 24, wx.FONTFAMILY_SWISS, wx.FONTSTYLE_NORMAL, wx.FONTWEIGHT_NORMAL, False, "Arial" ) )
66 | self.m_balanceST.SetForegroundColour( wx.SystemSettings.GetColour( wx.SYS_COLOUR_INACTIVECAPTIONTEXT ) )
67 |
68 | bSizer16.Add( self.m_balanceST, 0, wx.ALL|wx.EXPAND, 5 )
69 |
70 |
71 | bSizer13.Add( bSizer16, 1, wx.EXPAND, 5 )
72 |
73 | bSizer17 = wx.BoxSizer( wx.VERTICAL )
74 |
75 | bSizer13.Add( bSizer17, 1, wx.EXPAND, 5 )
76 |
77 |
78 | bSizer5.Add( bSizer13, 0, wx.ALL|wx.EXPAND, 5 )
79 |
80 |
81 | bSizer231.Add( bSizer5, 0, wx.EXPAND, 5 )
82 |
83 | bSizer6 = wx.BoxSizer( wx.HORIZONTAL )
84 |
85 | bSizer301 = wx.BoxSizer( wx.VERTICAL )
86 |
87 | bSizer23 = wx.BoxSizer( wx.VERTICAL )
88 |
89 | ########### Cart Grid Start
90 | self.m_productsGrid = wx.grid.Grid( self, wx.ID_ANY, wx.DefaultPosition, wx.Size( -1,-1 ), 0 )
91 | self.m_productsGrid.CreateGrid( 99, 6 )
92 | self.m_productsGrid.EnableEditing( True )
93 | self.m_productsGrid.EnableGridLines( True )
94 | self.m_productsGrid.EnableDragGridSize( False )
95 | self.m_productsGrid.SetMargins( 0, 0 )
96 | self.m_productsGrid.SetRowLabelSize( 20 )
97 |
98 | self.m_productsGrid.SetColSize( 0, 40 )
99 | self.m_productsGrid.SetColSize( 1, 80 )
100 | self.m_productsGrid.SetColSize( 2, 120 )
101 | self.m_productsGrid.SetColSize( 3, 140 )
102 | self.m_productsGrid.SetColSize( 4, 160 )
103 |
104 | self.m_productsGrid.SetColLabelValue( 0, u"ID" )
105 | self.m_productsGrid.SetColLabelValue( 1, u"Name" )
106 | self.m_productsGrid.SetColLabelValue( 2, u"Quantity" )
107 | self.m_productsGrid.SetColLabelValue( 3, u"Unit Price" )
108 | self.m_productsGrid.SetColLabelValue( 4, u"Total Discount" )
109 | self.m_productsGrid.SetColLabelValue( 5, u"Total Price" )
110 |
111 | self.m_productsGrid.SetColLabelAlignment( wx.ALIGN_CENTRE, wx.ALIGN_CENTRE )
112 | self.m_productsGrid.SetRowLabelAlignment( wx.ALIGN_CENTRE, wx.ALIGN_CENTRE )
113 | ########### Cart Grid End
114 |
115 | bSizer23.Add( self.m_productsGrid, 1, wx.EXPAND|wx.ALL, 5 )
116 |
117 |
118 | bSizer301.Add( bSizer23, 1, wx.ALIGN_BOTTOM|wx.ALL|wx.EXPAND|wx.LEFT|wx.RIGHT|wx.TOP, 5 )
119 |
120 | bSizer32 = wx.BoxSizer( wx.HORIZONTAL )
121 |
122 | bSizer32.SetMinSize( wx.Size( -1,60 ) )
123 | bSizer31 = wx.BoxSizer( wx.VERTICAL )
124 |
125 | bSizer31.SetMinSize( wx.Size( -1,60 ) )
126 | self.m_TotalST = wx.StaticText( self.m_papa, wx.ID_ANY, u"Total", wx.DefaultPosition, wx.Size( -1,60 ), 0 )
127 | self.m_TotalST.Wrap( -1 )
128 | self.m_TotalST.SetFont( wx.Font( 24, wx.FONTFAMILY_SWISS, wx.FONTSTYLE_NORMAL, wx.FONTWEIGHT_NORMAL, False, "Arial" ) )
129 |
130 | bSizer31.Add( self.m_TotalST, 0, wx.ALL|wx.EXPAND, 5 )
131 |
132 |
133 | bSizer32.Add( bSizer31, 1, wx.EXPAND, 5 )
134 |
135 | bSizer33 = wx.BoxSizer( wx.VERTICAL )
136 |
137 | bSizer33.SetMinSize( wx.Size( -1,60 ) )
138 | self.m_TotalAmtST = wx.StaticText( self.m_papa, wx.ID_ANY, u"0", wx.DefaultPosition, wx.Size( -1,60 ), 0 )
139 | self.m_TotalAmtST.Wrap( -1 )
140 | self.m_TotalAmtST.SetFont( wx.Font( 24, wx.FONTFAMILY_SWISS, wx.FONTSTYLE_NORMAL, wx.FONTWEIGHT_NORMAL, False, "Arial" ) )
141 |
142 | bSizer33.Add( self.m_TotalAmtST, 0, wx.ALL|wx.EXPAND, 5 )
143 |
144 |
145 | bSizer32.Add( bSizer33, 1, wx.EXPAND, 5 )
146 |
147 |
148 | bSizer301.Add( bSizer32, 0, wx.ALIGN_BOTTOM|wx.ALL|wx.FIXED_MINSIZE|wx.EXPAND, 5 )
149 |
150 |
151 | bSizer6.Add( bSizer301, 1, wx.EXPAND, 5 )
152 |
153 | bSizer8 = wx.BoxSizer( wx.VERTICAL )
154 |
155 | bSizer9 = wx.BoxSizer( wx.VERTICAL )
156 |
157 | bSizer24 = wx.BoxSizer( wx.VERTICAL )
158 |
159 | bSizer9.Add( bSizer24, 1, wx.ALL|wx.EXPAND|wx.LEFT|wx.RIGHT|wx.TOP, 5 )
160 |
161 |
162 | bSizer8.Add( bSizer9, 0, wx.ALL|wx.EXPAND, 5 )
163 |
164 | bSizer10 = wx.BoxSizer( wx.VERTICAL )
165 |
166 | bSizer12 = wx.BoxSizer( wx.HORIZONTAL )
167 |
168 | bSizer41 = wx.BoxSizer( wx.VERTICAL )
169 |
170 | self.m_checkoutB = wx.Button( self.m_papa, wx.ID_ANY, u"Cash Sale", wx.DefaultPosition, wx.DefaultSize, 0 )
171 | self.m_checkoutB.SetFont( wx.Font( 18, wx.FONTFAMILY_SWISS, wx.FONTSTYLE_NORMAL, wx.FONTWEIGHT_NORMAL, False, "Arial" ) )
172 | self.m_checkoutB.SetForegroundColour( wx.SystemSettings.GetColour( wx.SYS_COLOUR_CAPTIONTEXT ) )
173 |
174 | bSizer41.Add( self.m_checkoutB, 1, wx.ALL|wx.EXPAND, 5 )
175 |
176 |
177 | bSizer12.Add( bSizer41, 1, wx.ALL|wx.EXPAND, 5 )
178 |
179 | bSizer29 = wx.BoxSizer( wx.VERTICAL )
180 |
181 | self.m_pInvoiceB = wx.Button( self.m_papa, wx.ID_ANY, u"Print Invoice", wx.DefaultPosition, wx.DefaultSize, 0 )
182 | self.m_pInvoiceB.SetFont( wx.Font( 18, wx.FONTFAMILY_SWISS, wx.FONTSTYLE_NORMAL, wx.FONTWEIGHT_NORMAL, False, "Arial" ) )
183 |
184 | bSizer29.Add( self.m_pInvoiceB, 1, wx.ALL|wx.EXPAND, 5 )
185 |
186 | bSizer12.Add( bSizer29, 1, wx.ALL|wx.EXPAND, 5 )
187 |
188 | bSizer88 = wx.BoxSizer( wx.VERTICAL )
189 |
190 | self.m_refundB = wx.Button( self.m_papa, wx.ID_ANY, u"Return", wx.DefaultPosition, wx.DefaultSize, 0 )
191 | self.m_refundB.SetFont( wx.Font( 18, wx.FONTFAMILY_SWISS, wx.FONTSTYLE_NORMAL, wx.FONTWEIGHT_NORMAL, False, "Arial" ) )
192 |
193 | bSizer88.Add( self.m_refundB, 1, wx.ALL|wx.EXPAND, 5 )
194 |
195 | bSizerCC = wx.BoxSizer( wx.VERTICAL )
196 |
197 | self.m_cleanCartB = wx.Button( self.m_papa, wx.ID_ANY, u"Clean Cart", wx.DefaultPosition, wx.DefaultSize, 0 )
198 | self.m_cleanCartB.SetFont( wx.Font( 18, wx.FONTFAMILY_SWISS, wx.FONTSTYLE_NORMAL, wx.FONTWEIGHT_NORMAL, False, "Arial" ) )
199 |
200 | bSizerCC.Add( self.m_cleanCartB, 1, wx.ALL|wx.EXPAND, 5 )
201 |
202 | bSizer12.Add( bSizerCC, 1, wx.ALL|wx.EXPAND, 5 )
203 |
204 | bSizer12.Add( bSizer88, 1, wx.ALL|wx.EXPAND, 5 )
205 |
206 | bSizer10.Add( bSizer12, 1, wx.ALL|wx.EXPAND, 5 )
207 |
208 | bSizer30 = wx.BoxSizer( wx.HORIZONTAL )
209 |
210 | bSizer40 = wx.BoxSizer( wx.VERTICAL )
211 |
212 | bSizer40.SetMinSize( wx.Size( -1,200 ) )
213 | self.m_prodSuggest = wx.dataview.DataViewListCtrl( self.m_papa, wx.ID_ANY, wx.DefaultPosition, wx.DefaultSize, 0 )
214 | self.m_prodSuggest.SetMinSize( wx.Size( -1,200 ) )
215 |
216 | self.m_prodSuggest.AppendTextColumn('Name')
217 | self.m_prodSuggest.AppendTextColumn('Price')
218 |
219 | bSizer40.Add( self.m_prodSuggest, 1, wx.ALL|wx.EXPAND, 5 )
220 |
221 |
222 | bSizer30.Add( bSizer40, 1, wx.EXPAND, 5 )
223 |
224 |
225 | bSizer10.Add( bSizer30, 1, wx.ALL|wx.EXPAND, 5 )
226 |
227 |
228 | bSizer8.Add( bSizer10, 1, wx.ALL|wx.EXPAND, 5 )
229 |
230 |
231 | bSizer6.Add( bSizer8, 1, wx.ALL|wx.EXPAND, 5 )
232 |
233 |
234 | bSizer231.Add( bSizer6, 1, wx.EXPAND, 5 )
235 |
236 |
237 | self.m_papa.SetSizer( bSizer231 )
238 | self.m_papa.Layout()
239 | bSizer231.Fit( self.m_papa )
240 | bSizerMyFrame1.Add( self.m_papa, 1, wx.EXPAND |wx.ALL, 5 )
241 |
242 |
243 | self.SetSizer( bSizerMyFrame1 )
244 | self.Layout()
245 |
246 | self.Centre( wx.BOTH )
247 |
248 | # Connect Events
249 | self.m_checkoutB.Bind( wx.EVT_BUTTON, self.CheckOutFunc )
250 | self.m_pInvoiceB.Bind( wx.EVT_BUTTON, self.printInvoice )
251 | self.m_refundB.Bind( wx.EVT_BUTTON, self.refundFunc )
252 | self.m_cleanCartB.Bind( wx.EVT_BUTTON, self.clearCart )
253 | self.m_productsGrid.Bind(wx.grid.EVT_GRID_CELL_CHANGED, self.cartChange)
254 |
255 | # Collect barcode input
256 | self.m_papa.Bind(wx.EVT_CHAR_HOOK, self.barcodeInput)
257 | self.m_papa.SetFocus()
258 |
259 | def __del__( self ):
260 | pass
261 |
262 | def cartChange (self, event):
263 | # this function deals with all types in changes in the cart
264 | r = event.GetRow()
265 | if (event.GetCol() == 2):
266 | # if quantity was changed
267 | x = f.incQty( int(self.m_productsGrid.GetCellValue(r, 0)), int(self.m_productsGrid.GetCellValue(r, 2))-f.cart['qty'][r] )
268 | if x == True:
269 | self.m_productsGrid.SetCellValue(r, 5, str(f.cart['totalPrice'][r]))
270 | self.m_productsGrid.SetCellValue(r, 4, str( (f.cart['origPrice'][r] - f.cart['price'][r]) * f.cart['qty'][r] ))
271 | if type(x) == type(int()):
272 | self.alert("Only "+str(x)+" are available", '')
273 | self.m_productsGrid.SetCellValue(r, 2, event.GetString())
274 |
275 | if (event.GetCol() == 3):
276 | # if unit price was changed
277 | #f.cart['discount'][r] = f.cart['discount'][r] + int( f.cart['price'][r] - int(self.m_productsGrid.GetCellValue(r, 3)) )
278 | f.cart['price'][r] = int(self.m_productsGrid.GetCellValue(r, 3))
279 | f.cart['totalPrice'][r] = f.cart['qty'][r] * f.cart['price'][r]
280 |
281 | self.m_productsGrid.SetCellValue(r, 4, str( (f.cart['origPrice'][r] - f.cart['price'][r]) * f.cart['qty'][r] ))
282 | self.m_productsGrid.SetCellValue(r, 5, str(f.cart['totalPrice'][r]))
283 |
284 | if (event.GetCol() == 4):
285 | # if discount was changed
286 | #f.cart['discount'][r] = int(self.m_productsGrid.GetCellValue(r, 4))
287 | f.cart['price'][r] = f.cart['price'][r] - int(self.m_productsGrid.GetCellValue(r, 4))
288 | f.cart['totalPrice'][r] = f.cart['qty'][r] * f.cart['price'][r]
289 |
290 | self.m_productsGrid.SetCellValue(r, 3, str(f.cart['price'][r]))
291 | self.m_productsGrid.SetCellValue(r, 5, str(f.cart['totalPrice'][r]))
292 |
293 | if (event.GetCol() == 5):
294 | # if total price was changed
295 | f.cart['totalPrice'][r] = int(self.m_productsGrid.GetCellValue(r, 5))
296 | #f.cart['discount'][r] = f.cart['discount'][r] + f.cart['price'][r] - f.cart['totalPrice'][r] / f.cart['qty'][r]
297 | f.cart['price'][r] = f.cart['totalPrice'][r] / f.cart['qty'][r]
298 |
299 | self.m_productsGrid.SetCellValue(r, 4, str( (f.cart['origPrice'][r] - f.cart['price'][r]) * f.cart['qty'][r] ))
300 | self.m_productsGrid.SetCellValue(r, 3, str(f.cart['price'][r]))
301 |
302 | self.m_TotalAmtST.SetLabel(str(f.computeTotalBill()))
303 |
304 |
305 | def refundFunc( self, event ):
306 | try:
307 | f.refundProd(self.custNo)
308 | self.clearEverything()
309 | except ValueError:
310 | self.alert("Cart is Empty", "Alert")
311 | else:
312 | pass
313 | self.m_balanceST.SetFocus()
314 |
315 | def CheckOutFunc( self, event ):
316 | try:
317 | bill=str(f.computeTotalBill())
318 | f.checkout(self.custNo)
319 | self.clearEverything()
320 |
321 | except ValueError:
322 | self.alert("Cart is Empty", "Alert")
323 | else:
324 | pass
325 | self.m_balanceST.SetFocus()
326 |
327 | def printInvoice(self, event):
328 | amt = self.makePopUp("Enter Recieved Amount", "Amount Recieved")
329 | try:
330 | f.prepareInvoice (self.custNo, amt)
331 | self.clearEverything()
332 | except ValueError:
333 | self.alert("Cart is Empty", "Alert")
334 | else:
335 | pass
336 | self.m_balanceST.SetFocus()
337 |
338 | def makePopUp(self, prompt, title):
339 | pp = wx.TextEntryDialog(self, prompt, title)
340 | pp.ShowModal()
341 | r = pp.GetValue()
342 | pp.Destroy()
343 | pp.Show()
344 | return r
345 |
346 | def alert(self, msg, title):
347 | x = wx.MessageDialog(self, msg, title)
348 | x.ShowModal()
349 |
350 | def dumpCartInDvlc (self):
351 | for x in range(self.cartItems):
352 | self.m_productsGrid.SetCellValue(x, 0, str( f.cart['pid'][x] ))
353 | self.m_productsGrid.SetCellValue(x, 1, str( f.cart['name'][x] ))
354 | self.m_productsGrid.SetCellValue(x, 2, str( f.cart['qty'][x] ))
355 | self.m_productsGrid.SetCellValue(x, 3, str( f.cart['price'][x] ))
356 | self.m_productsGrid.SetCellValue(x, 4, str( f.cart['origPrice'][x] - f.cart['price'][x] ))
357 | self.m_productsGrid.SetCellValue(x, 5, str( f.cart['totalPrice'][x] ))
358 | self.m_TotalAmtST.SetLabel(str(f.computeTotalBill()))
359 |
360 | def cleanCart (self):
361 | for x in range(self.cartItems):
362 | self.m_productsGrid.SetCellValue(x, 0, '')
363 | self.m_productsGrid.SetCellValue(x, 1, '')
364 | self.m_productsGrid.SetCellValue(x, 2, '')
365 | self.m_productsGrid.SetCellValue(x, 3, '')
366 | self.m_productsGrid.SetCellValue(x, 4, '')
367 | self.m_productsGrid.SetCellValue(x, 5, '')
368 | self.m_TotalAmtST.SetLabel('0')
369 |
370 | def clearCart (self, event):
371 | self.cleanCart()
372 | f.releaseAllProducts()
373 |
374 | def clearEverything (self):
375 | self.cleanCart()
376 | self.custNo = 0
377 | self.m_customerST.SetLabel('')
378 | self.cartItems = 0
379 |
380 | def newCust(self):
381 | dlg = nc.GetData(parent = self.m_papa)
382 | dlg.ShowModal()
383 |
384 | def newProd(self, bc):
385 | dlg = np.GetData(self.m_papa, bc)
386 | dlg.ShowModal()
387 |
388 | def barcodeInput (self, event):
389 | c = event.GetUnicodeKey()
390 | #print(c)
391 | if c is 8:
392 | #backspace
393 | self.inputStream = self.inputStream[:-1]
394 | if c is 27:
395 | # esc key
396 | self.inputStream = ''
397 | if c in range(48, 91):
398 | # number or alphabet
399 | self.inputStream = self.inputStream + chr(c)
400 | if c is 13:
401 | # enter key
402 | print(self.inputStream)
403 | inS = self.inputStream
404 | self.inputStream = ''
405 |
406 | #checking for custom commands first
407 | print(inS[:5])
408 | if inS[:5] == 'SWINC':
409 | x = f.incQty(f.cart['pid'][-1:][0], int(inS[5:]))
410 | if x == True:
411 | self.dumpCartInDvlc()
412 | if type(x) == type(int()):
413 | self.alert("Only "+str(x)+" are available", '')
414 | return
415 |
416 | if inS[:5] == 'SWDEC':
417 | f.incQty(f.cart['pid'][-1:][0], -int(inS[5:]))
418 | self.dumpCartInDvlc()
419 | return
420 |
421 | if inS == 'SWPRNTRCPT':
422 | self.CheckOutFunc(1)
423 | return
424 |
425 | if inS[:2] == '03' and len(inS) == 11:
426 | customer = f.fetchClientId(inS)
427 | self.m_customerST.SetLabel(customer['name'])
428 | self.custNo = customer['id']
429 | return
430 |
431 | if inS == 'NEWCUST':
432 | self.newCust()
433 | return
434 |
435 | qty = 1
436 | x = f.findBarcode(inS, qty)
437 |
438 | if x == False:
439 | self.alert("Already in the cart", '')
440 |
441 | if x == True:
442 | self.cartItems = self.cartItems+1
443 | self.dumpCartInDvlc()
444 |
445 | if type(x) == type(int()):
446 | self.alert("Only "+str(x)+" are available", '')
447 |
448 | if x is None:
449 | self.newProd(inS)
450 | x = f.findBarcode(inS, qty)
451 | if x == True:
452 | self.cartItems = self.cartItems+1
453 | self.dumpCartInDvlc()
454 | self.m_TotalAmtST.SetLabel(str(f.computeTotalBill()))
455 | if type(x) == type(int()):
456 | self.alert("Only "+str(x)+" are available", '')
457 |
458 | # unfinished business here
459 |
460 |
461 | self.m_balanceST.SetLabel(self.inputStream)
462 |
--------------------------------------------------------------------------------
/salesTerminal(archived).py:
--------------------------------------------------------------------------------
1 | import wx
2 | import wx.xrc
3 | import wx.grid
4 |
5 | class salesPanel ( wx.Panel ):
6 |
7 | def __init__( self, parent ):
8 | # input stream
9 | self.inputStream = ''
10 |
11 | wx.Panel.__init__ ( self, parent, wx.ID_ANY, wx.DefaultPosition, wx.DefaultSize, wx.TAB_TRAVERSAL )
12 |
13 | self.mainSizer = wx.BoxSizer(wx.VERTICAL)
14 |
15 | self.topInfoSizer = wx.BoxSizer (wx.HORIZONTAL)
16 |
17 | self.topInfoSizerLeftSide = wx.BoxSizer (wx.VERTICAL)
18 |
19 | self.customerNoST = wx.StaticText( self, wx.ID_ANY, u"Customer ID: 99999")
20 | self.customerNoST.SetFont( wx.Font( 20, wx.FONTFAMILY_SWISS, wx.FONTSTYLE_NORMAL, wx.FONTWEIGHT_NORMAL, False, "Arial" ) )
21 | self.topInfoSizerLeftSide.Add (self.customerNoST, wx.EXPAND|wx.ALL)
22 |
23 | self.supplierNoST = wx.StaticText( self, wx.ID_ANY, u"Supplier ID: 99999")
24 | self.supplierNoST.SetFont( wx.Font( 20, wx.FONTFAMILY_SWISS, wx.FONTSTYLE_NORMAL, wx.FONTWEIGHT_NORMAL, False, "Arial" ) )
25 | self.topInfoSizerLeftSide.Add (self.supplierNoST, wx.EXPAND|wx.ALL)
26 |
27 | self.operatorNoST = wx.StaticText( self, wx.ID_ANY, u"Operator ID: 99999", wx.DefaultPosition, wx.DefaultSize, 0 )
28 | self.operatorNoST.SetFont( wx.Font( 20, wx.FONTFAMILY_SWISS, wx.FONTSTYLE_NORMAL, wx.FONTWEIGHT_NORMAL, False, "Arial" ) )
29 | self.topInfoSizerLeftSide.Add (self.operatorNoST, wx.EXPAND|wx.ALL)
30 |
31 | self.topInfoSizerRightSide = wx.BoxSizer (wx.VERTICAL)
32 |
33 | self.inputStringST = wx.StaticText( self, wx.ID_ANY, u"Input String")
34 | self.inputStringST.SetFont( wx.Font( 20, wx.FONTFAMILY_SWISS, wx.FONTSTYLE_NORMAL, wx.FONTWEIGHT_NORMAL, False, "Arial" ) )
35 | self.topInfoSizerRightSide.Add (self.inputStringST, wx.EXPAND|wx.ALL|wx.ALIGN_CENTER)
36 |
37 | self.topInfoSizer.Add (self.topInfoSizerLeftSide, wx.EXPAND|wx.ALIGN_LEFT)
38 | self.topInfoSizer.Add (self.topInfoSizerRightSide, wx.EXPAND|wx.ALIGN_RIGHT)
39 |
40 | self.bottomSizer = wx.BoxSizer (wx.HORIZONTAL)
41 |
42 | self.cartSizer = wx.BoxSizer (wx.HORIZONTAL)
43 | ########### Cart Grid Start
44 | self.productsGrid = wx.grid.Grid( self, wx.ID_ANY, wx.DefaultPosition, wx.Size( -1,-1 ), 0 )
45 | self.productsGrid.CreateGrid( 99, 6 )
46 | self.productsGrid.EnableEditing( True )
47 | self.productsGrid.EnableGridLines( True )
48 | self.productsGrid.EnableDragGridSize( False )
49 | self.productsGrid.SetMargins( 0, 0 )
50 | self.productsGrid.SetRowLabelSize( 20 )
51 |
52 | self.productsGrid.SetColSize( 0, 30 )
53 | self.productsGrid.SetColSize( 1, 60 )
54 | self.productsGrid.SetColSize( 2, 90 )
55 | self.productsGrid.SetColSize( 3, 120 )
56 | self.productsGrid.SetColSize( 4, 150 )
57 | self.productsGrid.SetColSize( 5, 180 )
58 |
59 | self.productsGrid.SetColLabelValue( 0, u"ID" )
60 | self.productsGrid.SetColLabelValue( 1, u"Name" )
61 | self.productsGrid.SetColLabelValue( 2, u"Quantity" )
62 | self.productsGrid.SetColLabelValue( 3, u"Unit Price" )
63 | self.productsGrid.SetColLabelValue( 4, u"Total Discount" )
64 | self.productsGrid.SetColLabelValue( 5, u"Total Price" )
65 |
66 | self.productsGrid.SetColLabelAlignment( wx.ALIGN_CENTRE, wx.ALIGN_CENTRE )
67 | self.productsGrid.SetRowLabelAlignment( wx.ALIGN_CENTRE, wx.ALIGN_CENTRE )
68 | ########### Cart Grid End
69 | self.cartSizer.Add (self.productsGrid)
70 |
71 | self.bottomRight = wx.BoxSizer (wx.VERTICAL)
72 |
73 | self.controlsSizer = wx.BoxSizer (wx.HORIZONTAL)
74 |
75 | self.cashSaleB = wx.Button( self, wx.ID_ANY, u"Cash Sale", wx.DefaultPosition, (200,200), 0 )
76 | self.cashSaleB.SetFont( wx.Font( 18, wx.FONTFAMILY_SWISS, wx.FONTSTYLE_NORMAL, wx.FONTWEIGHT_NORMAL, False, "Arial" ) )
77 | self.cashSaleB.SetForegroundColour( wx.SystemSettings.GetColour( wx.SYS_COLOUR_CAPTIONTEXT ) )
78 |
79 | self.controlsSizer.Add (self.cashSaleB, 1, wx.ALL|wx.EXPAND, 5)
80 |
81 | self.returnB = wx.Button( self, wx.ID_ANY, u"Return", wx.DefaultPosition, (200,200), 0 )
82 | self.returnB.SetFont( wx.Font( 18, wx.FONTFAMILY_SWISS, wx.FONTSTYLE_NORMAL, wx.FONTWEIGHT_NORMAL, False, "Arial" ) )
83 | self.returnB.SetForegroundColour( wx.SystemSettings.GetColour( wx.SYS_COLOUR_CAPTIONTEXT ) )
84 |
85 | self.controlsSizer.Add (self.returnB, 1, wx.ALL|wx.EXPAND, 5)
86 |
87 | self.clearB = wx.Button( self, wx.ID_ANY, u"Clear", wx.DefaultPosition, (200,200), 0 )
88 | self.clearB.SetFont( wx.Font( 18, wx.FONTFAMILY_SWISS, wx.FONTSTYLE_NORMAL, wx.FONTWEIGHT_NORMAL, False, "Arial" ) )
89 | self.clearB.SetForegroundColour( wx.SystemSettings.GetColour( wx.SYS_COLOUR_CAPTIONTEXT ) )
90 |
91 | self.controlsSizer.Add (self.clearB, 1, wx.ALL|wx.EXPAND, 5)
92 |
93 | self.bottomRight.Add (self.controlsSizer, wx.EXPAND|wx.ALL|wx.ALIGN_CENTER)
94 |
95 | self.billST = wx.StaticText( self, wx.ID_ANY, u"Bill: 99999")
96 | self.billST.SetFont( wx.Font( 20, wx.FONTFAMILY_SWISS, wx.FONTSTYLE_NORMAL, wx.FONTWEIGHT_NORMAL, False, "Arial" ) )
97 | self.bottomRight.Add (self.billST, wx.EXPAND|wx.ALL)
98 |
99 | self.DiscountTC = wx.TextCtrl( self, wx.ID_ANY, u"0", size=(200, 40))
100 | self.DiscountTC.SetFont( wx.Font( 20, wx.FONTFAMILY_SWISS, wx.FONTSTYLE_NORMAL, wx.FONTWEIGHT_NORMAL, False, "Arial" ) )
101 | self.bottomRight.Add (self.DiscountTC, wx.ALL)
102 |
103 | self.billAfterDiscountST = wx.StaticText( self, wx.ID_ANY, u"Bill After Discount: 99999")
104 | self.billAfterDiscountST.SetFont( wx.Font( 20, wx.FONTFAMILY_SWISS, wx.FONTSTYLE_NORMAL, wx.FONTWEIGHT_NORMAL, False, "Arial" ) )
105 | self.bottomRight.Add (self.billAfterDiscountST, wx.EXPAND|wx.ALL)
106 |
107 | self.bottomSizer.Add (self.cartSizer)
108 | self.bottomSizer.Add (self.bottomRight)
109 |
110 | self.mainSizer.Add (self.topInfoSizer, wx.EXPAND|wx.ALL)
111 | self.mainSizer.Add (self.bottomSizer, wx.EXPAND|wx.ALL)
112 |
113 | self.SetSizer( self.mainSizer )
114 | self.Layout()
115 |
116 | self.Bind(wx.EVT_CHAR_HOOK, self.keyInput)
117 |
118 | def keyInput(self, event):
119 | c = event.GetUnicodeKey()
120 | #print(c)
121 | if c is 8:
122 | #backspace
123 | self.inputStream = self.inputStream[:-1]
124 | if c is 27:
125 | # esc key
126 | self.inputStream = ''
127 | if c in range(48, 91):
128 | # number or alphabet
129 | self.inputStream = self.inputStream + chr(c)
130 | if c is 13:
131 | # enter key
132 | inS = self.inputStream
133 | self.inputStream = ''
134 |
135 | # checking for custom commands first
136 | # change to new supplier
137 | if inS[:2] == '03' and len(inS) == 11:
138 | # fetch or create new customer or supplier
139 | return
140 |
141 | # assume input is a barcode and look for a matching product in the database
142 |
143 |
144 | self.inputStringST.SetLabel(self.inputStream)
145 |
146 |
--------------------------------------------------------------------------------
/stockLevelsPanel.py:
--------------------------------------------------------------------------------
1 | # 26th May, 2018 5:05pm
2 |
3 | import wx
4 | import wx.grid
5 | import wx.xrc
6 | import wx.dataview
7 |
8 | from connectToDb import connectToDB
9 |
10 | class stockLevelsPanel ( wx.Panel ):
11 |
12 | def __init__( self, parent ):
13 | wx.Panel.__init__( self, parent, wx.ID_ANY, wx.DefaultPosition, wx.DefaultSize, wx.TAB_TRAVERSAL )
14 |
15 | bSizer11 = wx.BoxSizer( wx.VERTICAL )
16 |
17 | self.m_productsGrid = wx.grid.Grid( self, wx.ID_ANY, wx.DefaultPosition, wx.Size( -1,-1 ), 0 )
18 |
19 | p = self.populateTable()
20 | lenP = len(p)
21 |
22 | # Grid
23 | self.m_productsGrid.CreateGrid( lenP, 8 )
24 | self.m_productsGrid.EnableEditing( True )
25 | self.m_productsGrid.EnableGridLines( True )
26 | self.m_productsGrid.EnableDragGridSize( False )
27 | self.m_productsGrid.SetMargins( 0, 0 )
28 |
29 | # Populate Table
30 | col=0
31 | for x in p:
32 | row=0
33 | for y in list(x.values()):
34 | self.m_productsGrid.SetCellValue(col, row, str(y))
35 | row = row+1
36 | col = col+1
37 |
38 | # Columns
39 | self.m_productsGrid.SetColSize( 0, 30 )
40 | self.m_productsGrid.SetColSize( 1, 60 )
41 | self.m_productsGrid.SetColSize( 2, 90 )
42 | self.m_productsGrid.SetColSize( 3, 120 )
43 | self.m_productsGrid.SetColSize( 4, 150 )
44 | self.m_productsGrid.SetColSize( 5, 180 )
45 | self.m_productsGrid.SetColSize( 6, 210 )
46 | self.m_productsGrid.SetColSize( 7, 240 )
47 | #self.m_productsGrid.AutoSizeColumns()
48 | self.m_productsGrid.EnableDragColMove( True )
49 | self.m_productsGrid.EnableDragColSize( True )
50 | self.m_productsGrid.SetColLabelSize( 30 )
51 | self.m_productsGrid.SetColLabelValue( 0, u"ID" )
52 | self.m_productsGrid.SetColLabelValue( 1, u"Name" )
53 | self.m_productsGrid.SetColLabelValue( 2, u"Code Name" )
54 | self.m_productsGrid.SetColLabelValue( 3, u"Cost Price" )
55 | self.m_productsGrid.SetColLabelValue( 4, u"Selling Price" )
56 | self.m_productsGrid.SetColLabelValue( 5, u"Minimum Required" )
57 | self.m_productsGrid.SetColLabelValue( 6, u"Current Quantity" )
58 | self.m_productsGrid.SetColLabelValue( 7, u"Barcode" )
59 | self.m_productsGrid.SetColLabelAlignment( wx.ALIGN_CENTRE, wx.ALIGN_CENTRE )
60 |
61 | # Rows
62 | self.m_productsGrid.EnableDragRowSize( False )
63 | self.m_productsGrid.SetRowLabelSize( 1 )
64 | self.m_productsGrid.SetRowLabelAlignment( wx.ALIGN_CENTRE, wx.ALIGN_CENTRE )
65 |
66 | # Label Appearance
67 |
68 | # Cell Defaults
69 | self.m_productsGrid.SetDefaultCellAlignment( wx.ALIGN_CENTRE, wx.ALIGN_TOP )
70 | bSizer11.Add( self.m_productsGrid, 0, wx.ALIGN_CENTRE|wx.ALL, 5 )
71 |
72 | self.m_productsGrid.Bind(wx.grid.EVT_GRID_CELL_CHANGED, self.tableChange)
73 |
74 | self.SetSizer( bSizer11 )
75 | self.Layout()
76 | bSizer11.Fit( self )
77 |
78 | def tableChange (self, event):
79 | r = event.GetRow()
80 |
81 | qry = 'UPDATE products, currentinventory SET products.name = "%s", products.codeName = "%s", products.costPrice = "%s", products.sellingPrice = "%s", products.minLevel = "%s", currentinventory.quantity = "%s", products.barcode = "%s" WHERE products.id = currentinventory.productId AND products.id = "%s"' % (self.m_productsGrid.GetCellValue(r, 1), self.m_productsGrid.GetCellValue(r, 2), self.m_productsGrid.GetCellValue(r, 3), self.m_productsGrid.GetCellValue(r, 4), self.m_productsGrid.GetCellValue(r, 5), self.m_productsGrid.GetCellValue(r, 6), self.m_productsGrid.GetCellValue(r, 7), self.m_productsGrid.GetCellValue(r, 0))
82 | con = connectToDB()
83 | curs = con.cursor()
84 | curs.execute(qry)
85 | con.commit()
86 |
87 | #self.reloadJournal()
88 |
89 | def populateTable (self):
90 | #qry = 'SELECT products.id, products.name, products.codeName, products.costPrice, products.sellingPrice, products.minLevel, currentinventory.quantity, products.barcode FROM `currentinventory`, `producttype`, `products` WHERE (producttype.id = products.type) AND (products.id = currentinventory.productId)'
91 | qry = 'SELECT products.id, products.name, products.codeName, products.costPrice, products.sellingPrice, products.minLevel, currentinventory.quantity, products.barcode FROM `currentinventory`, `products` WHERE products.id = currentinventory.productId'
92 | con = connectToDB()
93 | curs = con.cursor()
94 | curs.execute(qry)
95 |
96 | prods = []
97 |
98 | while (1):
99 | r = curs.fetchone()
100 | if (r is not None):
101 | prods.append(r)
102 | else:
103 | break
104 | return prods
105 |
106 | def updateStocks (self):
107 | self.m_productsGrid.DeleteRows(numRows=self.m_productsGrid.GetNumberRows())
108 |
109 | p = self.populateTable()
110 | lenP = len(p)
111 |
112 | self.m_productsGrid.InsertRows(numRows=lenP)
113 |
114 | # Populate Table
115 | col=0
116 | for x in p:
117 | row=0
118 | for y in list(x.values()):
119 | self.m_productsGrid.SetCellValue(col, row, str(y))
120 | row = row+1
121 | col = col+1
122 |
--------------------------------------------------------------------------------
/supplierInfoPanel.py:
--------------------------------------------------------------------------------
1 | # 26th May, 2018 5:05pm
2 |
3 | import wx
4 | import wx.grid
5 | import wx.xrc
6 | import wx.dataview
7 |
8 | from connectToDb import connectToDB
9 |
10 | class supplierInfoPanel ( wx.Panel ):
11 |
12 | def __init__( self, parent ):
13 | wx.Panel.__init__( self, parent, wx.ID_ANY, wx.DefaultPosition, wx.DefaultSize, wx.TAB_TRAVERSAL )
14 |
15 | bSizer11 = wx.BoxSizer( wx.VERTICAL )
16 |
17 | self.m_custInfoGrid = wx.grid.Grid( self, wx.ID_ANY, wx.DefaultPosition, wx.Size( -1,700 ), 0 )
18 |
19 | p = self.populateTable()
20 | lenP = len(p)
21 |
22 | # Grid
23 | self.m_custInfoGrid.CreateGrid( lenP, 5 )
24 | self.m_custInfoGrid.EnableEditing( False )
25 | self.m_custInfoGrid.EnableGridLines( True )
26 | self.m_custInfoGrid.EnableDragGridSize( False )
27 | self.m_custInfoGrid.SetMargins( 0, 0 )
28 |
29 | # Populate Table
30 | col=0
31 | for x in p:
32 | row=0
33 | # if amount of invoice is smaller than the amount recieved yet, colour the cell red
34 | if float(x['balance']) > 0:
35 | self.m_custInfoGrid.SetCellTextColour(row, 4, wx.Colour(255, 128, 128))
36 | for y in list(x.values()):
37 | self.m_custInfoGrid.SetCellValue(col, row, str(y))
38 | row = row+1
39 | col = col+1
40 |
41 | # Columns
42 | self.m_custInfoGrid.SetColSize( 0, 30 )
43 | self.m_custInfoGrid.SetColSize( 1, 100 )
44 | self.m_custInfoGrid.SetColSize( 2, 120 )
45 | self.m_custInfoGrid.SetColSize( 3, 140 )
46 | #self.m_custInfoGrid.AutoSizeColumns()
47 | self.m_custInfoGrid.EnableDragColMove( True )
48 | self.m_custInfoGrid.EnableDragColSize( True )
49 | self.m_custInfoGrid.SetColLabelSize( 30 )
50 | self.m_custInfoGrid.SetColLabelValue( 0, u"ID" )
51 | self.m_custInfoGrid.SetColLabelValue( 1, u"Name" )
52 | self.m_custInfoGrid.SetColLabelValue( 2, u"Contact" )
53 | self.m_custInfoGrid.SetColLabelValue( 3, u"Address" )
54 | self.m_custInfoGrid.SetColLabelValue( 4, u"Balance" )
55 | self.m_custInfoGrid.SetColLabelAlignment( wx.ALIGN_CENTRE, wx.ALIGN_CENTRE )
56 |
57 | # Rows
58 | self.m_custInfoGrid.EnableDragRowSize( False )
59 | self.m_custInfoGrid.SetRowLabelSize( 1 )
60 | self.m_custInfoGrid.SetRowLabelAlignment( wx.ALIGN_CENTRE, wx.ALIGN_CENTRE )
61 |
62 | # Label Appearance
63 |
64 | # Cell Defaults
65 | self.m_custInfoGrid.SetDefaultCellAlignment( wx.ALIGN_CENTRE, wx.ALIGN_TOP )
66 | bSizer11.Add( self.m_custInfoGrid, 0, wx.ALIGN_CENTRE|wx.ALL, 5 )
67 |
68 | self.SetSizer( bSizer11 )
69 | self.Layout()
70 | bSizer11.Fit( self )
71 |
72 | #self.m_custInfoGrid.Bind( wx.grid.EVT_GRID_CELL_LEFT_CLICK, self.updateCollectedMoney )
73 |
74 | def populateTable (self):
75 | qry = 'select s.id, s.name, s.iban, s.contact, sum(p.totalBill - p.amountPaid) as balance from purchase p, supplier s where p.supplier = s.id group by s.id'
76 |
77 | con = connectToDB()
78 | curs = con.cursor()
79 | curs.execute(qry)
80 |
81 | inv = []
82 |
83 | while (1):
84 | r = curs.fetchone()
85 | if (r is not None):
86 | inv.append(r)
87 | else:
88 | return inv
89 |
90 | def updateSuppliers (self):
91 | self.m_custInfoGrid.DeleteRows(numRows=self.m_custInfoGrid.GetNumberRows())
92 |
93 | p = self.populateTable()
94 | lenP = len(p)
95 |
96 | self.m_custInfoGrid.InsertRows(numRows=lenP)
97 |
98 | # Populate Table
99 | col=0
100 | for x in p:
101 | row=0
102 | x = list(x.values())
103 | if float(x[4]) > 0:
104 | self.m_custInfoGrid.SetCellBackgroundColour(x[0], 4, wx.Colour(255, 128, 128))
105 | for y in x:
106 | self.m_custInfoGrid.SetCellValue(col, row, str(y))
107 | row = row+1
108 | col = col+1
109 |
110 | def updateCollectedMoney (self, event):
111 | iid = self.m_custInfoGrid.GetCellValue(event.GetRow(), 0)
112 | dlg = uim.GetData(self, iid)
113 | dlg.ShowModal()
114 | self.updateInvoices()
115 |
--------------------------------------------------------------------------------
/terminalFrontEnd.py:
--------------------------------------------------------------------------------
1 |
2 | import wx
3 | import wx.xrc
4 | import wx.grid
5 | import wx.adv
6 |
7 | from cart import terminal
8 |
9 | import newProd as np
10 | import newCust as nc
11 | from connectToDb import connectToDB
12 |
13 | class terminalPanel ( wx.Panel ):
14 |
15 | def __init__( self, parent, transactionButtonName ):
16 | # input stream
17 | self.inputStream = ''
18 | self.t = terminal()
19 |
20 | wx.Panel.__init__ ( self, parent, wx.ID_ANY, wx.DefaultPosition, wx.DefaultSize, wx.TAB_TRAVERSAL )
21 |
22 | self.SetSizeHints( wx.Size( -1,-1 ), wx.DefaultSize )
23 | self.SetForegroundColour( wx.SystemSettings.GetColour( wx.SYS_COLOUR_CAPTIONTEXT ) )
24 |
25 | bSizerMyFrame1 = wx.BoxSizer( wx.HORIZONTAL )
26 |
27 | self.papa = wx.Panel( self, wx.ID_ANY, wx.DefaultPosition, wx.DefaultSize, wx.TAB_TRAVERSAL)
28 | self.papa.SetFont( wx.Font( 14, wx.FONTFAMILY_SWISS, wx.FONTSTYLE_NORMAL, wx.FONTWEIGHT_NORMAL, False, "Arial" ) )
29 |
30 | bSizerMain = wx.BoxSizer( wx.VERTICAL )
31 |
32 | ########### Cart Grid Start
33 | self.productsGrid = wx.grid.Grid( self, wx.ID_ANY, wx.DefaultPosition, wx.Size( -1,-1 ), 0 )
34 | self.productsGrid.CreateGrid( 99, 6 )
35 | self.productsGrid.EnableEditing( True )
36 | self.productsGrid.EnableGridLines( True )
37 | self.productsGrid.EnableDragGridSize( False )
38 | self.productsGrid.SetMargins( 0, 0 )
39 | self.productsGrid.SetRowLabelSize( 20 )
40 |
41 | self.productsGrid.SetColSize( 0, 60 )
42 | self.productsGrid.SetColSize( 1, 120 )
43 | self.productsGrid.SetColSize( 2, 180 )
44 | self.productsGrid.SetColSize( 3, 240 )
45 | self.productsGrid.SetColSize( 4, 300 )
46 | self.productsGrid.SetColSize( 5, 360 )
47 |
48 | self.productsGrid.SetColLabelValue( 0, u"ID" )
49 | self.productsGrid.SetColLabelValue( 1, u"Name" )
50 | self.productsGrid.SetColLabelValue( 2, u"Quantity" )
51 | self.productsGrid.SetColLabelValue( 3, u"Unit Price" )
52 | self.productsGrid.SetColLabelValue( 4, u"Total Discount" )
53 | self.productsGrid.SetColLabelValue( 5, u"Total Price" )
54 |
55 | self.productsGrid.SetColLabelAlignment( wx.ALIGN_CENTRE, wx.ALIGN_CENTRE )
56 | self.productsGrid.SetRowLabelAlignment( wx.ALIGN_CENTRE, wx.ALIGN_CENTRE )
57 | ########### Cart Grid End
58 |
59 | self.bSizerPG = wx.BoxSizer( wx.HORIZONTAL )
60 | self.bSizerPG.Add( self.productsGrid, 1, wx.EXPAND|wx.ALL, 5 )
61 |
62 | self.inputTC = wx.SearchCtrl( self.papa, wx.ID_ANY, u"", wx.DefaultPosition, wx.DefaultSize, 0 )
63 | #self.inputTC.SetEditable( False )
64 | self.inputTC.SetDescriptiveText( "Search for Customer or Product" )
65 |
66 | '''
67 | searchSize = self.inputTC.GetSize()
68 | x, y = self.inputTC.GetScreenPosition()
69 | y = searchSize[1] + y
70 | '''
71 | self.suggestionList = wx.ListBox ( self.papa, choices=self.suggestionCandidatesAsList( self.inputTC.GetValue() ), pos=(30, 60), size=(-1, -1) )
72 | self.suggestionList.SetTransparent(wx.IMAGE_ALPHA_OPAQUE)
73 | self.suggestionList.Hide()
74 |
75 | self.customerHeading = wx.StaticText( self.papa, wx.ID_ANY, u"Customer Information", wx.DefaultPosition, wx.DefaultSize, 0 )
76 | self.customerName = wx.StaticText( self.papa, wx.ID_ANY, u"Name: ", wx.DefaultPosition, wx.DefaultSize, 0 )
77 | self.customerContact = wx.StaticText( self.papa, wx.ID_ANY, u"Contact: ", wx.DefaultPosition, wx.DefaultSize, 0 )
78 | #self.customerBalance = wx.StaticText( self.papa, wx.ID_ANY, u"Balance: ", wx.DefaultPosition, wx.DefaultSize, 0 )
79 | self.newCustomerButton = wx.Button( self.papa, wx.ID_ANY, u"Select Customer", wx.DefaultPosition, wx.DefaultSize, 0 )
80 |
81 | self.bSizerTopSecondRowCustInfo = wx.BoxSizer( wx.VERTICAL )
82 | self.bSizerTopSecondRowCustInfo.Add( self.customerHeading, 1, wx.EXPAND|wx.ALL, 5 )
83 | self.bSizerTopSecondRowCustInfo.Add( self.customerName, 1, wx.EXPAND|wx.ALL, 5 )
84 | self.bSizerTopSecondRowCustInfo.Add( self.customerContact, 1, wx.EXPAND|wx.ALL, 5 )
85 | #self.bSizerTopSecondRowCustInfo.Add( self.customerBalance, 1, wx.EXPAND|wx.ALL, 5 )
86 | self.bSizerTopSecondRowCustInfo.Add( self.newCustomerButton, 1, wx.EXPAND|wx.ALL, 5 )
87 |
88 | self.totalBill = wx.StaticText( self.papa, wx.ID_ANY, u"Total: 0000000", wx.DefaultPosition, wx.DefaultSize, 0 )
89 | self.discountTC = wx.StaticText( self.papa, wx.ID_ANY, u"Discount: 0000000", wx.DefaultPosition, wx.DefaultSize, 0 )
90 | self.billAfterDiscount = wx.StaticText( self.papa, wx.ID_ANY, u"After Discount: 0000000", wx.DefaultPosition, wx.DefaultSize, 0 )
91 |
92 | self.totalBill.SetFont( wx.Font( 18, wx.FONTFAMILY_SWISS, wx.FONTSTYLE_NORMAL, wx.FONTWEIGHT_BOLD, False, "Arial" ) )
93 | self.discountTC.SetFont( wx.Font( 18, wx.FONTFAMILY_SWISS, wx.FONTSTYLE_NORMAL, wx.FONTWEIGHT_BOLD, False, "Arial" ) )
94 | self.billAfterDiscount.SetFont( wx.Font( 18, wx.FONTFAMILY_SWISS, wx.FONTSTYLE_NORMAL, wx.FONTWEIGHT_BOLD, False, "Arial" ) )
95 |
96 | self.bSizerTopSecondRowCartInfo = wx.BoxSizer( wx.VERTICAL )
97 | self.bSizerTopSecondRowCartInfo.Add( self.totalBill, 1, wx.EXPAND|wx.ALL|wx.ALIGN_CENTRE_VERTICAL, 5 )
98 | self.bSizerTopSecondRowCartInfo.Add( self.discountTC, 1, wx.EXPAND|wx.ALL, 5 )
99 | self.bSizerTopSecondRowCartInfo.Add( self.billAfterDiscount, 2, wx.ALIGN_CENTRE_VERTICAL, 5 )
100 |
101 | self.transactionButton = wx.Button( self.papa, wx.ID_ANY, transactionButtonName, wx.DefaultPosition, wx.DefaultSize, 0 )
102 | self.returnButton = wx.Button( self.papa, wx.ID_ANY, u"Return", wx.DefaultPosition, wx.DefaultSize, 0 )
103 | self.cleanCartButton = wx.Button( self.papa, wx.ID_ANY, u"Clear", wx.DefaultPosition, wx.DefaultSize, 0 )
104 |
105 | self.transactionButton.SetFont( wx.Font( 18, wx.FONTFAMILY_SWISS, wx.FONTSTYLE_NORMAL, wx.FONTWEIGHT_BOLD, False, "Arial" ) )
106 |
107 | self.bSizerTopSecondRowControls = wx.BoxSizer( wx.VERTICAL )
108 | self.bSizerTopSecondRowControls.Add( self.transactionButton, 3, wx.EXPAND|wx.ALL, 5 )
109 | self.bSizerTopSecondRowControls.Add( self.returnButton, 2, wx.EXPAND|wx.ALL, 5 )
110 | self.bSizerTopSecondRowControls.Add( self.cleanCartButton, 2, wx.EXPAND|wx.ALL, 5 )
111 |
112 | self.bSizerTopSecondRow = wx.BoxSizer( wx.HORIZONTAL )
113 | self.bSizerTopSecondRow.Add ( self.bSizerTopSecondRowCustInfo, 3, wx.EXPAND|wx.ALL, 5 )
114 | self.bSizerTopSecondRow.Add ( self.bSizerTopSecondRowCartInfo, 3, wx.EXPAND|wx.ALL, 5 )
115 | self.bSizerTopSecondRow.Add ( self.bSizerTopSecondRowControls, 4, wx.EXPAND|wx.ALL, 5 )
116 |
117 | self.bSizerTop = wx.BoxSizer( wx.VERTICAL )
118 | self.bSizerTop.Add ( self.inputTC, 1, wx.EXPAND|wx.ALL, 5 )
119 | #self.bSizerTop.Add ( self.suggestionList, 0, wx.EXPAND|wx.ALL, 5 )
120 | self.bSizerTop.Add ( self.bSizerTopSecondRow, 4, wx.EXPAND|wx.ALL, 5 )
121 |
122 | bSizerMain.Add( self.bSizerTop, 4, wx.EXPAND|wx.ALL, 5 )
123 | bSizerMain.Add( self.bSizerPG, 6, wx.EXPAND|wx.ALL, 5 )
124 |
125 | self.papa.SetSizer( bSizerMain )
126 | self.papa.Layout()
127 | bSizerMain.Fit( self.papa )
128 | bSizerMyFrame1.Add( self.papa, 1, wx.EXPAND |wx.ALL, 5 )
129 |
130 | self.SetSizer( bSizerMyFrame1 )
131 | self.Layout()
132 |
133 | self.Centre( wx.BOTH )
134 |
135 | # Connect Events
136 | self.inputTC.Bind( wx.EVT_TEXT, self.search )
137 | self.inputTC.Bind( wx.EVT_SET_FOCUS, self.showSearchSuggestion )
138 | self.inputTC.Bind( wx.EVT_KILL_FOCUS, self.hideSearchSuggestion )
139 |
140 | self.suggestionList.Bind (wx.EVT_SET_FOCUS, self.search )
141 |
142 | self.transactionButton.Bind( wx.EVT_BUTTON, self.CheckOutFunc )
143 | self.returnButton.Bind( wx.EVT_BUTTON, self.refundFunc )
144 | self.cleanCartButton.Bind( wx.EVT_BUTTON, self.clearEverything )
145 |
146 | self.productsGrid.Bind(wx.grid.EVT_GRID_CELL_CHANGED, self.cartChange)
147 |
148 | self.newCustomerButton.Bind ( wx.EVT_BUTTON, self.determineParty )
149 |
150 | # Collect barcode input
151 | #self.papa.Bind( wx.EVT_TEXT, self.barcodeInput )
152 | self.inputTC.Bind(wx.EVT_CHAR_HOOK, self.barcodeInput)
153 | #self.inputTC.SetFocus()
154 |
155 | def __del__( self ):
156 | pass
157 |
158 | def determineParty (self, event):
159 | dlg = nc.GetData(self.papa, self.t)
160 | dlg.ShowModal()
161 |
162 | if (self.t.customerId != 0):
163 | self.customerName.SetLabel("Name: " + self.t.customerName)
164 | self.customerContact.SetLabel("Contact: "+self.t.customerContact)
165 |
166 | def showSearchSuggestion (self, event):
167 | self.suggestionList.Show()
168 | self.Layout()
169 |
170 | def hideSearchSuggestion (self, event):
171 | if (self.suggestionList.HasFocus() == False):
172 | self.suggestionList.Hide()
173 | self.Layout()
174 |
175 | def search (self, event):
176 | self.suggestionList.SetItems( self.suggestionCandidatesAsList( self.inputTC.GetValue() ) )
177 | self.suggestionList.Show()
178 | self.suggestionList.SetSelection(0)
179 | self.Layout()
180 |
181 | def cartChange (self, event):
182 | # this function deals with all types in changes in the cart
183 | r = event.GetRow()
184 | if (event.GetCol() == 2):
185 | # if quantity was changed
186 | x = self.t.increaseQty( int(self.productsGrid.GetCellValue(r, 0)), int(self.productsGrid.GetCellValue(r, 2))-self.t.getCartProducts()[r].qty )
187 | if x == True:
188 | self.productsGrid.SetCellValue(r, 5, str( self.t.getCartProducts()[r].qty * self.t.getCartProducts()[r].price ))
189 | self.productsGrid.SetCellValue(r, 4, str( self.t.getCartProducts()[r].qty * ( self.t.getCartProducts()[r].origPrice - self.t.getCartProducts()[r].price ) ))
190 | if type(x) == type(int()):
191 | self.alert("Only "+str(x)+" are available", '')
192 | self.productsGrid.SetCellValue(r, 2, event.GetString())
193 |
194 | if (event.GetCol() == 3):
195 | # if unit price was changed
196 | self.t.getCartProducts()[r].price = int(self.productsGrid.GetCellValue(r, 3))
197 |
198 | self.productsGrid.SetCellValue(r, 4, str( self.t.getCartProducts()[r].qty * ( self.t.getCartProducts()[r].origPrice - self.t.getCartProducts()[r].price ) ))
199 | self.productsGrid.SetCellValue(r, 5, str( self.t.getCartProducts()[r].qty * self.t.getCartProducts()[r].price ))
200 |
201 | if (event.GetCol() == 4):
202 | # if discount was changed
203 | self.t.getCartProducts()[r].price = self.t.getCartProducts()[r].price - ( int(self.productsGrid.GetCellValue(r, 4)) / self.t.getCartProducts()[r].qty )
204 |
205 | self.productsGrid.SetCellValue(r, 3, str( self.t.getCartProducts()[r].price ))
206 | self.productsGrid.SetCellValue(r, 5, str( self.t.getCartProducts()[r].qty * self.t.getCartProducts()[r].price ))
207 |
208 | if (event.GetCol() == 5):
209 | # if total price was changed
210 | self.t.getCartProducts()[r].price = int(self.productsGrid.GetCellValue(r, 5)) / self.t.getCartProducts()[r].qty
211 |
212 | self.productsGrid.SetCellValue(r, 4, str( (self.t.getCartProducts()[r].origPrice - self.t.getCartProducts()[r].price) * self.t.getCartProducts()[r].qty ))
213 | self.productsGrid.SetCellValue(r, 3, str( self.t.getCartProducts()[r].price ))
214 |
215 | self.totalBill.SetLabel( "Total: " + str( self.t.getCart().computeTotalBill() + self.t.getCart().computeTotalDiscount() ))
216 | self.discountTC.SetLabel( "Discount: " + str( self.t.getCart().computeTotalDiscount() ))
217 | self.billAfterDiscount.SetLabel( "After Discount: " + str( self.t.getCart().computeTotalBill() ))
218 |
219 | def suggestionCandidates (self, searchString):
220 | qry = 'SELECT products.name, products.codeName, products.costPrice, products.sellingPrice, products.barcode FROM `currentinventory`, `products` WHERE products.id = currentinventory.productId AND codeName LIKE "%'+str(searchString)+'%"'
221 | conn = connectToDB()
222 | curs = conn.cursor()
223 | curs.execute(qry)
224 | r = curs.fetchall()
225 | menu = wx.Menu()
226 | for x in r:
227 | help = "Rs. " + str(x['costPrice']) + " Rs. " + str(x['sellingPrice']) + " " + str(x['barcode'])
228 | menu.Append(wx.ID_NEW, x['codeName'], helpString=help)
229 | return menu
230 |
231 | def suggestionCandidatesAsList (self, searchString):
232 | qry = 'SELECT DISTINCT products.name, products.codeName, products.costPrice, products.sellingPrice, products.barcode FROM `currentinventory`, `products` WHERE products.id = currentinventory.productId AND codeName LIKE "%'+str(searchString)+'%" OR BARCODE LIKE "%'+str(searchString)+'%"'
233 | conn = connectToDB()
234 | curs = conn.cursor()
235 | curs.execute(qry)
236 | r = curs.fetchall()
237 | sug = []
238 | for x in r:
239 | prod = x['codeName'] + " - "+x['name']+" Rs. " + str(x['costPrice']) + " Rs. " + str(x['sellingPrice']) + " " + str(x['barcode'])
240 | sug.append(prod)
241 | sug.append("New Product")
242 | return sug
243 |
244 | def fetchAllCodenames (self):
245 | qry = 'SELECT codeName FROM products'
246 | conn = connectToDB()
247 | curs = conn.cursor()
248 | curs.execute(qry)
249 | r = curs.fetchall()
250 | sug = []
251 | for x in r:
252 | sug.append(x['codeName'])
253 | return sug
254 |
255 | def refundFunc( self, event ):
256 | pass
257 |
258 | def CheckOutFunc( self, event ):
259 | pass
260 |
261 | def makePopUp(self, prompt, title):
262 | pp = wx.TextEntryDialog(self, prompt, title)
263 | pp.ShowModal()
264 | r = pp.GetValue()
265 | pp.Destroy()
266 | pp.Show()
267 | return r
268 |
269 | def makePopUpDate(self, prompt, title):
270 | pp = wx.TextEntryDialog(self, prompt, title)
271 | pp.ShowModal()
272 | r = pp.GetValue()
273 | pp.Destroy()
274 | pp.Show()
275 | return r
276 |
277 | def alert(self, msg, title):
278 | x = wx.MessageDialog(self, msg, title)
279 | x.ShowModal()
280 |
281 | def dumpCartInDvlc (self):
282 | for x in range(self.t.numberOfItems()):
283 | self.productsGrid.SetCellValue(x, 0, str( self.t.getCartProducts()[x].pid ))
284 | self.productsGrid.SetCellValue(x, 1, str( self.t.getCartProducts()[x].name ))
285 | self.productsGrid.SetCellValue(x, 2, str( self.t.getCartProducts()[x].qty ))
286 | self.productsGrid.SetCellValue(x, 3, str( self.t.getCartProducts()[x].price ))
287 | self.productsGrid.SetCellValue(x, 4, str( self.t.getCartProducts()[x].origPrice - self.t.getCartProducts()[x].price ))
288 | self.productsGrid.SetCellValue(x, 5, str( self.t.getCartProducts()[x].qty * self.t.getCartProducts()[x].price ))
289 | self.totalBill.SetLabel( "Total: " + str( self.t.getCart().computeTotalBill() + self.t.getCart().computeTotalDiscount() ))
290 | self.discountTC.SetLabel( "Discount: " + str( self.t.getCart().computeTotalDiscount() ))
291 | self.billAfterDiscount.SetLabel( "After Discount: " + str( self.t.getCart().computeTotalBill() ))
292 |
293 | def clearCartGrid (self):
294 | for x in range(self.t.numberOfItems()):
295 | self.productsGrid.SetCellValue(x, 0, '')
296 | self.productsGrid.SetCellValue(x, 1, '')
297 | self.productsGrid.SetCellValue(x, 2, '')
298 | self.productsGrid.SetCellValue(x, 3, '')
299 | self.productsGrid.SetCellValue(x, 4, '')
300 | self.productsGrid.SetCellValue(x, 5, '')
301 |
302 | self.totalBill.SetLabel('Total: 0000000')
303 | self.discountTC.SetLabel( "Discount: 0000000" )
304 | self.billAfterDiscount.SetLabel( "After Discount: 0000000" )
305 |
306 | self.customerName.SetLabel('Name: ')
307 | self.customerContact.SetLabel('Contact: ')
308 | #self.customerBalance.SetLabel('Balance: ')
309 |
310 | def clearEverything (self, event=None):
311 | self.clearCartGrid()
312 | self.t.refresh()
313 |
314 | def newProd(self, bc):
315 | dlg = np.GetData(self.papa, bc)
316 | dlg.ShowModal()
317 |
318 | def identifyParty (self, inS):
319 | if self.t.fetchCustomerId(inS):
320 | self.customerName.SetLabel(self.t.customerName)
321 | self.customerContact.SetLabel(self.t.customerContact)
322 | else:
323 | dlg = nc.GetData(self.papa, inS)
324 | dlg.ShowModal()
325 |
326 | self.t.fetchCustomerId(inS)
327 | self.customerST.SetLabel(self.t.customerName)
328 |
329 | def barcodeInput (self, event):
330 | if event.GetKeyCode() == wx.WXK_UP:
331 | self.suggestionList.SetSelection( self.suggestionList.GetSelection() -1 )
332 | return
333 | elif event.GetKeyCode() == wx.WXK_DOWN:
334 | self.suggestionList.SetSelection( self.suggestionList.GetSelection() +1 )
335 | return
336 | c = event.GetUnicodeKey()
337 | if c is 8:
338 | # backspace
339 | self.inputStream = self.inputStream[:-1]
340 | if c is 27:
341 | # esc key
342 | self.inputStream = ''
343 | if c in range(48, 91):
344 | # number or alphabet
345 | self.inputStream = self.inputStream + chr(c)
346 | if c is 13:
347 | # enter key
348 | listSelection = self.suggestionList.GetString( self.suggestionList.GetSelection() )
349 | print (listSelection)
350 | if listSelection == "New Product":
351 | self.newProd( self.inputTC.GetValue() )
352 | else:
353 | x = self.t.findProduct( listSelection.split()[0] , 1)
354 |
355 | if x == True:
356 | self.dumpCartInDvlc()
357 | self.inputStream = ''
358 | self.hideSearchSuggestion(None)
359 | self.inputTC.SetValue(self.inputStream)
360 |
361 |
362 |
363 | '''
364 | class terminalPanel ( wx.Panel ):
365 |
366 | def __init__( self, parent, transactionButtonName ):
367 | # input stream
368 | self.inputStream = ''
369 | self.t = terminal()
370 |
371 | wx.Panel.__init__ ( self, parent, wx.ID_ANY, wx.DefaultPosition, wx.DefaultSize, wx.TAB_TRAVERSAL )
372 |
373 | self.SetSizeHints( wx.Size( -1,-1 ), wx.DefaultSize )
374 | self.SetForegroundColour( wx.SystemSettings.GetColour( wx.SYS_COLOUR_CAPTIONTEXT ) )
375 |
376 | bSizerMyFrame1 = wx.BoxSizer( wx.VERTICAL )
377 |
378 | self.m_papa = wx.Panel( self, wx.ID_ANY, wx.DefaultPosition, wx.DefaultSize, wx.TAB_TRAVERSAL)
379 |
380 | bSizer231 = wx.BoxSizer( wx.VERTICAL )
381 |
382 | bSizer5 = wx.BoxSizer( wx.VERTICAL )
383 |
384 | bSizer5.SetMinSize( wx.Size( 150,20 ) )
385 | bSizer13 = wx.BoxSizer( wx.HORIZONTAL )
386 |
387 | bSizer13.SetMinSize( wx.Size( 150,5 ) )
388 | bSizer15 = wx.BoxSizer( wx.VERTICAL )
389 |
390 | self.m_customerST = wx.StaticText( self.m_papa, wx.ID_ANY, u"", wx.DefaultPosition, wx.DefaultSize, 0 )
391 | self.m_customerST.Wrap( -1 )
392 | self.m_customerST.SetFont( wx.Font( 24, wx.FONTFAMILY_SWISS, wx.FONTSTYLE_NORMAL, wx.FONTWEIGHT_NORMAL, False, "Arial" ) )
393 | self.m_customerST.SetForegroundColour( wx.SystemSettings.GetColour( wx.SYS_COLOUR_INACTIVECAPTIONTEXT ) )
394 |
395 | bSizer15.Add( self.m_customerST, 0, wx.ALL|wx.EXPAND, 5 )
396 |
397 |
398 | bSizer13.Add( bSizer15, 1, wx.ALL|wx.EXPAND, 5 )
399 |
400 | #------------
401 | bSizerTS = wx.BoxSizer( wx.VERTICAL )
402 |
403 | self.m_searchProd = ACTextControl( self.m_papa, self.suggestionCandidates() )
404 | #self.m_searchProd.Wrap( -1 )
405 | #self.m_searchProd.SetFont( wx.Font( 24, wx.FONTFAMILY_SWISS, wx.FONTSTYLE_NORMAL, wx.FONTWEIGHT_NORMAL, False, "Arial" ) )
406 | #self.m_searchProd.SetForegroundColour( wx.SystemSettings.GetColour( wx.SYS_COLOUR_INACTIVECAPTIONTEXT ) )
407 |
408 | bSizerTS.Add( self.m_searchProd, 0, wx.ALL|wx.EXPAND, 5 )
409 |
410 | bSizer13.Add( bSizerTS, 1, wx.ALL|wx.EXPAND, 5 )
411 | #--------------
412 |
413 | bSizer16 = wx.BoxSizer( wx.VERTICAL )
414 |
415 | self.m_balanceST = wx.StaticText( self.m_papa, wx.ID_ANY, u"", wx.DefaultPosition, wx.DefaultSize, 0 )
416 | self.m_balanceST.Wrap( -1 )
417 | self.m_balanceST.SetFont( wx.Font( 24, wx.FONTFAMILY_SWISS, wx.FONTSTYLE_NORMAL, wx.FONTWEIGHT_NORMAL, False, "Arial" ) )
418 | self.m_balanceST.SetForegroundColour( wx.SystemSettings.GetColour( wx.SYS_COLOUR_INACTIVECAPTIONTEXT ) )
419 |
420 | bSizer16.Add( self.m_balanceST, 0, wx.ALL|wx.EXPAND, 5 )
421 |
422 |
423 | bSizer13.Add( bSizer16, 1, wx.EXPAND, 5 )
424 |
425 | bSizer17 = wx.BoxSizer( wx.VERTICAL )
426 |
427 | bSizer13.Add( bSizer17, 1, wx.EXPAND, 5 )
428 |
429 |
430 | bSizer5.Add( bSizer13, 0, wx.ALL|wx.EXPAND, 5 )
431 |
432 |
433 | bSizer231.Add( bSizer5, 0, wx.EXPAND, 5 )
434 |
435 | bSizer6 = wx.BoxSizer( wx.HORIZONTAL )
436 |
437 | bSizer301 = wx.BoxSizer( wx.VERTICAL )
438 |
439 | bSizer23 = wx.BoxSizer( wx.VERTICAL )
440 |
441 | ########### Cart Grid Start
442 | self.m_productsGrid = wx.grid.Grid( self, wx.ID_ANY, wx.DefaultPosition, wx.Size( -1,-1 ), 0 )
443 | self.m_productsGrid.CreateGrid( 99, 6 )
444 | self.m_productsGrid.EnableEditing( True )
445 | self.m_productsGrid.EnableGridLines( True )
446 | self.m_productsGrid.EnableDragGridSize( False )
447 | self.m_productsGrid.SetMargins( 0, 0 )
448 | self.m_productsGrid.SetRowLabelSize( 20 )
449 |
450 | self.m_productsGrid.SetColSize( 0, 40 )
451 | self.m_productsGrid.SetColSize( 1, 80 )
452 | self.m_productsGrid.SetColSize( 2, 120 )
453 | self.m_productsGrid.SetColSize( 3, 140 )
454 | self.m_productsGrid.SetColSize( 4, 160 )
455 |
456 | self.m_productsGrid.SetColLabelValue( 0, u"ID" )
457 | self.m_productsGrid.SetColLabelValue( 1, u"Name" )
458 | self.m_productsGrid.SetColLabelValue( 2, u"Quantity" )
459 | self.m_productsGrid.SetColLabelValue( 3, u"Unit Price" )
460 | self.m_productsGrid.SetColLabelValue( 4, u"Total Discount" )
461 | self.m_productsGrid.SetColLabelValue( 5, u"Total Price" )
462 |
463 | self.m_productsGrid.SetColLabelAlignment( wx.ALIGN_CENTRE, wx.ALIGN_CENTRE )
464 | self.m_productsGrid.SetRowLabelAlignment( wx.ALIGN_CENTRE, wx.ALIGN_CENTRE )
465 | ########### Cart Grid End
466 |
467 | bSizer23.Add( self.m_productsGrid, 1, wx.EXPAND|wx.ALL, 5 )
468 |
469 |
470 | bSizer301.Add( bSizer23, 1, wx.ALIGN_BOTTOM|wx.ALL|wx.EXPAND|wx.LEFT|wx.RIGHT|wx.TOP, 5 )
471 |
472 | bSizer32 = wx.BoxSizer( wx.HORIZONTAL )
473 |
474 | bSizer32.SetMinSize( wx.Size( -1,60 ) )
475 | bSizer31 = wx.BoxSizer( wx.VERTICAL )
476 |
477 | bSizer31.SetMinSize( wx.Size( -1,60 ) )
478 | self.m_TotalST = wx.StaticText( self.m_papa, wx.ID_ANY, u"Total", wx.DefaultPosition, wx.Size( -1,60 ), 0 )
479 | self.m_TotalST.Wrap( -1 )
480 | self.m_TotalST.SetFont( wx.Font( 24, wx.FONTFAMILY_SWISS, wx.FONTSTYLE_NORMAL, wx.FONTWEIGHT_NORMAL, False, "Arial" ) )
481 |
482 | bSizer31.Add( self.m_TotalST, 0, wx.ALL|wx.EXPAND, 5 )
483 |
484 |
485 | bSizer32.Add( bSizer31, 1, wx.EXPAND, 5 )
486 |
487 | bSizer33 = wx.BoxSizer( wx.VERTICAL )
488 |
489 | bSizer33.SetMinSize( wx.Size( -1,60 ) )
490 | self.m_TotalAmtST = wx.StaticText( self.m_papa, wx.ID_ANY, u"0", wx.DefaultPosition, wx.Size( -1,60 ), 0 )
491 | self.m_TotalAmtST.Wrap( -1 )
492 | self.m_TotalAmtST.SetFont( wx.Font( 24, wx.FONTFAMILY_SWISS, wx.FONTSTYLE_NORMAL, wx.FONTWEIGHT_NORMAL, False, "Arial" ) )
493 |
494 | bSizer33.Add( self.m_TotalAmtST, 0, wx.ALL|wx.EXPAND, 5 )
495 |
496 |
497 | bSizer32.Add( bSizer33, 1, wx.EXPAND, 5 )
498 |
499 |
500 | bSizer301.Add( bSizer32, 0, wx.ALIGN_BOTTOM|wx.ALL|wx.FIXED_MINSIZE|wx.EXPAND, 5 )
501 |
502 |
503 | bSizer6.Add( bSizer301, 1, wx.EXPAND, 5 )
504 |
505 | bSizer8 = wx.BoxSizer( wx.VERTICAL )
506 |
507 | bSizer9 = wx.BoxSizer( wx.VERTICAL )
508 |
509 | bSizer24 = wx.BoxSizer( wx.VERTICAL )
510 |
511 | bSizer9.Add( bSizer24, 1, wx.ALL|wx.EXPAND|wx.LEFT|wx.RIGHT|wx.TOP, 5 )
512 |
513 |
514 | bSizer8.Add( bSizer9, 0, wx.ALL|wx.EXPAND, 5 )
515 |
516 | bSizer10 = wx.BoxSizer( wx.VERTICAL )
517 |
518 | bSizer12 = wx.BoxSizer( wx.HORIZONTAL )
519 |
520 | bSizer41 = wx.BoxSizer( wx.VERTICAL )
521 |
522 | self.m_transactionB = wx.Button( self.m_papa, wx.ID_ANY, transactionButtonName, wx.DefaultPosition, wx.DefaultSize, 0 )
523 | self.m_transactionB.SetFont( wx.Font( 18, wx.FONTFAMILY_SWISS, wx.FONTSTYLE_NORMAL, wx.FONTWEIGHT_NORMAL, False, "Arial" ) )
524 | self.m_transactionB.SetForegroundColour( wx.SystemSettings.GetColour( wx.SYS_COLOUR_CAPTIONTEXT ) )
525 |
526 | bSizer41.Add( self.m_transactionB, 1, wx.ALL|wx.EXPAND, 5 )
527 |
528 |
529 | bSizer12.Add( bSizer41, 1, wx.ALL|wx.EXPAND, 5 )
530 |
531 | bSizer88 = wx.BoxSizer( wx.VERTICAL )
532 |
533 | self.m_returnB = wx.Button( self.m_papa, wx.ID_ANY, u"Return", wx.DefaultPosition, wx.DefaultSize, 0 )
534 | self.m_returnB.SetFont( wx.Font( 18, wx.FONTFAMILY_SWISS, wx.FONTSTYLE_NORMAL, wx.FONTWEIGHT_NORMAL, False, "Arial" ) )
535 |
536 | bSizer88.Add( self.m_returnB, 1, wx.ALL|wx.EXPAND, 5 )
537 |
538 | bSizerCC = wx.BoxSizer( wx.VERTICAL )
539 |
540 | self.m_cleanCartB = wx.Button( self.m_papa, wx.ID_ANY, u"Clear", wx.DefaultPosition, wx.DefaultSize, 0 )
541 | self.m_cleanCartB.SetFont( wx.Font( 18, wx.FONTFAMILY_SWISS, wx.FONTSTYLE_NORMAL, wx.FONTWEIGHT_NORMAL, False, "Arial" ) )
542 |
543 | bSizerCC.Add( self.m_cleanCartB, 1, wx.ALL|wx.EXPAND, 5 )
544 |
545 | bSizer12.Add( bSizerCC, 1, wx.ALL|wx.EXPAND, 5 )
546 |
547 | bSizer12.Add( bSizer88, 1, wx.ALL|wx.EXPAND, 5 )
548 |
549 | bSizer10.Add( bSizer12, 1, wx.ALL|wx.EXPAND, 5 )
550 |
551 | bSizer30 = wx.BoxSizer( wx.HORIZONTAL )
552 |
553 | ''
554 | bSizer40 = wx.BoxSizer( wx.VERTICAL )
555 |
556 | bSizer40.SetMinSize( wx.Size( -1,200 ) )
557 | self.m_prodSuggest = wx.dataview.DataViewListCtrl( self.m_papa, wx.ID_ANY, wx.DefaultPosition, wx.DefaultSize, 0 )
558 | self.m_prodSuggest.SetMinSize( wx.Size( -1,200 ) )
559 |
560 | self.m_prodSuggest.AppendTextColumn('Name')
561 | self.m_prodSuggest.AppendTextColumn('Price')
562 |
563 | bSizer40.Add( self.m_prodSuggest, 1, wx.ALL|wx.EXPAND, 5 )
564 |
565 | bSizer30.Add( bSizer40, 1, wx.EXPAND, 5 )
566 | ''
567 |
568 | bSizer10.Add( bSizer30, 1, wx.ALL|wx.EXPAND, 5 )
569 |
570 |
571 | bSizer8.Add( bSizer10, 1, wx.ALL|wx.EXPAND, 5 )
572 |
573 |
574 | bSizer6.Add( bSizer8, 1, wx.ALL|wx.EXPAND, 5 )
575 |
576 |
577 | bSizer231.Add( bSizer6, 1, wx.EXPAND, 5 )
578 |
579 |
580 | self.m_papa.SetSizer( bSizer231 )
581 | self.m_papa.Layout()
582 | bSizer231.Fit( self.m_papa )
583 | bSizerMyFrame1.Add( self.m_papa, 1, wx.EXPAND |wx.ALL, 5 )
584 |
585 |
586 | self.SetSizer( bSizerMyFrame1 )
587 | self.Layout()
588 |
589 | self.Centre( wx.BOTH )
590 |
591 | # Connect Events
592 | self.m_transactionB.Bind( wx.EVT_BUTTON, self.CheckOutFunc )
593 | self.m_returnB.Bind( wx.EVT_BUTTON, self.refundFunc )
594 | self.m_cleanCartB.Bind( wx.EVT_BUTTON, self.clearEverything )
595 | self.m_productsGrid.Bind(wx.grid.EVT_GRID_CELL_CHANGED, self.cartChange)
596 |
597 | # Collect barcode input
598 | #self.m_papa.Bind(wx.EVT_CHAR_HOOK, self.barcodeInput)
599 | self.m_papa.SetFocus()
600 |
601 | def __del__( self ):
602 | pass
603 |
604 | def cartChange (self, event):
605 | # this function deals with all types in changes in the cart
606 | r = event.GetRow()
607 | if (event.GetCol() == 2):
608 | # if quantity was changed
609 | x = self.t.increaseQty( int(self.m_productsGrid.GetCellValue(r, 0)), int(self.m_productsGrid.GetCellValue(r, 2))-self.t.getCartProducts()[r].qty )
610 | if x == True:
611 | self.m_productsGrid.SetCellValue(r, 5, str( self.t.getCartProducts()[r].qty * self.t.getCartProducts()[r].price ))
612 | self.m_productsGrid.SetCellValue(r, 4, str( self.t.getCartProducts()[r].qty * ( self.t.getCartProducts()[r].origPrice - self.t.getCartProducts()[r].price ) ))
613 | if type(x) == type(int()):
614 | self.alert("Only "+str(x)+" are available", '')
615 | self.m_productsGrid.SetCellValue(r, 2, event.GetString())
616 |
617 | if (event.GetCol() == 3):
618 | # if unit price was changed
619 | self.t.getCartProducts()[r].price = int(self.m_productsGrid.GetCellValue(r, 3))
620 |
621 | self.m_productsGrid.SetCellValue(r, 4, str( self.t.getCartProducts()[r].qty * ( self.t.getCartProducts()[r].origPrice - self.t.getCartProducts()[r].price ) ))
622 | self.m_productsGrid.SetCellValue(r, 5, str( self.t.getCartProducts()[r].qty * self.t.getCartProducts()[r].price ))
623 |
624 | if (event.GetCol() == 4):
625 | # if discount was changed
626 | self.t.getCartProducts()[r].price = self.t.getCartProducts()[r].price - ( int(self.m_productsGrid.GetCellValue(r, 4)) / self.t.getCartProducts()[r].qty )
627 |
628 | self.m_productsGrid.SetCellValue(r, 3, str( self.t.getCartProducts()[r].price ))
629 | self.m_productsGrid.SetCellValue(r, 5, str( self.t.getCartProducts()[r].qty * self.t.getCartProducts()[r].price ))
630 |
631 | if (event.GetCol() == 5):
632 | # if total price was changed
633 | self.t.getCartProducts()[r].price = int(self.m_productsGrid.GetCellValue(r, 5)) / self.t.getCartProducts()[r].qty
634 |
635 | self.m_productsGrid.SetCellValue(r, 4, str( (self.t.getCartProducts()[r].origPrice - self.t.getCartProducts()[r].price) * self.t.getCartProducts()[r].qty ))
636 | self.m_productsGrid.SetCellValue(r, 3, str( self.t.getCartProducts()[r].price ))
637 |
638 | self.m_TotalAmtST.SetLabel(str( self.t.getCart().computeTotalBill() ))
639 |
640 | def suggestionCandidates (self):
641 | qry = 'select codeName from products'
642 | conn = connectToDB()
643 | curs = conn.cursor()
644 | curs.execute(qry)
645 | r = curs.fetchall()
646 | cand = []
647 | for x in r:
648 | cand.append(x['codeName'])
649 | return cand
650 |
651 | def refundFunc( self, event ):
652 | pass
653 |
654 | def CheckOutFunc( self, event ):
655 | pass
656 |
657 | def makePopUp(self, prompt, title):
658 | pp = wx.TextEntryDialog(self, prompt, title)
659 | pp.ShowModal()
660 | r = pp.GetValue()
661 | pp.Destroy()
662 | pp.Show()
663 | return r
664 |
665 | def makePopUpDate(self, prompt, title):
666 | pp = wx.TextEntryDialog(self, prompt, title)
667 | pp.ShowModal()
668 | r = pp.GetValue()
669 | pp.Destroy()
670 | pp.Show()
671 | return r
672 |
673 | def alert(self, msg, title):
674 | x = wx.MessageDialog(self, msg, title)
675 | x.ShowModal()
676 |
677 | def dumpCartInDvlc (self):
678 | for x in range(self.t.numberOfItems()):
679 | self.m_productsGrid.SetCellValue(x, 0, str( self.t.getCartProducts()[x].pid ))
680 | self.m_productsGrid.SetCellValue(x, 1, str( self.t.getCartProducts()[x].name ))
681 | self.m_productsGrid.SetCellValue(x, 2, str( self.t.getCartProducts()[x].qty ))
682 | self.m_productsGrid.SetCellValue(x, 3, str( self.t.getCartProducts()[x].price ))
683 | self.m_productsGrid.SetCellValue(x, 4, str( self.t.getCartProducts()[x].origPrice - self.t.getCartProducts()[x].price ))
684 | self.m_productsGrid.SetCellValue(x, 5, str( self.t.getCartProducts()[x].qty * self.t.getCartProducts()[x].price ))
685 | self.m_TotalAmtST.SetLabel(str( self.t.getCart().computeTotalBill() ))
686 |
687 | def clearCartGrid (self):
688 | for x in range(self.t.numberOfItems()):
689 | self.m_productsGrid.SetCellValue(x, 0, '')
690 | self.m_productsGrid.SetCellValue(x, 1, '')
691 | self.m_productsGrid.SetCellValue(x, 2, '')
692 | self.m_productsGrid.SetCellValue(x, 3, '')
693 | self.m_productsGrid.SetCellValue(x, 4, '')
694 | self.m_productsGrid.SetCellValue(x, 5, '')
695 | self.m_TotalAmtST.SetLabel('0')
696 | self.m_customerST.SetLabel('')
697 |
698 | def clearEverything (self, event=None):
699 | self.clearCartGrid()
700 | self.t.refresh()
701 |
702 | def newProd(self, bc):
703 | dlg = np.GetData(self.m_papa, bc)
704 | dlg.ShowModal()
705 |
706 | def identifyParty (self, inS):
707 | if self.t.fetchCustomerId(inS):
708 | self.m_customerST.SetLabel(self.t.customerName)
709 | else:
710 | dlg = nc.GetData(self.m_papa, inS)
711 | dlg.ShowModal()
712 |
713 | self.t.fetchCustomerId(inS)
714 | self.m_customerST.SetLabel(self.t.customerName)
715 |
716 | def barcodeInput (self, event):
717 | c = event.GetUnicodeKey()
718 | if c is 8:
719 | # backspace
720 | self.inputStream = self.inputStream[:-1]
721 | if c is 27:
722 | # esc key
723 | self.inputStream = ''
724 | if c in range(48, 91):
725 | # number or alphabet
726 | self.inputStream = self.inputStream + chr(c)
727 | if c is 13:
728 | # enter key
729 | inS = self.inputStream
730 | self.inputStream = ''
731 |
732 | #checking for custom commands first
733 | if inS[:5] == 'SWINC':
734 | # increase quantity of last entered product
735 | return
736 |
737 | if inS[:5] == 'SWDEC':
738 | # decrease quantity of last entered product
739 | return
740 |
741 | if inS == 'SWPRNTRCPT':
742 | # print reciept
743 | return
744 |
745 | if inS[:2] == '03' and len(inS) == 11:
746 | # identify customer using the entered mobile number or register one
747 | self.identifyParty(inS)
748 | return
749 |
750 | # otherwise check if the entered string was a barcode number
751 | x = self.t.findProduct(inS, 1)
752 |
753 | ''
754 | if x == False:
755 | self.alert("Already in the cart", '')
756 |
757 | if type(x) == type(int()):
758 | self.alert("Only "+str(x)+" are available", '')
759 | ''
760 |
761 | if x == True:
762 | self.dumpCartInDvlc()
763 |
764 | if x is None:
765 | self.newProd(inS)
766 | x = self.t.findProduct(inS, 1)
767 | if x == True:
768 | self.dumpCartInDvlc()
769 | ''
770 | if type(x) == type(int()):
771 | self.alert("Only "+str(x)+" are available", '')
772 | ''
773 |
774 | # unfinished business here
775 | self.m_balanceST.SetLabel(self.inputStream)
776 | '''
777 |
--------------------------------------------------------------------------------
/updateInvoiceMoney.py:
--------------------------------------------------------------------------------
1 | from connectToDb import connectToDB
2 |
3 | conn = connectToDB()
4 |
5 | import wx
6 | import wx.xrc
7 |
8 | import gLedgerFunctions as af
9 | #import functions as f
10 |
11 | class GetData(wx.Dialog):
12 | def __init__(self, parent, iid, cid):
13 | self.iid = iid
14 | self.cid = cid
15 |
16 | wx.Dialog.__init__(self, parent, wx.ID_ANY, "Invoice "+iid, size= (650,500))
17 | self.panel = wx.Panel(self,wx.ID_ANY)
18 |
19 | self.m_cartDV = wx.dataview.DataViewListCtrl( self.panel, wx.ID_ANY, (20,20), wx.Size( 600, 180 ), 0 )
20 | self.m_cartDV.SetMinSize( wx.Size( -1,400 ) )
21 |
22 | self.m_cartDV.AppendTextColumn('Name')
23 | self.m_cartDV.AppendTextColumn('Quantity')
24 | self.m_cartDV.AppendTextColumn('Price')
25 | self.m_cartDV.AppendTextColumn('Total Price')
26 |
27 | qry = 'select p.name, pi.quantity, pi.price from productinvoice pi, products p where pi.product = p.id and invoiceId = %s' % (iid)
28 | curs = conn.cursor()
29 | curs.execute(qry)
30 | r = curs.fetchone()
31 | while (1):
32 | if r is not None:
33 | self.m_cartDV.AppendItem([ r['name'], str(r['quantity']), str(r['price']), str(int(r['quantity']) * int(r['price'])) ])
34 | r = curs.fetchone()
35 | else:
36 | break
37 |
38 | self.lblRecMoney = wx.StaticText(self.panel, label="Recieved Money", pos=(20,220))
39 | self.recMoney = wx.TextCtrl(self.panel, value="", pos=(130,220), size=(90,-1))
40 |
41 | self.lblcheque = wx.StaticText(self.panel, label="Cheque Number", pos=(20,270))
42 | self.chequeNum = wx.TextCtrl(self.panel, value="", pos=(130,270), size=(90,-1))
43 |
44 | self.lbltranspKey = wx.StaticText(self.panel, label="Bilty", pos=(20,320))
45 | self.transpKey = wx.TextCtrl(self.panel, value="", pos=(130,320), size=(90,-1))
46 |
47 | self.lbltranspAgency = wx.StaticText(self.panel, label="Agency", pos=(20,370))
48 | self.transpAgency = wx.TextCtrl(self.panel, value="", pos=(130,370), size=(90,-1))
49 |
50 | self.saveButton =wx.Button(self.panel, label="Save", pos=(110,420))
51 | self.closeButton =wx.Button(self.panel, label="Cancel", pos=(250,420))
52 | self.returnButton =wx.Button(self.panel, label="Return", pos=(390,420))
53 |
54 | self.saveButton.Bind(wx.EVT_BUTTON, self.SaveConnString)
55 | self.closeButton.Bind(wx.EVT_BUTTON, self.OnQuit)
56 | self.returnButton.Bind(wx.EVT_BUTTON, self.OnReturn)
57 |
58 | self.Bind(wx.EVT_CLOSE, self.OnQuit)
59 |
60 | self.Show()
61 |
62 | def returnInvoice(saleId):
63 | qry = 'INSERT INTO `refunds` (time, date, customer, totalBill, discount, preparedBy) SELECT "%s", "%s", buyerId, amount, discount, employeeId FROM invoice WHERE id = %s ' % (str(t.strftime("%H:%M", t.localtime())), t.strftime("%d-%m-%y", t.localtime()), saleId)
64 |
65 | curs = conn.cursor()
66 | curs.execute(qry)
67 |
68 | i = conn.insert_id()
69 |
70 | qry = 'INSERT INTO productrefund (refundId, product, quantity, price, discount) SELECT "%s", product, quantity, price, discount FROM productinvoice WHERE invoiceId = %s' % (i, saleId)
71 | curs.execute(qry)
72 |
73 | qry = 'UPDATE currentinventory ci JOIN productinvoice pi ON ci.productId = pi.product SET ci.quantity = ci.quantity+pi.quantity WHERE pi.invoiceId = %s' % (saleId)
74 | curs.execute(qry)
75 | conn.commit()
76 |
77 | af.invoiceReturnEntry(saleId, i)
78 |
79 | def OnReturn (self, event):
80 | returnInvoice(self.iid)
81 | self.Destroy()
82 |
83 | def OnQuit(self, event):
84 | self.result_name = None
85 | self.Destroy()
86 |
87 | def updateMoney (self, iid, amt, cust, cheque):
88 | ### update recieved amount
89 | qry = 'UPDATE `invoice` SET amountRecieved = amountRecieved+%s WHERE id = %s' % (amt, iid)
90 | curs = conn.cursor()
91 | curs.execute(qry)
92 |
93 | qry = 'INSERT INTO `invoicePayment` (invoiceId, amount) VALUES (%s, %s)' % (iid, amt)
94 | curs = conn.cursor()
95 | curs.execute(qry)
96 |
97 | conn.commit()
98 |
99 | af.invoiceMoneyUpdateEntry (amt, cust, iid, cheque)
100 |
101 | def updateTranspKey(self, transpKey, transAgency, iid):
102 | qry = 'UPDATE `invoice` SET transportKey = "%s", transportAgency = "%s" WHERE id = %s' % (transpKey, transAgency, iid)
103 | curs = conn.cursor()
104 | curs.execute(qry)
105 | conn.commit()
106 |
107 | def SaveConnString(self, event):
108 | recMoney = self.recMoney.GetValue()
109 | cheque = self.chequeNum.GetValue()
110 | transpKey = self.transpKey.GetValue()
111 | transpAgency = self.transpAgency.GetValue()
112 | if (recMoney != ''):
113 | self.updateMoney(self.iid, recMoney, self.cid, cheque)
114 | if (transpKey != ''):
115 | self.updateTranspKey(transpKey, transpAgency, self.iid)
116 | self.Destroy()
117 |
118 |
--------------------------------------------------------------------------------
/updatePurchaseMoney.py:
--------------------------------------------------------------------------------
1 | from connectToDb import connectToDB
2 |
3 | conn = connectToDB()
4 |
5 | import wx
6 | import wx.xrc
7 |
8 | import gLedgerFunctions as af
9 |
10 | class GetData(wx.Dialog):
11 | def __init__(self, parent, iid, sid):
12 | self.iid = iid
13 | self.sid = sid
14 |
15 | wx.Dialog.__init__(self, parent, wx.ID_ANY, "Purchase "+iid, size= (650,400))
16 | self.panel = wx.Panel(self,wx.ID_ANY)
17 |
18 | self.m_cartDV = wx.dataview.DataViewListCtrl( self.panel, wx.ID_ANY, (20,20), wx.Size( 600, 180 ), 0 )
19 | self.m_cartDV.SetMinSize( wx.Size( -1,400 ) )
20 |
21 | self.m_cartDV.AppendTextColumn('Name')
22 | self.m_cartDV.AppendTextColumn('Quantity')
23 | self.m_cartDV.AppendTextColumn('Price')
24 | self.m_cartDV.AppendTextColumn('Total Price')
25 |
26 | qry = 'select p.name, pp.quantity, pp.price from productpurchase pp, products p where pp.product = p.id and purchaseId = %s' % (iid)
27 | curs = conn.cursor()
28 | curs.execute(qry)
29 | r = curs.fetchone()
30 | while (1):
31 | if r is not None:
32 | self.m_cartDV.AppendItem([ r['name'], str(r['quantity']), str(r['price']), str(int(r['quantity']) * int(r['price'])) ])
33 | r = curs.fetchone()
34 | else:
35 | break
36 |
37 | self.lblRecMoney = wx.StaticText(self.panel, label="Paid Money", pos=(20,220))
38 | self.recMoney = wx.TextCtrl(self.panel, value="", pos=(130,220), size=(90,-1))
39 |
40 | self.lblcheque = wx.StaticText(self.panel, label="Cheque Number", pos=(20,270))
41 | self.chequeNum = wx.TextCtrl(self.panel, value="", pos=(130,270), size=(90,-1))
42 |
43 | self.saveButton =wx.Button(self.panel, label="Save", pos=(110,320))
44 | self.closeButton =wx.Button(self.panel, label="Cancel", pos=(250,320))
45 | self.returnButton =wx.Button(self.panel, label="Return", pos=(390,320))
46 |
47 | self.saveButton.Bind(wx.EVT_BUTTON, self.SaveConnString)
48 | self.closeButton.Bind(wx.EVT_BUTTON, self.OnQuit)
49 | self.returnButton.Bind(wx.EVT_BUTTON, self.OnReturn)
50 |
51 | self.Bind(wx.EVT_CLOSE, self.OnQuit)
52 |
53 | self.Show()
54 |
55 | def returnPurchase (purchaseId):
56 | qry = 'UPDATE purchase SET returned=1 WHERE id = %s' % (purchaseId)
57 | curs = conn.cursor()
58 | curs.execute(qry)
59 |
60 | af.purchaseReturnEntry(purchaseId)
61 |
62 | def OnReturn (self, event):
63 | returnPurchase(self.iid)
64 | self.Destroy()
65 |
66 | def OnQuit(self, event):
67 | self.result_name = None
68 | self.Destroy()
69 |
70 | def updateMoney (self, iid, amt, supp, chequeNo):
71 | qry = 'UPDATE `purchase` SET amountPaid = amountPaid+%s WHERE id = %s' % (amt, iid)
72 | curs = conn.cursor()
73 | curs.execute(qry)
74 |
75 | qry = 'INSERT INTO `purchasePayment` (purchaseId, amount) VALUES (%s, %s)' % (iid, amt)
76 | curs = conn.cursor()
77 | curs.execute(qry)
78 |
79 | conn.commit()
80 |
81 | af.purchaseMoneyUpdateEntry (amt, supp, iid, chequeNo)
82 |
83 | def SaveConnString(self, event):
84 | recMoney = self.recMoney.GetValue()
85 | if (recMoney == ''):
86 | self.updateMoney(self.iid, recMoney, self.sid, self.chequeNum.GetValue())
87 | self.Destroy()
88 |
89 |
--------------------------------------------------------------------------------
/validators.py:
--------------------------------------------------------------------------------
1 | import wx
2 | import wx.grid
3 |
4 | class numOnlyValidator(wx.Validator):
5 | def __init__(self):
6 | super(numOnlyValidator, self).__init__()
7 |
8 | self.Bind(wx.EVT_CHAR, self.Validate)
9 | # --------------------------------------------------------------------------
10 | def Clone(self):
11 | return numOnlyValidator()
12 |
13 | # --------------------------------------------------------------------------
14 | def Validate(self, event):
15 | k = event.GetKeyCode()
16 | if not(k >= 48 and k <= 57):
17 | #wx.MessageBox("Please enter numbers only", "Invalid Input", wx.OK | wx.ICON_ERROR)
18 | return False
19 |
20 | #self.GetWindow().SetValue( self.GetWindow().GetValue() + chr(k) )
21 | event.Skip()
22 | return True
23 |
24 | # --------------------------------------------------------------------------
25 | def TransferToWindow(self):
26 | return True
27 |
28 | # --------------------------------------------------------------------------
29 | def TransferFromWindow(self):
30 | return True
31 | '''
32 | class numOnlyGridEditor (wx.grid.GridCellTextEditor):
33 | def __init__ (self):
34 | super(numOnlyGridEditor, self).__init__()
35 |
36 | self.SetValidator(numOnlyValidator())
37 |
38 | def EndEdit (self, row, col, grid, oldval):
39 | print ("asdasd")
40 | if not self.Validate():
41 | return None
42 | '''
43 |
--------------------------------------------------------------------------------