_invoice.py 6.9 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179
  1. # from winmentor import count_down, tarif, headers
  2. import os
  3. import re
  4. import mimetypes
  5. from time import sleep
  6. from datetime import datetime, time
  7. from email.header import Header
  8. from email.mime.base import MIMEBase
  9. from email.mime.multipart import MIMEMultipart
  10. from email.mime.application import MIMEApplication
  11. from email.mime.audio import MIMEAudio
  12. from email.mime.image import MIMEImage
  13. from email.mime.text import MIMEText
  14. from fpdf import FPDF
  15. from envelopes import Envelope
  16. from winmentor import WinMentor
  17. # imports for Envelope subclass
  18. # imports for Envelope subclass
  19. # import logging
  20. # logging.basicConfig(filename='winmentor/generated_files/inv_number',
  21. # format='%(asctime)s %(message)s', datefmt='%m/%d/%Y %I:%M:%S %p', level=logging.INFO)
  22. def _printer(func):
  23. def wrapper(*args, **kwargs):
  24. print(datetime.now().microsecond, 'now processing', func.__name__)
  25. return func(*args)
  26. return wrapper
  27. class HtmlEnvelope(Envelope):
  28. def __init__(self, msg_type='alternative'):
  29. self.msg_type = msg_type
  30. Envelope.__init__(self)
  31. def to_mime_message(self):
  32. """Returns the envelope as
  33. :py:class:`email.mime.multipart.MIMEMultipart`."""
  34. msg = MIMEMultipart(self.msg_type) # html for attachments
  35. msg['Subject'] = self._header(self._subject or '')
  36. msg['From'] = self._encoded(self._addrs_to_header([self._from]))
  37. msg['To'] = self._encoded(self._addrs_to_header(self._to))
  38. if self._cc:
  39. msg['CC'] = self._addrs_to_header(self._cc)
  40. if self._headers:
  41. for key, value in self._headers.items():
  42. msg[key] = self._header(value)
  43. for part in self._parts:
  44. type_maj, type_min = part[0].split('/')
  45. if type_maj == 'text' and type_min in ('html', 'plain'):
  46. msg.attach(MIMEText(part[1], type_min, self._charset))
  47. else:
  48. msg.attach(part[1])
  49. return msg
  50. def add_to_addr(self, to_addr):
  51. """Adds a ``To`` address."""
  52. if isinstance(to_addr, str):
  53. self._to.append(to_addr)
  54. else:
  55. self._to.extend(to_addr)
  56. class InvoiceDetails(object):
  57. def __init__(self):
  58. self.invoiceref = ''
  59. self.supplref = ''
  60. self.clientref = ''
  61. class Invoice(object):
  62. PATH_PDF = 'winmentor/generated_files'
  63. TARIF = {}
  64. def __init__(self, fiscal_code, _companies, winment_path=os.getenv('WINMENT', 'c:/winment/data/').replace('\\', '/')):
  65. self._companies = _companies
  66. self.bank_account = set()
  67. self.net = set()
  68. self.winment_path = winment_path
  69. self.fiscal_code = fiscal_code
  70. self._name = self.__supplyer__().name
  71. self._fiscal_code = self.__supplyer__().vat_code
  72. self._reg = self.__supplyer__().reg_number
  73. self._address = self.__supplyer__().address + self.__supplyer__().location
  74. @classmethod
  75. def set_tarifs(cls, tarif):
  76. cls.TARIF = tarif
  77. return cls.TARIF
  78. @classmethod
  79. def set_pdf_path(cls, new_path):
  80. cls.PATH_PDF = new_path
  81. return cls.PATH_PDF
  82. def add_net(self, value):
  83. self.net.add(value)
  84. return self.net
  85. def net_printer(self):
  86. for i in self.net:
  87. return i
  88. def add_bank_account(self, account_num):
  89. self.bank_account.add(account_num)
  90. return self.bank_account
  91. @_printer
  92. def account_printer(self):
  93. for i in self.bank_account:
  94. return i
  95. @_printer
  96. def __supplyer__(self):
  97. for i in self._companies:
  98. if i.vat_code == self.fiscal_code:
  99. return i
  100. @property
  101. def get_code(self):
  102. return self.fiscal_code
  103. @get_code.setter
  104. def set_code(self, _value):
  105. self.fiscal_code = _value
  106. return self.fiscal_code
  107. def pdf_body(self, list_, tarifs, numbers, service_name):
  108. for i in tarifs.keys():
  109. if i == list_.name:
  110. # deprecated: d_set = [tarifs[i]['mail'], tarifs[i]['price']]# list_.extend(d_set)
  111. list_.mail = tarifs[i]['mail']
  112. list_.price = tarifs[i]['price']
  113. self.pdf.cell(110, 10, 'Cota tva: 19.00, tva la incasare', border=0, ln=1, align='L')
  114. self.pdf.cell(130, 10, 'Denumire', border=1, ln=0, align='C')
  115. self.pdf.cell(20, 10, 'PU', border=1, ln=0, align='C')
  116. self.pdf.cell(20, 10, 'Valoare', border=1, ln=0, align='C')
  117. self.pdf.cell(10, 10, 'Tva', border=1, ln=1, align='C')
  118. self.pdf.cell(130, 10, service_name, border=1, ln=0)
  119. self.pdf.cell(20, 10, f'{list_.price}', border=1, ln=0, align='C') # unit price
  120. self.pdf.cell(20, 10, f'{list_.price}', border=1, ln=0, align='C') # value
  121. self.pdf.cell(10, 10, f'{list_.price * 0.19:.2f}', border=1, ln=1, align='C') # Vat
  122. self.pdf.cell(40, 10, 'TOTAL:', border=0, ln=0)
  123. self.pdf.cell(140, 10, f'{round(list_.price * 1.19, 2)}', border=0, ln=1, align='R') # total
  124. # deprecated: if isinstance(list_[-2], int): above values else: above values
  125. self.pdf.cell(170, 10, 'Semnarea si stampilarea facturilor nu constituie elemente', border=0, ln=1, align='C')
  126. self.pdf.cell(170, 10, 'obligatorii pe care trebuie sa le contina factura, ART. 319 alin. 29 leg.227/2015, oug. 17/2015.', border=0, ln=1, align='C')
  127. self.pdf.cell(170, 10, 'Operator: Darvai Claudia, Termen: 10 zile', border=0, ln=1, align='L') # due date
  128. # self.pdf.cell(170, 10, 'Semnatura furnizorului', border=0, ln=1, align='L') # picture link
  129. # self.pdf.cell(170, 10, 'Semnatura de primire', border=0, ln=1, align='L')
  130. @_printer
  131. def gen_file(self, list_, image, link, tarifs, numbers, service_name):
  132. self.pdf = FPDF()
  133. self.pdf.add_page()
  134. self.pdf.set_font('Helvetica', style='B', size=12)
  135. self.pdf.cell(65, 10, ' ', align='C', border=0)
  136. self.pdf.multi_cell(60, 10, txt=f'Factura seria/numarul AB-{numbers} din {datetime.now().date()}', border=1, align='C')
  137. self.pdf.set_font('Helvetica', style='', size=9)
  138. self.pdf.multi_cell(100, 10, txt=f'Furnizor: {self._name}\nCod fiscal: {self._fiscal_code}\n\
  139. Nr. reg.: {self._reg}\nAdresa: {self._address}\nnr.cont: {self.account_printer()}\n\
  140. web: {self.net_printer()}', border=0, align='L')
  141. self.pdf.cell(90, 10, ' ', align='R', border=0)
  142. self.pdf.multi_cell(110, 10, txt=f'Client: {list_.name}\nCod fiscal: {list_.vat_code}\n\
  143. Nr. reg.: {list_.reg_number}\nAdresa {list_.address} {list_.location}', border=0, align='R')
  144. self.pdf.ln(25)
  145. self.pdf_body(list_, tarifs, numbers, service_name)
  146. self.pdf.image(image, x=80, w=50, h=25, link=link)
  147. self.pdf.output(f'{self.PATH_PDF}/Factura {list_.name.title()} {datetime.now().date()}.pdf')