pyntrastat.py 6.8 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165
  1. '''
  2. Created on Feb 12, 2020 @author: deeejas
  3. '''
  4. import xml.etree.cElementTree as ET
  5. import pandas as pd
  6. import datetime as dt
  7. def indent(elem, level=0):
  8. i = "\n" + level * " "
  9. if len(elem):
  10. # print(len(elem))
  11. if not elem.text or not elem.text.strip():
  12. elem.text = i + " "
  13. # print(elem.text)
  14. if not elem.tail or not elem.tail.strip():
  15. elem.tail = i
  16. # print(elem.tail)
  17. for elem in elem:
  18. indent(elem, level + 1)
  19. if not elem.tail or not elem.tail.strip():
  20. elem.tail = i
  21. else:
  22. if level and (not elem.tail or not elem.tail.strip()):
  23. elem.tail = i
  24. class ContactPerson(object):
  25. def __init__(self, LastName=None, FirstName=None, Email=None,
  26. Phone=None, Fax=None, Position=None):
  27. self.LastName = LastName
  28. self.FirstName = FirstName
  29. self.Email = Email
  30. self.Phone = Phone
  31. self.Fax = Fax
  32. self.Position = Position
  33. class Company(object):
  34. '''
  35. classdocs
  36. '''
  37. def __init__(self, VatNr=None, FirmName=None, RefPeriod=None,
  38. CreateDt=None, ApplicationRef=None, ContactPerson=None):
  39. '''
  40. Constructor
  41. '''
  42. self.VatNr = VatNr
  43. self.FirmName = FirmName
  44. self.RefPeriod = RefPeriod
  45. self.CreateDt = CreateDt or dt.datetime.now().strftime('%Y-%m-%dT%H:%M:%S-08:00')
  46. self.ApplicationRef = ApplicationRef
  47. self.ContactPerson = ContactPerson
  48. class Intrastat(object):
  49. def __init__(self, company: object, person: object, versions: dict,
  50. header: tuple, elem_attribs: dict, supplucodes: set):
  51. # temporary remove filename attribute as it's only need for study
  52. # self.filename = filename
  53. self.company = company
  54. self.person = person
  55. self.versions = versions
  56. self.header = header
  57. self.elem_attribs = elem_attribs
  58. # self.decl = ET.parse(self.filename)
  59. self.supplucodes = supplucodes
  60. def make_arrival(self):
  61. # creates the type of declaration: arrival/exp
  62. arrival = ET.Element('InsNewArrival', self.elem_attribs)
  63. code_vers = ET.SubElement(arrival, self.header[0])
  64. decl_header = ET.SubElement(arrival, self.header[1])
  65. company_dict = vars(self.company)
  66. person_dict = vars(self.person)
  67. self.arrival = arrival
  68. for tagname, value in self.versions.items():
  69. e = ET.SubElement(code_vers, tagname)
  70. e.text = value
  71. for tagname, value in company_dict.items():
  72. e = ET.SubElement(decl_header, tagname)
  73. e.text = value
  74. if tagname == 'ContactPerson':
  75. for subtagname, subvalue in person_dict.items():
  76. se = ET.SubElement(e, subtagname)
  77. se.text = subvalue
  78. def make_arrival_items(self, source_xls):
  79. # makes each position of the decl. is subelement of newarrival
  80. dtypes = {'NETWEIGHT': 'int64', 'NETVALUE': 'int64'}
  81. self.source_xls = source_xls
  82. df = pd.read_excel(self.source_xls, dtype=dtypes)
  83. self.grouped_df = df.groupby(
  84. [
  85. 'VSCODE',
  86. 'ACode',
  87. 'Bcode',
  88. 'DeliveryTermsCode',
  89. 'TransportCode',
  90. 'CountryOfOrigin',
  91. 'EXP',
  92. 'SUPPL'
  93. ])[
  94. ['NETVALUE',
  95. 'NETWEIGHT',
  96. 'Q',
  97. 'SUPPLVALUE'
  98. ]].sum()
  99. # helper function called here
  100. print(self.grouped_df)
  101. # print(self.grouped_df['NETVALUE'].iloc[0])
  102. self._arrival_items(self.grouped_df)
  103. def _arrival_items(self, dframe):
  104. # loops over grouped df and adds items
  105. for n in range(1, len(dframe) + 1):
  106. order_attrib = {'OrderNr': f'{n}'}
  107. # print(order_attrib)
  108. new_item = ET.SubElement(self.arrival, 'InsArrivalItem', order_attrib)
  109. new_item_code = ET.SubElement(new_item, 'Cn8Code')
  110. new_item_code.text = f'{self.grouped_df.index[n-1][0]}'
  111. new_item_val = ET.SubElement(new_item, 'InvoiceValue')
  112. new_item_val.text = f'{self.grouped_df["NETVALUE"].iloc[n-1]}'
  113. new_item_statval = ET.SubElement(new_item, 'StatisticalValue')
  114. if self.grouped_df.index[n - 1][7] == 1:
  115. new_item_statval.text = f'{int(self.grouped_df["NETVALUE"].iloc[n-1]-self.grouped_df["SUPPLVALUE"].iloc[n-1]*0.12)}'
  116. elif self.grouped_df.index[n - 1][7] == 2:
  117. new_item_statval.text = f'{int(self.grouped_df["NETVALUE"].iloc[n-1]+self.grouped_df["SUPPLVALUE"].iloc[n-1]*0.88)}'
  118. else:
  119. new_item_statval.text = f'{self.grouped_df["NETVALUE"].iloc[n-1]}'
  120. new_item_netmass = ET.SubElement(new_item, 'NetMass')
  121. new_item_netmass.text = f'{self.grouped_df["NETWEIGHT"].iloc[n-1]}'
  122. new_item_acode = ET.SubElement(new_item, 'NatureOfTransactionACode')
  123. new_item_acode.text = f'{self.grouped_df.index[n-1][1]}'
  124. new_item_bcode = ET.SubElement(new_item, 'NatureOfTransactionBCode')
  125. new_item_bcode.text = f'{self.grouped_df.index[n-1][2]}'
  126. new_item_delterms = ET.SubElement(new_item, 'DeliveryTermsCode')
  127. new_item_delterms.text = f'{self.grouped_df.index[n-1][3]}'
  128. new_item_transpcode = ET.SubElement(new_item, 'ModeOfTransportCode')
  129. new_item_transpcode.text = f'{self.grouped_df.index[n-1][4]}'
  130. new_item_origin = ET.SubElement(new_item, 'CountryOfOrigin')
  131. new_item_origin.text = f'{self.grouped_df.index[n-1][5]}'
  132. if f'{self.grouped_df.index[n-1][0]}' in self.supplucodes:
  133. new_item_supplunits = ET.SubElement(new_item, 'InsSupplUnitsInfo')
  134. new_item_supplunitcode = ET.SubElement(new_item_supplunits, 'SupplUnitCode')
  135. new_item_supplunitcode.text = 'p/st'
  136. new_item_supplunits = ET.SubElement(new_item_supplunits, 'QtyInSupplUnits')
  137. new_item_supplunits.text = f'{self.grouped_df["Q"].iloc[n-1]}'
  138. new_item_exp = ET.SubElement(new_item, 'CountryOfConsignment')
  139. new_item_exp.text = f'{self.grouped_df.index[n-1][6]}'
  140. def write_xml(self):
  141. ns = ET.register_namespace('InsNewArrival',
  142. 'http://www.intrastat.ro/xml/InsSchema')
  143. todecl = ET.ElementTree(self.arrival)
  144. indent(todecl._root)
  145. todecl.write(
  146. 'xml/{}_{}.xml'.format(self.company.VatNr.replace('00', '', 1),
  147. self.company.RefPeriod),
  148. encoding='UTF-8',
  149. xml_declaration=True,
  150. default_namespace=ns,
  151. method='xml')
  152. # EOF