PageRenderTime 56ms CodeModel.GetById 25ms RepoModel.GetById 0ms app.codeStats 0ms

/core/promogest/modules/Statistiche/ui/StatisticaGenerale.py

http://promogest.googlecode.com/
Python | 381 lines | 334 code | 24 blank | 23 comment | 21 complexity | 64de6e9f4dcaf6ccd20537ae78c496a0 MD5 | raw file
Possible License(s): GPL-2.0
  1. # -*- coding: utf-8 -*-
  2. # Copyright (C) 2005, 2006, 2007 2008, 2009, 2010, 2011 by Promotux
  3. # di Francesco Meloni snc - http://www.promotux.it/
  4. # Author: Francesco Meloni <francesco@promotux.it>
  5. # Author: Francesco Marella <francesco.marella@gmail.com>
  6. # This file is part of Promogest.
  7. # Promogest is free software: you can redistribute it and/or modify
  8. # it under the terms of the GNU General Public License as published by
  9. # the Free Software Foundation, either version 2 of the License, or
  10. # (at your option) any later version.
  11. # Promogest is distributed in the hope that it will be useful,
  12. # but WITHOUT ANY WARRANTY; without even the implied warranty of
  13. # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
  14. # GNU General Public License for more details.
  15. # You should have received a copy of the GNU General Public License
  16. # along with Promogest. If not, see <http://www.gnu.org/licenses/>.
  17. import os
  18. import datetime
  19. from promogest.ui.GladeWidget import GladeWidget
  20. from promogest import Environment
  21. from promogest.dao.TestataMovimento import TestataMovimento
  22. from promogest.dao.RigaMovimento import RigaMovimento
  23. from promogest.dao.Riga import Riga
  24. from promogest.dao.Articolo import Articolo
  25. from promogest.dao.Magazzino import Magazzino
  26. from promogest.dao.CategoriaCliente import CategoriaCliente
  27. from promogest.dao.CategoriaArticolo import CategoriaArticolo
  28. from promogest.dao.ClienteCategoriaCliente import ClienteCategoriaCliente
  29. from promogest.ui.utils import *
  30. from promogest.ui.utilsCombobox import *
  31. from promogest.ui.gtk_compat import *
  32. from promogest.dao.DaoUtils import *
  33. from promogest.lib.HtmlViewer import HtmlViewer
  34. from promogest.lib.relativedelta import relativedelta
  35. class StatisticaGenerale(GladeWidget):
  36. """ Questa classe nasce con l'intenzione di gestire una interfaccia di
  37. creazione delle statistiche pi? generale possibile,per il momento ne
  38. gestisce una
  39. TODO: Scorporare la parte logica dalla gestione della pura interfaccia
  40. """
  41. def __init__(self, idMagazzino=None, nome=""):
  42. GladeWidget.__init__(self, 'statistica_dialog',
  43. 'Statistiche/gui/statistiche_dialog.glade',
  44. isModule=True)
  45. self.placeWindow(self.getTopLevel())
  46. self.da_data_entry.set_text('01/01/' + Environment.workingYear)
  47. self.a_data_entry.set_text(dateToString(datetime.datetime.now()))
  48. # self._idMagazzino = idMagazzino
  49. self.da_data_entry.show_all()
  50. self.a_data_entry.show_all()
  51. self.cateClienteId = []
  52. self.cateArticoloId = []
  53. self.magazzinoId = []
  54. self.cateClienteDen = []
  55. self.cateArticoloDen = []
  56. self.magazzinoDen = []
  57. self.magazzinoTutti = False
  58. self.cateArticoloTutti = False
  59. self.cateClienteTutti = False
  60. self.nomestatistica= nome
  61. self.draw()
  62. def draw(self):
  63. """ Disegnamo le colonne della treeview delle statistiche """
  64. self.treeview = self.show_treeview
  65. cellspin = gtk.CellRendererToggle()
  66. cellspin.set_property('activatable', True)
  67. cellspin.connect('toggled', self.on_column_selected_edited, self.treeview, True)
  68. column = gtk.TreeViewColumn('Seleziona', cellspin)
  69. column.add_attribute( cellspin, "active", 1)
  70. column.set_sizing(GTK_COLUMN_GROWN_ONLY)
  71. column.set_resizable(True)
  72. self.treeview.append_column(column)
  73. renderer = gtk.CellRendererText()
  74. renderer.set_property('editable', False)
  75. renderer.set_data('column', 0)
  76. renderer.set_data('max_length', 200)
  77. column = gtk.TreeViewColumn('Descrizione', renderer, text=2)
  78. column.set_sizing(GTK_COLUMN_GROWN_ONLY)
  79. column.set_clickable(False)
  80. column.set_resizable(True)
  81. column.set_expand(True)
  82. self.treeview.append_column(column)
  83. self.treeview.set_search_column(2)
  84. self._treeViewModel = gtk.ListStore(object, bool, str)
  85. self.treeview.set_model(self._treeViewModel)
  86. self._refresh()
  87. def _refresh(self):
  88. datata = self.da_data_entry.get_text()
  89. adata= self.a_data_entry.get_text()
  90. produt = self.produttore_entry.get_text()
  91. buffer= self.sommario_textview.get_buffer()
  92. line_count = buffer.get_line_count()
  93. if not self.magazzinoTutti:
  94. maga = str(self.magazzinoDen)[1:-1]
  95. else:
  96. maga = "TUTTI"
  97. if not self.cateArticoloTutti:
  98. catea = str(self.cateArticoloDen)[1:-1]
  99. else:
  100. catea = "TUTTI"
  101. if not self.cateClienteTutti:
  102. catec = str(self.cateClienteDen)[1:-1]
  103. else:
  104. catec = "TUTTI"
  105. stringa ="""
  106. Stiamo per creare un CSV relativo alla statistica: %s
  107. Con i seguenti parametri di ricerca e filtraggio:
  108. DA DATA: %s
  109. A DATA: %s
  110. PRODUTTORE: %s
  111. MAGAZZINO: %s
  112. CATEGORIA CLIENTE: %s
  113. CATEGORIA ARTICOLO: %s
  114. CLIENTE : %s
  115. """%(self.nomestatistica, datata, adata, produt, maga, catec, catea,"")
  116. buffer.set_text(stringa)
  117. self.sommario_textview.set_buffer(buffer)
  118. def on_column_selected_edited(self, cell, path, treeview,value, editNext=True):
  119. """ Function to set the value quantita edit in the cell"""
  120. model = treeview.get_model()
  121. model[path][1] = not model[path][1]
  122. for a in model[path].iterchildren():
  123. a[1] = model[path][1]
  124. def on_statistica_dialog_destroy(self, widget):
  125. self.a_data_entry.destroy()
  126. self.da_data_entry.destroy()
  127. self.getTopLevel().destroy()
  128. def on_ok_button_clicked(self, button):
  129. """ cb del bottone ELABORA """
  130. if posso("STA"):
  131. self.exportss(self)
  132. else:
  133. fenceDialog()
  134. def on_tutti_button_clicked(self, button):
  135. for m in self._treeViewModel:
  136. m[1] = True
  137. def on_nessuno_button_clicked(self, button):
  138. for m in self._treeViewModel:
  139. m[1] = False
  140. def on_categoria_cliente_button_clicked(self, button):
  141. self._treeViewModel.clear()
  142. cate = CategoriaCliente().select(batchSize=None)
  143. for c in cate:
  144. self._treeViewModel.append([c,False, c.denominazione])
  145. self.treeview.set_model(self._treeViewModel)
  146. def on_categoria_articolo_clicked(self, button):
  147. self._treeViewModel.clear()
  148. cate = CategoriaArticolo().select(batchSize=None)
  149. for c in cate:
  150. self._treeViewModel.append([c,False, c.denominazione])
  151. self.treeview.set_model(self._treeViewModel)
  152. def on_magazzino_button_clicked(self, button):
  153. """ cb del bottone magazzino """
  154. self._treeViewModel.clear()
  155. mag = Magazzino().select(batchSize=None)
  156. for c in mag:
  157. self._treeViewModel.append([c,False, c.denominazione])
  158. self.treeview.set_model(self._treeViewModel)
  159. def on_famiglia_articolo_clicked(self, button):
  160. return
  161. def on_aggiungi_regola_button_clicked(self, button):
  162. """ cb del bottone aggiungi regola """
  163. if len(self._treeViewModel) > 0:
  164. if type(self._treeViewModel[0][0]).__name__ =="CategoriaCliente":
  165. self.cateClienteId=[]
  166. self.cateClienteDen=[]
  167. self.cateClienteTutti = True
  168. elif type(self._treeViewModel[0][0]).__name__ =="CategoriaArticolo":
  169. self.cateArticoloId = []
  170. self.cateArticoloDen = []
  171. self.cateArticoloTutti = True
  172. elif type(self._treeViewModel[0][0]).__name__ =="Magazzino":
  173. self.magazzinoId = []
  174. self.magazzinoDen = []
  175. self.magazzinoTutti = True
  176. for riga in self._treeViewModel:
  177. if type(riga[0]).__name__ =="CategoriaCliente" and riga[1] == True:
  178. self.cateClienteId.append(riga[0].id)
  179. self.cateClienteDen.append(str(riga[0].denominazione))
  180. elif type(riga[0]).__name__ =="CategoriaCliente" and riga[1] == False:
  181. self.cateClienteTutti = False
  182. elif type(riga[0]).__name__ =="CategoriaArticolo" and riga[1] == True:
  183. self.cateArticoloId.append(riga[0].id)
  184. self.cateArticoloDen.append(str(riga[0].denominazione))
  185. elif type(riga[0]).__name__ =="CategoriaArticolo" and riga[1] == False:
  186. self.cateArticoloTutti = False
  187. elif type(riga[0]).__name__ =="Magazzino" and riga[1] == True:
  188. self.magazzinoId.append(riga[0].id)
  189. self.magazzinoDen.append(str(riga[0].denominazione))
  190. elif type(riga[0]).__name__ =="Magazzino" and riga[1] == False:
  191. self.magazzinoTutti = False
  192. self._refresh()
  193. def exportss(self, filename):
  194. idsCliente = []
  195. idsArticoli = []
  196. artiID = []
  197. intervallo = ''
  198. self.res = []
  199. # Prelevo i dati dalla ui
  200. daData = stringToDate(self.da_data_entry.get_text())
  201. aData = stringToDate(self.a_data_entry.get_text())
  202. produt = self.produttore_entry.get_text()
  203. # Id dei clienti
  204. clienti = ClienteCategoriaCliente().select(idCategoria = self.cateClienteId, batchSize=None)
  205. for cli in clienti:
  206. idsCliente.append(cli.id_cliente)
  207. # id degli articoli
  208. articoli = Articolo().select(idCategoria = self.cateArticoloId,
  209. produttore = produt, batchSize=None)
  210. for art in articoli:
  211. idsArticoli.append(art.id)
  212. # inizializzo un po' di variabili e dizionari
  213. quantitaVendutaDict = {}
  214. quantitaAcquistata = 0
  215. quantitaAcquistataTotale = 0
  216. valoreAcquistoDict= {}
  217. valoreAcquisto = 0
  218. quantitaVenduta = 0
  219. quantitaVendutaTotale = 0
  220. valoreAcquistoTotale= 0
  221. valoreVenditaDict = {}
  222. valoreVendita = 0
  223. valoreVenditaTotale = Decimal("0")
  224. ricaricomedioDict = {}
  225. incidenzaAcquistoDict = {}
  226. incidenzaVenditaDict = {}
  227. # smisto i dati secondo categoriaArticolo
  228. print " ID CATEGORIE", self.cateArticoloId
  229. for arto in self.cateArticoloId:
  230. # INIZIO livello categoria
  231. nomeCategoria = CategoriaArticolo().getRecord(id=arto)
  232. articoli = Articolo().select(idCategoria = arto,
  233. produttore = produt, batchSize=None)
  234. print "ARTICOLI IN QUELLA CATEGORIA", len(articoli)
  235. for art in articoli:
  236. # INIZIO livello articolo
  237. print "INIZIO AD ELABORARE L'ARTICOLO ", art.id
  238. quantitaVendutaUNO = 0
  239. quantitaVendutaTotaleUNO = 0
  240. quantitaAcquistataUNO = 0
  241. quantitaAcquistataTotaleUNO = 0
  242. # tutte le righe movimento per la vendita
  243. righeArticoloMovimentate= Environment.params["session"]\
  244. .query(RigaMovimento, TestataMovimento)\
  245. .filter(TestataMovimento.data_movimento.between(daData, aData))\
  246. .filter(TestataMovimento.id_cliente.in_(idsCliente))\
  247. .filter(RigaMovimento.id_testata_movimento == TestataMovimento.id)\
  248. .filter(Riga.id_magazzino.in_(self.magazzinoId))\
  249. .filter(Riga.id_articolo == art.id)\
  250. .all()
  251. print "RIGHE DI MOVIMENTO VENDITA", righeArticoloMovimentate
  252. for rig in righeArticoloMovimentate:
  253. # Quanti ne ho venduti IN TOTALE
  254. quantitaVendutaUNO += rig[0].quantita
  255. quantitaVendutaTotaleUNO += rig[0].quantita
  256. quantitaVendutaTotale += rig[0].quantita
  257. quantitaAcquistataUNO = 0
  258. rigaArticoloMovimentata= Environment.params["session"]\
  259. .query(RigaMovimento, TestataMovimento)\
  260. .filter(TestataMovimento.data_movimento.between(daData+relativedelta(months=-4), aData))\
  261. .filter(TestataMovimento.id_cliente == None)\
  262. .filter(TestataMovimento.id_fornitore != None)\
  263. .filter(RigaMovimento.id_testata_movimento == TestataMovimento.id)\
  264. .filter(Riga.id_magazzino.in_(self.magazzinoId))\
  265. .filter(Riga.id_articolo == art.id)\
  266. .all()
  267. print "RIGHE DI MOVIMENTO ACQUISTOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOO", rigaArticoloMovimentata
  268. if not rigaArticoloMovimentata:
  269. forni= leggiFornitura(art.id)
  270. valoreAcquisto += (forni["prezzoNetto"]*quantitaVendutaUNO)
  271. valoreAcquistoTotale += (forni["prezzoNetto"]*quantitaVendutaUNO)
  272. print " PREZZO DA FORNITURA"
  273. else:
  274. # for r in rigaArticoloMovimentata:
  275. valoreAcquisto += (rigaArticoloMovimentata[0][0].valore_unitario_netto*quantitaVendutaUNO)
  276. valoreAcquistoTotale += (rigaArticoloMovimentata[0][0].valore_unitario_netto*quantitaVendutaUNO)
  277. quantitaAcquistataUNO += rigaArticoloMovimentata[0][0].quantita
  278. quantitaAcquistataTotaleUNO += rigaArticoloMovimentata[0][0].quantita
  279. # quantitaAcquistataTotale += r[0].quantita
  280. print " VALORE ACQUISTO", valoreAcquisto
  281. ope = leggiOperazione(rig[1].operazione)
  282. if ope["fonteValore"] =="vendita_iva":
  283. # devo scorporare l'iva dal prezzo finale di vendita
  284. imponibile = Decimal(str(float(rig[0].valore_unitario_netto)/(1+float(rig[0].percentuale_iva)/100)))
  285. elif ope["fonteValore"] =="vendita_senza_iva":
  286. imponibile = Decimal(str(float(rig[0].valore_unitario_netto)))
  287. else:
  288. print "TIPO DI FONTE VALORE PER LA VENDITA NN RICONOSCIUTO"
  289. valoreVendita += (imponibile*quantitaVendutaUNO)
  290. valoreVenditaTotale += (imponibile*quantitaVendutaUNO)
  291. # QUESTO LIVELLO ARTICOLO
  292. if quantitaVendutaTotaleUNO <= quantitaAcquistataTotaleUNO:
  293. print "ARTICOLO %s OK", str(art.id), quantitaVendutaTotaleUNO,quantitaAcquistataTotaleUNO
  294. else:
  295. print " SERVE TROVARE UN PREZZO ACQUISTO", str(art.id),quantitaVendutaTotaleUNO,quantitaAcquistataTotaleUNO
  296. # Questo livello categoria
  297. quantitaVenduta =+quantitaVendutaTotale
  298. if valoreAcquisto!=0:
  299. ricaricomedioDict[nomeCategoria.denominazione] = ((valoreVendita - valoreAcquisto )/ valoreAcquisto) *100
  300. else:
  301. ricaricomedioDict[nomeCategoria.denominazione] = 0
  302. quantitaVendutaDict[nomeCategoria.denominazione] = quantitaVenduta or Decimal("0")
  303. valoreAcquistoDict[nomeCategoria.denominazione] = valoreAcquisto or Decimal("0")
  304. valoreVenditaDict[nomeCategoria.denominazione] = valoreVendita or Decimal("0")
  305. quantitaVenduta = 0
  306. valoreAcquisto = 0
  307. valoreVendita = 0
  308. # Questo livello fuori da tutto
  309. for k,v in valoreVenditaDict.items():
  310. if v:
  311. incidenzaVenditaDict[k] = v*100 / valoreVenditaTotale
  312. else:
  313. incidenzaVenditaDict[k] = 0
  314. for k,v in valoreAcquistoDict.items():
  315. if v:
  316. incidenzaAcquistoDict[k] = v*100 / valoreAcquistoTotale
  317. else:
  318. incidenzaAcquistoDict[k] = 0
  319. print "FINE ELABORAZIONE", tempo()
  320. pageData = {
  321. "file": "statistica_ricarico_medio_e_influenza_vendite.html",
  322. "categorieArticolo": self.cateArticoloDen,
  323. "quantitaVendutaDict":quantitaVendutaDict,
  324. "valoreAcquistoDict":valoreAcquistoDict,
  325. "valoreVenditaDict":valoreVenditaDict,
  326. "ricaricomedioDict":ricaricomedioDict,
  327. "incidenzaVenditaDict": incidenzaVenditaDict,
  328. "incidenzaAcquistoDict": incidenzaAcquistoDict,
  329. "quantitaVendutaTotale": quantitaVendutaTotale,
  330. "valoreAcquistoTotale": valoreAcquistoTotale,
  331. "valoreVenditaTotale": valoreVenditaTotale,
  332. "daData": self.da_data_entry.get_text(),
  333. "aData":self.a_data_entry.get_text(),
  334. "produttore": produt,
  335. "cateclienti": self.cateClienteDen,
  336. "magazzini": self.magazzinoDen,
  337. "nomestatistica":self.nomestatistica}
  338. view = HtmlViewer(pageData)
  339. return