├── 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 |
  1. Screenshots
  2. 8 |
  3. This software is written using Python 3 and powered by MySQL.
  4. 9 |
  5. It has so far been tested on Linux.
  6. 10 |
11 | 12 |

Features

13 |
14 |

Point of Sale

15 |
16 |
    17 |
  1. Functionality to query and add products by Barcode Number, Name and Code Name.
  2. 18 |
  3. Associate customer with each sale and purchase using their unique contact mobile phone number.
  4. 19 |
  5. Apply discount of individual products and the entire sale.
  6. 20 |
  7. Sale with cash (full payment), cheque (credit sale), purchase and return both sales and purchase.
  8. 21 |
  9. Update cash collected/paid against credit sales/purchase with cheque numbers.
  10. 22 |
23 |
24 |

Accounting

25 |
26 |
    27 |
  1. 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.
  2. 28 |
  3. Make manual General Journal Entries
  4. 29 |
  5. Edit existing entries
  6. 30 |
  7. Display accounts of each Head of Account
  8. 31 |
  9. Maintain Accounts Recievable and Payable of each customer
  10. 32 |
  11. Create Control Account
  12. 33 |
  13. Create Income Statement
  14. 34 |
  15. All accounts mentioned above can be viewed for any date range
  16. 35 |
36 |
37 |

Future Plans

38 |
39 |
    40 |
  1. Add ERP functionality to control access rights of employees
  2. 41 |
  3. Add Depreciation and Inventory Valuation
  4. 42 |
  5. Include BI Dashboard
  6. 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 | --------------------------------------------------------------------------------