JPK.php 38 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820821822823824825826827828829830831832833834835836837838839840841842843844845846847848849850851852853854855856857858859860861862863864865866867868869870871872873874875876877878879880881882883884885886887888889890891892893894895896897898899900901902903904905906907908909910911912913914915916917918919920921922923924925926927928929930931932933934935936937938939940941942943944945946947948949950951952953954955956957958959960961962963
  1. <?php
  2. Lib::loadClass('RouteBase');
  3. Lib::loadClass('ProcesHelper');
  4. class Route_UrlAction_JPK extends RouteBase {
  5. private $REFERER, $LAST_REFERER;
  6. private $JPK, $BO;
  7. public function handleAuth() {
  8. if (!User::logged()) {
  9. throw new HttpException('Unauthorized', 401);
  10. }
  11. $this->LAST_REFERER = $_SERVER['HTTP_REFERER'];
  12. if (($this->REFERER=V::get('REFERER','',$_POST))=='') $this->REFERER = $_SERVER['HTTP_REFERER'];
  13. try {
  14. if (!($ID_JPK = V::get('ID_JPK',0,$_GET,'int'))) throw new Exception("Błąd parametru");
  15. if ($result = DB::getPDO()->fetchall("select * from JPK where ID='{$ID_JPK}'")) $this->JPK = $result[0];
  16. else throw new Exception("Dostęp zabroniony");
  17. if ($result = DB::getPDO()->fetchall("select * from BILLING_OWNER where ID='{$this->JPK['ID_BILLING_OWNER']}'")) $this->BO = $result[0];
  18. else throw new Exception("Błąd spójności danych");
  19. } catch (Exception $e) {
  20. SE_Layout::gora();
  21. SE_Layout::menu();
  22. SE_Layout::alert('danger',$e->getMessage());
  23. ?>
  24. <div class="container" style="text-align:center">
  25. <a href="<?=$this->REFERER?>" class="btn btn-primary">Powrót</a>
  26. </div>
  27. <?php
  28. SE_Layout::dol();
  29. die();
  30. }
  31. }
  32. private function initialize() {
  33. SE_Layout::gora();
  34. SE_Layout::menu();
  35. try {
  36. if (V::get('action','',$_POST) == 'initialize') {
  37. $month = V::get('MONTH','',$_POST);
  38. $purpose = V::get('PURPOSE','',$_POST);
  39. if (!preg_match("/^[[:digit:]]{4}-[[:digit:]]{2}$/",$month)) throw new Exception("błędny format daty (YYYY-MM)");
  40. switch ($purpose) {
  41. case "1":
  42. $lastMonth = DB::getPDO()->fetchValue("select max(MONTH) from JPK where ID_BILLING_OWNER='{$this->JPK['ID_BILLING_OWNER']}' and TYPE='{$this->JPK['TYPE']}' and PURPOSE='1'");
  43. if (strtotime($month) <= strtotime($lastMonth)) throw new Exception("błędny miesiąc (deklaracja z tego okresu lub późniejszego już istnieje)");
  44. break;
  45. case "2":
  46. $JPKexists = DB::getPDO()->fetchValue("select ID from JPK where ID_BILLING_OWNER='{$this->JPK['ID_BILLING_OWNER']}' and TYPE='{$this->JPK['TYPE']}' and MONTH='{$month}' and PURPOSE='1'");
  47. if (!$JPKexists) throw new Exception("brak deklaracji z tego okresu - nie ma czego korygować");
  48. break;
  49. default:
  50. throw new Exception("błędne określenie celu złożenia deklaracji");
  51. }
  52. $sqlObj = new stdClass();
  53. $sqlObj->ID = $this->JPK['ID'];
  54. $sqlObj->A_STATUS = 'NORMAL';
  55. $sqlObj->A_STATUS_INFO = 'W trakcie tworzenia';
  56. $sqlObj->MONTH = $month;
  57. $sqlObj->PURPOSE = $purpose;
  58. $affected = DB::getDB()->UPDATE_OBJ('JPK', $sqlObj);
  59. if ($affected) {
  60. SE_Layout::alert('success','Pomyślnie zainicjalizowano deklarację JPK.');
  61. ?>
  62. <div class="container" style="text-align:center">
  63. <form method="post">
  64. <input type="hidden" name="REFERER" value="<?=$this->REFERER?>"/>
  65. <button type="submit" class="btn btn-primary">Edytuj</button>
  66. <a href="<?=$this->REFERER?>" class="btn btn-default">Powrót</a>
  67. </form>
  68. </div>
  69. <?php
  70. }
  71. else {
  72. SE_Layout::alert('warning','Wystąpił nieznany błąd podczas inicjalizowania deklaracji JPK.');
  73. ?>
  74. <div class="container" style="text-align:center">
  75. <a href="<?=$this->REFERER?>" class="btn btn-primary">Powrót</a>
  76. </div>
  77. <?php
  78. }
  79. } else {
  80. ?>
  81. <div class="container" style="margin-top:20px">
  82. <form class="form-horizontal" method="post">
  83. <legend>Inicjalizacja deklaracji JPK</legend>
  84. <div class="form-group">
  85. <label class="col-sm-3 control-label">Operator</label>
  86. <div class="col-sm-9" style="margin-top:7px;"><?=$this->BO['name1']?></div>
  87. </div>
  88. <div class="form-group">
  89. <label class="col-sm-3 control-label">Typ JPK</label>
  90. <div class="col-sm-9" style="margin-top:7px;"><?=$this->JPK['TYPE']?></div>
  91. </div>
  92. <div class="form-group">
  93. <label class="col-sm-3 control-label">Miesiąc, którego dotyczy deklaracja</label>
  94. <div class="col-sm-2">
  95. <div class="input-group">
  96. <input type="text" id="MONTH" class="form-control se_type-date" name="MONTH" value="2017-01" maxlength="7"/>
  97. <span class="input-group-addon">
  98. <span class="glyphicon glyphicon-calendar"/>
  99. </span>
  100. </input>
  101. </div>
  102. </div>
  103. </div>
  104. <div class="form-group">
  105. <label class="col-sm-3 control-label">Cel złożenia deklaracji za dany okres</label>
  106. <div class="col-sm-3">
  107. <select class="form-control" name="PURPOSE">
  108. <option value="1">Złożenie po raz pierwszy</option>
  109. <option value="2">Korekta</option>
  110. </select>
  111. </div>
  112. </div>
  113. <div class="form-group">
  114. <div class="col-sm-offset-3 col-sm-9">
  115. <button type="submit" class="btn btn-primary" name="action" value="initialize">Zapisz</button>
  116. <a href="<?=$this->REFERER?>" class="btn btn-default">Anuluj</a>
  117. </div>
  118. </div>
  119. <input type="hidden" name="REFERER" value="<?=$this->REFERER?>"/>
  120. </form>
  121. </div>
  122. <script>
  123. jQuery(document.getElementById('MONTH')).parent().datetimepicker({
  124. format: 'YYYY-MM'
  125. , locale: 'pl'
  126. , showTodayButton: false
  127. , minDate: '2017-01-01'
  128. , maxDate: '<?=date("Y-m", strtotime("-1 month"))?>-28'
  129. });
  130. </script>
  131. <?php
  132. }
  133. } catch (Exception $e) {
  134. SE_Layout::alert('danger', "Wystąpił problem z inicjalizacją deklaracji JPK - " . $e->getMessage());
  135. ?>
  136. <div class="container" style="text-align:center">
  137. <a href="<?=$this->REFERER?>" class="btn btn-primary">Powrót</a>
  138. </div>
  139. <?php
  140. }
  141. SE_Layout::dol();
  142. }
  143. private $fieldsDescrJPK_VAT = array(
  144. "KodFormularza" => "Kod formularza",
  145. "WariantFormularza" => "Wariant formularza",
  146. "CelZlozenia" => "Cel złożenia",
  147. "DataWytworzeniaJPK" => "Data wytworzenia JPK",
  148. "DataOd" => "Data od",
  149. "DataDo" => "Data do",
  150. "DomyslnyKodWaluty" => "Waluta",
  151. "KodUrzedu" => "Kod urzędu skarbowego",
  152. "PelnaNazwa" => "Nazwa podmiotu",
  153. "NIP" => "NIP",
  154. "REGON" => "Regon",
  155. "KodKraju" => "Kod kraju",
  156. "Wojewodztwo" => "Województwo",
  157. "Powiat" => "Powiat",
  158. "Gmina" => "Gmina",
  159. "Miejscowosc" => "Miejscowość",
  160. "Ulica" => "Ulica",
  161. "NrDomu" => "Nr domu",
  162. "NrLokalu" => "Nr lokalu",
  163. "KodPocztowy" => "Kod pocztowy",
  164. "Poczta" => "Poczta",
  165. "LiczbaWierszySprzedazy" => "Liczba dokumentów sprzedaży",
  166. "PodatekNalezny" => "Podatek należny",
  167. "LiczbaWierszyZakupow" => "Liczba dokumentów zakupu",
  168. "PodatekNaliczony" => "Podatek naliczony"
  169. );
  170. private function showJPK_VAT($xml) {
  171. $ns = $xml->getNamespaces(true);
  172. $summaryJPK_VAT = $this->getSummaryJPK_VAT($xml);
  173. $result['KodFormularza'] = $xml->Naglowek->KodFormularza;
  174. $result['WariantFormularza'] = $xml->Naglowek->WariantFormularza;
  175. $result['CelZlozenia'] = $xml->Naglowek->CelZlozenia;
  176. $result['DataWytworzeniaJPK'] = date("Y-m-d H:i:s", strtotime($xml->Naglowek->DataWytworzeniaJPK));
  177. $result['DataOd'] = $xml->Naglowek->DataOd;
  178. $result['DataDo'] = $xml->Naglowek->DataDo;
  179. $result['DomyslnyKodWaluty'] = $xml->Naglowek->DomyslnyKodWaluty;
  180. $result['KodUrzedu'] = $xml->Naglowek->KodUrzedu;
  181. $result['NIP'] = $xml->Podmiot1->IdentyfikatorPodmiotu->children($ns['etd'])->NIP;
  182. $result['PelnaNazwa'] = $xml->Podmiot1->IdentyfikatorPodmiotu->children($ns['etd'])->PelnaNazwa;
  183. $result['REGON'] = $xml->Podmiot1->IdentyfikatorPodmiotu->children($ns['etd'])->REGON;
  184. $result['KodKraju'] = $xml->Podmiot1->AdresPodmiotu->KodKraju;
  185. $result['Wojewodztwo'] = $xml->Podmiot1->AdresPodmiotu->Wojewodztwo;
  186. $result['Powiat'] = $xml->Podmiot1->AdresPodmiotu->Powiat;
  187. $result['Gmina'] = $xml->Podmiot1->AdresPodmiotu->Gmina;
  188. $result['Ulica'] = $xml->Podmiot1->AdresPodmiotu->Ulica;
  189. $result['NrDomu'] = $xml->Podmiot1->AdresPodmiotu->NrDomu;
  190. $result['NrLokalu'] = $xml->Podmiot1->AdresPodmiotu->NrLokalu;
  191. $result['Miejscowosc'] = $xml->Podmiot1->AdresPodmiotu->Miejscowosc;
  192. $result['KodPocztowy'] = $xml->Podmiot1->AdresPodmiotu->KodPocztowy;
  193. $result['Poczta'] = $xml->Podmiot1->AdresPodmiotu->Poczta;
  194. $result['LiczbaWierszySprzedazy'] = $summaryJPK_VAT['LiczbaWierszySprzedazy'] ? $summaryJPK_VAT['LiczbaWierszySprzedazy'] : "";
  195. $result['PodatekNalezny'] = $summaryJPK_VAT['LiczbaWierszySprzedazy'] ? number_format($summaryJPK_VAT['PodatekNalezny'], 2, ',', '.'): "";
  196. $result['LiczbaWierszyZakupow'] = $summaryJPK_VAT['LiczbaWierszyZakupow'] ? $summaryJPK_VAT['LiczbaWierszyZakupow'] : "";
  197. $result['PodatekNaliczony'] = $summaryJPK_VAT['LiczbaWierszyZakupow'] ? number_format($summaryJPK_VAT['PodatekNaliczony'], 2, ',', '.'): "";
  198. return $result;
  199. }
  200. private function showTable() {
  201. ?>
  202. <div class="form-group">
  203. <div class="col-sm-12">
  204. <table class="table table-bordered table-hover table-striped">
  205. <thead>
  206. <tr style="text-align:center; background-color:lightgray"><td width="19%"></td><td witdh="27%">Insert</td><td width="27%">L1</td><td width="27%">Dane wynikowe</td></tr>
  207. </thead>
  208. <tbody>
  209. <?php
  210. if ($this->JPK['IN_INSERT']) {
  211. $xmlIN_INSERT = simplexml_load_string($this->JPK['IN_INSERT']);
  212. $IN_INSERT = $this->showJPK_VAT($xmlIN_INSERT);
  213. }
  214. if ($this->JPK['IN_L1']) {
  215. $xmlIN_L1 = simplexml_load_string($this->JPK['IN_L1']);
  216. $IN_L1 = $this->showJPK_VAT($xmlIN_L1);
  217. }
  218. if ($this->JPK['OUT_MERGED']) {
  219. $xmlOUT_MERGED = simplexml_load_string($this->JPK['OUT_MERGED']);
  220. $OUT_MERGED = $this->showJPK_VAT($xmlOUT_MERGED);
  221. }
  222. foreach ($this->fieldsDescrJPK_VAT as $fieldKey => $fieldName) {
  223. echo "<tr><td>{$fieldName}</td><td>";
  224. if ($this->JPK['IN_INSERT']) echo $IN_INSERT[$fieldKey];
  225. echo "</td><td>";
  226. if ($this->JPK['IN_L1']) echo $IN_L1[$fieldKey];
  227. echo "</td><td>";
  228. if ($this->JPK['OUT_MERGED']) echo $OUT_MERGED[$fieldKey];
  229. echo "</td></tr>\n";
  230. }
  231. ?>
  232. </tbody>
  233. </table>
  234. </div>
  235. </div>
  236. <?php
  237. }
  238. private function show() {
  239. if (V::get('action','',$_POST) == "getJPK") {
  240. try {
  241. if (!$this->JPK['OUT_MERGED']) throw new Exception("Błąd danych - nie wygenerowano wynikowego pliku JPK");
  242. $xml = simplexml_load_string($this->JPK['OUT_MERGED']);
  243. $ns = $xml->getNamespaces(true);
  244. $this->validateJPK_VAT($xml);
  245. $fileName = preg_replace("/[: \.]/", "_", "JPK_VAT_{$this->JPK['MONTH']}_"
  246. . str_replace('"', '', $xml->Podmiot1->IdentyfikatorPodmiotu->children($ns['etd'])->PelnaNazwa)
  247. . "_" . str_replace("T", "_", $xml->Naglowek->DataWytworzeniaJPK)) . ".xml";
  248. $output = $xml->asXml();
  249. header("Content-Type: text/xml");
  250. header("Content-Disposition: attachment; filename={$fileName};");
  251. header("Content-Transfer-Encoding: binary");
  252. header("Content-Length: " . strlen($output));
  253. echo $output;
  254. } catch (Exception $e) {
  255. SE_Layout::gora();
  256. SE_Layout::menu();
  257. SE_Layout::alert('danger', $e->getMessage());
  258. ?>
  259. <div class="container" style="text-align:center">
  260. <form method="post" action="<?=$this->LAST_REFERER?>">
  261. <input type="hidden" name="REFERER" value="<?=$this->REFERER?>"/>
  262. <button type="submit" class="btn btn-primary">Powrót</button>
  263. </form>
  264. </div>
  265. <?php
  266. SE_Layout::dol();
  267. }
  268. } else {
  269. SE_Layout::gora();
  270. SE_Layout::menu();
  271. ?>
  272. <div class="container" style="margin-top:20px">
  273. <form class="form-horizontal" method="post" target="_blank">
  274. <legend>
  275. Podgląd deklaracji JPK :: <?=$this->JPK['TYPE']?> - <?=$this->JPK['MONTH']." (".($this->JPK['PURPOSE'] == 1 ? "pierwsze złożenie" : "korekta").")"?>
  276. <span class="pull-right">
  277. <?=$this->BO['name1']?>
  278. </span>
  279. </legend>
  280. <div class="form-group">
  281. <div class="form-group">
  282. <div class="col-sm-10">
  283. <button type="submit" class="btn-sm btn-primary" name="action" value="getJPK">Pobierz plik JPK</button>
  284. </div>
  285. </div>
  286. <?=$this->showTable();?>
  287. <div class="form-group" style="text-align:center">
  288. <div class="col-sm-12">
  289. <input type="hidden" name="REFERER" value="<?=$this->REFERER?>"/>
  290. <a href="<?=$this->REFERER?>" class="btn btn-default">Powrót</a>
  291. </div>
  292. </div>
  293. </form>
  294. </div>
  295. <?php
  296. SE_Layout::dol();
  297. }
  298. }
  299. private function edit() {
  300. SE_Layout::gora();
  301. SE_Layout::menu();
  302. ?>
  303. <div class="container" style="margin-top:20px">
  304. <form class="form-horizontal" method="post" enctype="multipart/form-data">
  305. <legend>
  306. Edycja deklaracji JPK :: <?=$this->JPK['TYPE']?> - <?=$this->JPK['MONTH']." (".($this->JPK['PURPOSE'] == 1 ? "pierwsze złożenie" : "korekta").")"?>
  307. <span class="pull-right">
  308. <?=$this->BO['name1']?>
  309. </span>
  310. </legend>
  311. <div class="form-group">
  312. <label class="col-sm-3 control-label"><?=($this->JPK['IN_INSERT'] ? "Usuń dane zaimportowane" : "Dodaj plik JPK")?> z pakietu Insert</label>
  313. <?php
  314. if ($this->JPK['IN_INSERT']) {
  315. ?>
  316. <div class="col-sm-9" style="margin-top:3px;">
  317. <button type="submit" class="btn-xs btn-default" name="action" value="delete_insert_jpk">Usuń</button>
  318. </div>
  319. <?php
  320. } else {
  321. ?>
  322. <div class="col-sm-9" style="margin-top:7px;">
  323. <input type="hidden" name="action" value="upload_insert_jpk"/>
  324. <input type="file" name="IN_INSERT" onchange="javascript:this.form.submit();"/>
  325. </div>
  326. <?php
  327. }
  328. ?>
  329. </div>
  330. <div class="form-group">
  331. <label class="col-sm-3 control-label"><?=($this->JPK['IN_L1'] ? "Usuń" : "Pobierz")?> dane z L1</label>
  332. <div class="col-sm-9" style="margin-top:3px;">
  333. <button type="submit" class="btn-xs btn-default" name="action" value=<?=($this->JPK['IN_L1'] ? '"delete_l1_jpk">Usuń' : '"import_l1_jpk">Pobierz')?></button>
  334. </div>
  335. </div>
  336. <?php
  337. if (!($this->JPK['IN_INSERT'] || $this->JPK['IN_L1'])) {
  338. ?>
  339. <div class="form-group">
  340. <label class="col-sm-3 control-label">Reinicjalizuj deklarację</label>
  341. <div class="col-sm-9" style="margin-top:3px;">
  342. <button type="submit" class="btn-xs btn-default" name="action" value="reinitialize">Reinicjalizuj</button>
  343. </div>
  344. </div>
  345. <?php
  346. }
  347. if ($this->JPK['IN_INSERT'] && $this->JPK['IN_L1'] && (!$this->JPK['OUT_MERGED'])) {
  348. ?>
  349. <div class="form-group">
  350. <label class="col-sm-3 control-label">Importuj dane podmiotu z</label>
  351. <div class="col-sm-9" style="margin-top:3px;">
  352. <input type="radio" name="SRC_PODMIOT" value="Insert" checked> Insert<br/>
  353. <input type="radio" name="SRC_PODMIOT" value="L1"> L1
  354. </div>
  355. </div>
  356. <div class="form-group">
  357. <label class="col-sm-3 control-label">Generuj deklarację wynikową</label>
  358. <div class="col-sm-9" style="margin-top:3px;">
  359. <button type="submit" class="btn-xs btn-default" name="action" value="generate_merged_jpk">Generuj</button>
  360. </div>
  361. </div>
  362. <?php
  363. }
  364. if ($this->JPK['OUT_MERGED']) {
  365. ?>
  366. <div class="form-group">
  367. <label class="col-sm-3 control-label">Zamknij deklarację JPK</label>
  368. <div class="col-sm-9" style="margin-top:3px;">
  369. <button type="submit" class="btn-xs btn-default" name="action" value="close_jpk">Zamknij</button>
  370. <p class="help-block">(tej operacji nie można cofnąć)</p>
  371. </div>
  372. </div>
  373. <?php
  374. }
  375. ?>
  376. <?=$this->showTable()?>
  377. <div class="form-group" style="text-align:center">
  378. <div class="col-sm-12">
  379. <input type="hidden" name="REFERER" value="<?=$this->REFERER?>"/>
  380. <input type="hidden" name="_task" value="edit">
  381. <a href="<?=$this->REFERER?>" class="btn btn-primary">Powrót</a>
  382. </div>
  383. </div>
  384. </form>
  385. </div>
  386. <?php
  387. SE_Layout::dol();
  388. }
  389. public function editAction() {
  390. $allowedActions = array("upload_insert_jpk", "delete_insert_jpk", "import_l1_jpk", "delete_l1_jpk", "generate_merged_jpk", "close_jpk", "reinitialize");
  391. if (in_array(($action = V::get('action','',$_POST)), $allowedActions)) $this->$action();
  392. else {
  393. SE_Layout::gora();
  394. SE_Layout::menu();
  395. SE_Layout::alert('danger', "Wykryto abuse! Wysłano informację do administratora.");
  396. ?>
  397. <div class="container" style="text-align:center">
  398. <form method="post" action="<?=$this->LAST_REFERER?>">
  399. <input type="hidden" name="REFERER" value="<?=$this->REFERER?>"/>
  400. <button type="submit" class="btn btn-primary">Powrót</button>
  401. </form>
  402. </div>
  403. <?php
  404. SE_Layout::dol();
  405. }
  406. }
  407. private function getSummaryJPK_VAT($xml) {
  408. $PodatekNaleznyFields = array("K_16" => "1", "K_18" => "1", "K_20" => "1", "K_24" => "1", "K_26" => "1", "K_28" => "1",
  409. "K_30" => "1", "K_33" => "1", "K_35" => "1", "K_36" => "1", "K_37" => "1", "K_38" => "-1", "K_39" => "-1");
  410. $PodatekNaliczonyFields = array("K_44" => 1, "K_46" => 1, "K_47" => 1, "K_48" => 1, "K_49" => 1, "K_50" => 1);
  411. $result = array(
  412. "LiczbaWierszySprzedazy" => 0,
  413. "PodatekNalezny" => 0,
  414. "LiczbaWierszyZakupow" => 0,
  415. "PodatekNaliczony" => 0);
  416. foreach ($xml->SprzedazWiersz as $SprzedazWiersz) {
  417. foreach ($PodatekNaleznyFields as $PodatekNaleznyField => $sign) {
  418. if (isset($SprzedazWiersz->$PodatekNaleznyField)) {
  419. $result["PodatekNalezny"] += round((float) $SprzedazWiersz->$PodatekNaleznyField * $sign, 2);
  420. }
  421. }
  422. $result["LiczbaWierszySprzedazy"]++;
  423. }
  424. foreach ($xml->ZakupWiersz as $ZakupWiersz) {
  425. foreach ($PodatekNaliczonyFields as $PodatekNaliczonyField => $sign) {
  426. if (isset($ZakupWiersz->$PodatekNaliczonyField)) {
  427. $result["PodatekNaliczony"] += round((float) $ZakupWiersz->$PodatekNaliczonyField * $sign, 2);
  428. }
  429. }
  430. $result["LiczbaWierszyZakupow"]++;
  431. }
  432. $result["PodatekNalezny"] = round($result["PodatekNalezny"], 2);
  433. $result["PodatekNaliczony"] = round($result["PodatekNaliczony"], 2);
  434. return $result;
  435. }
  436. private function validateJPK_VAT(&$xml) {
  437. $ns = $xml->getNamespaces(true);
  438. if ($xml->Naglowek->KodFormularza != "JPK_VAT") throw new Exception("Błędny typ deklaracji JPK");
  439. if ($xml->Naglowek->WariantFormularza != "2") throw new Exception("Błędna wersja deklaracji JPK");
  440. if ($xml->Naglowek->CelZlozenia != $this->JPK['PURPOSE']) throw new Exception("Niezgodny cel złożenia deklaracji JPK");
  441. if ($xml->Naglowek->DataOd != ($this->JPK['MONTH'] . "-01")) throw new Exception("Błędna data 'od' deklaracji JPK");
  442. if ($xml->Naglowek->DataDo != date("Y-m-d", strtotime($xml->Naglowek->DataOd . "+ 1 month - 1 day"))) throw new Exception("Błędna data 'do' deklaracji JPK");
  443. if ($xml->Naglowek->DomyslnyKodWaluty != "PLN") throw new Exception("Błędna waluta deklaracji JPK");
  444. if (trim(str_replace('-', '', $xml->Podmiot1->IdentyfikatorPodmiotu->children($ns['etd'])->NIP)) != trim(str_replace('-', '', $this->BO['nip']))) throw new Exception("Niezgodny NIP podmiotu w deklaracji JPK");
  445. $summaryJPK_VAT = $this->getSummaryJPK_VAT($xml);
  446. if ($summaryJPK_VAT["LiczbaWierszySprzedazy"]) {
  447. if ($xml->SprzedazCtrl->LiczbaWierszySprzedazy != $summaryJPK_VAT["LiczbaWierszySprzedazy"]) throw new Exception("Brak spójności liczby wierszy sprzedaży w deklaracji JPK");
  448. if (((float) $xml->SprzedazCtrl->PodatekNalezny) != $summaryJPK_VAT["PodatekNalezny"]) throw new Exception("Brak spójności wartości podatku należnego w deklaracji JPK");
  449. }
  450. if ($summaryJPK_VAT["LiczbaWierszyZakupow"]) {
  451. if ($xml->ZakupCtrl->LiczbaWierszyZakupow != $summaryJPK_VAT["LiczbaWierszyZakupow"]) throw new Exception("Brak spójności liczby wierszy zakupów w deklaracji JPK");
  452. if (((float) $xml->ZakupCtrl->PodatekNaliczony) != $summaryJPK_VAT["PodatekNaliczony"]) throw new Exception("Brak spójności wartości podatku naliczonego w deklaracji JPK");
  453. }
  454. function HandleXmlError($errno, $errstr, $errfile, $errline) {
  455. if ($errno==E_WARNING && (substr_count($errstr,"DOMDocument::loadXML()")>0)) throw new DOMException($errstr);
  456. else return false;
  457. }
  458. set_error_handler('HandleXmlError');
  459. try {
  460. $dom = new DOMDocument();
  461. $dom->preserveWhiteSpace = false;
  462. $dom->formatOutput = true;
  463. $dom->loadXML($xml->asXML());
  464. } catch (Exception $e) {
  465. throw new Exception("Błąd parsowania pliku JPK");
  466. }
  467. restore_error_handler();
  468. libxml_use_internal_errors(true);
  469. if (!$dom->schemaValidate(APP_PATH_SCHEMA . "/jpk/Schemat_JPK_VAT(2)_v1-0.xsd")) {
  470. $errors = '';
  471. foreach (libxml_get_errors() as $libxml_error) $errors .= "<br/>{$libxml_error->message}";
  472. throw new Exception("Plik JPK niezgodny ze schematem XSD{$errors}");
  473. }
  474. $xml = simplexml_load_string($dom->saveXML());
  475. }
  476. private function upload_insert_jpk() {
  477. try {
  478. if ($_FILES['IN_INSERT']['type'] != "text/xml") throw new Exception("Błędny plik JPK");
  479. $xml = simplexml_load_file($_FILES['IN_INSERT']['tmp_name']);
  480. $this->validateJPK_VAT($xml);
  481. if ($this->JPK['IN_L1']) $info = "Zaimportowano dane z Insert i L1";
  482. else $info = "Zaimportowano dane z Insert";
  483. $sqlObj = new stdClass();
  484. $sqlObj->ID = $this->JPK['ID'];
  485. $sqlObj->A_STATUS_INFO = $info;
  486. $sqlObj->IN_INSERT = $xml->asXml();
  487. if (!$affected = DB::getDB()->UPDATE_OBJ('JPK', $sqlObj)) throw new Exception("Wystąpił błąd, prawdopodobnie Ten plik JPK został wgrany już wcześniej");
  488. $this->handleAuth();
  489. $this->edit();
  490. } catch (Exception $e) {
  491. SE_Layout::gora();
  492. SE_Layout::menu();
  493. SE_Layout::alert('danger', $e->getMessage());
  494. ?>
  495. <div class="container" style="text-align:center">
  496. <form method="post" action="<?=$this->LAST_REFERER?>">
  497. <input type="hidden" name="REFERER" value="<?=$this->REFERER?>"/>
  498. <button type="submit" class="btn btn-primary">Powrót</button>
  499. </form>
  500. </div>
  501. <?php
  502. SE_Layout::dol();
  503. }
  504. }
  505. private function delete_insert_jpk() {
  506. try {
  507. $info = "Usunięto dane z Insert";
  508. if ($this->JPK['IN_L1']) $info .= " (pozostawiono dane z L1)";
  509. $sqlObj = new stdClass();
  510. $sqlObj->ID = $this->JPK['ID'];
  511. $sqlObj->A_STATUS_INFO = $info;
  512. $sqlObj->IN_INSERT = null;
  513. $sqlObj->OUT_MERGED = null;
  514. if (!$affected = DB::getDB()->UPDATE_OBJ('JPK', $sqlObj)) throw new Exception("Wystąpił nieznany błąd");
  515. $this->handleAuth();
  516. $this->edit();
  517. } catch (Exception $e) {
  518. SE_Layout::gora();
  519. SE_Layout::menu();
  520. SE_Layout::alert('danger', $e->getMessage());
  521. ?>
  522. <div class="container" style="text-align:center">
  523. <form method="post" action="<?=$this->LAST_REFERER?>">
  524. <input type="hidden" name="REFERER" value="<?=$this->REFERER?>"/>
  525. <button type="submit" class="btn btn-primary">Powrót</button>
  526. </form>
  527. </div>
  528. <?php
  529. SE_Layout::dol();
  530. }
  531. }
  532. private function import_l1_jpk() {
  533. $xmlSchema = <<<EOT
  534. <?xml version="1.0" encoding="UTF-8" standalone="no" ?>
  535. <JPK xmlns="http://jpk.mf.gov.pl/wzor/2016/10/26/10261/" xmlns:etd="http://crd.gov.pl/xml/schematy/dziedzinowe/mf/2016/01/25/eD/DefinicjeTypy/" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance">
  536. <Naglowek>
  537. <KodFormularza kodSystemowy="JPK_VAT (2)" wersjaSchemy="1-0">JPK_VAT</KodFormularza>
  538. <WariantFormularza>2</WariantFormularza>
  539. <CelZlozenia></CelZlozenia>
  540. <DataWytworzeniaJPK></DataWytworzeniaJPK>
  541. <DataOd></DataOd>
  542. <DataDo></DataDo>
  543. <DomyslnyKodWaluty>PLN</DomyslnyKodWaluty>
  544. <KodUrzedu></KodUrzedu>
  545. </Naglowek>
  546. <Podmiot1>
  547. <IdentyfikatorPodmiotu>
  548. <etd:NIP></etd:NIP>
  549. <etd:PelnaNazwa></etd:PelnaNazwa>
  550. <etd:REGON></etd:REGON>
  551. </IdentyfikatorPodmiotu>
  552. <AdresPodmiotu>
  553. <KodKraju></KodKraju>
  554. <Wojewodztwo></Wojewodztwo>
  555. <Powiat></Powiat>
  556. <Gmina></Gmina>
  557. <Ulica></Ulica>
  558. <NrDomu></NrDomu>
  559. <NrLokalu></NrLokalu>
  560. <Miejscowosc></Miejscowosc>
  561. <KodPocztowy></KodPocztowy>
  562. <Poczta></Poczta>
  563. </AdresPodmiotu>
  564. </Podmiot1>
  565. </JPK>
  566. EOT;
  567. $queryFVAT = <<<EOT
  568. select
  569. bn.ID as BN_ID,
  570. concat(bua.P_NAME, if(bua.P_NAME_SECOND='','',concat(' ',bua.P_NAME_SECOND))) AS NazwaKontrahenta,
  571. concat(bua.P_ADDRESS_STREET,' ',bua.P_ADDRESS_HOUSE, if(bua.P_ADDRESS_HOME='','',concat('/',bua.P_ADDRESS_HOME)),', ',P_ADDRESS_POST_CODE,' ',P_ADDRESS_CITY) AS AdresKontrahenta,
  572. bf.SELL_DATE AS 'DataWystawienia',
  573. concat(bn.NUMBER,'/',bn.ID_BILLING_PREFIXES) AS 'DowodSprzedazy',
  574. if(coalesce(bua.P_NIP,'')='','brak',coalesce(bua.P_NIP,'')) AS 'NrKontrahenta',
  575. round(bfp.AMMOUNT * bfp.PRICE, 2) as Netto,
  576. round(round(bfp.AMMOUNT * bfp.PRICE, 2) * bfp.VAT/100, 2) as VAT,
  577. bfp.VAT_NAME as 'VAT_NAME'
  578. from BILLING_NUMBERS bn
  579. join BILLS_FVAT bf on bn.ID=bf.ID_BILLING_NUMBERS
  580. join BILLS_FVAT_POS bfp on bf.ID=bfp.ID_BILLS_FVAT
  581. join BILLING_USERS_ADD bua on bua.id_users=bn.ID_BILLING_USERS
  582. join BILLING_USERS bu on bu.ID=bn.ID_BILLING_USERS
  583. where bn.ID_BILLING_NUMBERS_TYPE='1' and bf.BILL_DATE like '{$this->JPK['MONTH']}%'
  584. and bu.BILLING_OWNER='{$this->BO['ID']}'
  585. order by bf.BILL_DATE,bn.ID
  586. EOT;
  587. $queryKORV = <<<EOT
  588. select
  589. bn.ID AS BN_ID,
  590. concat(bua.P_NAME, if(bua.P_NAME_SECOND='','',concat(' ',bua.P_NAME_SECOND))) AS NazwaKontrahenta,
  591. concat(bua.P_ADDRESS_STREET,' ',bua.P_ADDRESS_HOUSE, if(bua.P_ADDRESS_HOME='','',concat('/',bua.P_ADDRESS_HOME)),', ',P_ADDRESS_POST_CODE,' ',P_ADDRESS_CITY) AS AdresKontrahenta,
  592. bk.BILL_DATE AS 'DataWystawienia',
  593. bk.SELL_DATE AS 'DataSprzedazy',
  594. concat(bn.NUMBER,'/',bn.ID_BILLING_PREFIXES) AS 'DowodSprzedazy',
  595. if(coalesce(bua.P_NIP,'')='','brak',coalesce(bua.P_NIP,'')) AS 'NrKontrahenta',
  596. bkp.AMMOUNT AS AMMOUNT,
  597. bkp.PRICE AS PRICE,
  598. bkp.VAT AS VAT,
  599. bkp.VAT_NAME AS VAT_NAME,
  600. bkp.N_AMMOUNT AS N_AMMOUNT,
  601. bkp.N_PRICE AS N_PRICE,
  602. bkp.N_VAT AS N_VAT,
  603. bkp.N_VAT_NAME AS N_VAT_NAME,
  604. bkp.TYP_KOREKTY AS TYP_KOREKTY
  605. from BILLING_NUMBERS bn
  606. join BILLS_KORV bk on bn.ID=bk.ID_BILLING_NUMBERS
  607. join BILLS_KORV_POS bkp on bk.ID=bkp.ID_BILLS_FVAT
  608. join BILLING_USERS_ADD bua on bua.id_users=bn.ID_BILLING_USERS
  609. join BILLING_USERS bu on bu.ID=bn.ID_BILLING_USERS
  610. where bn.ID_BILLING_NUMBERS_TYPE='3'
  611. and bk.BILL_DATE like '{$this->JPK['MONTH']}%'
  612. and bkp.TYP_KOREKTY IS NOT NULL
  613. and bu.BILLING_OWNER='{$this->BO['ID']}'
  614. order by bk.BILL_DATE,bn.ID
  615. EOT;
  616. $xmlVAT = array(
  617. 'ZW' => array('netto' => 'K_10', 'vat' => ''),
  618. '0' => array('netto' => 'K_13', 'vat' => ''),
  619. '7' => array('netto' => 'K_17', 'vat' => 'K_18'),
  620. '8' => array('netto' => 'K_17', 'vat' => 'K_18'),
  621. '22' => array('netto' => 'K_19', 'vat' => 'K_20'),
  622. '23' => array('netto' => 'K_19', 'vat' => 'K_20')
  623. );
  624. try {
  625. if (DB::getPDO(931)->fetchValue("select sum(c) from (select count(*) as c from BILLS_FVAT where OPEN='y' union select count(*) as c from BILLS_KORV where OPEN='y') as c;")) {
  626. throw new Exception("wykryto niezamknięte faktury lub korekty faktur");
  627. }
  628. $xml = new SimpleXMLElement($xmlSchema);
  629. $ns = $xml->getNamespaces(true);
  630. $xml->Naglowek->CelZlozenia = $this->JPK['PURPOSE'];
  631. $xml->Naglowek->DataWytworzeniaJPK = date("Y-m-d\TH:i:s");
  632. $xml->Naglowek->DataOd = $this->JPK['MONTH'] . "-01";
  633. $xml->Naglowek->DataDo = date("Y-m-d", strtotime($xml->Naglowek->DataOd . "+ 1 month - 1 day"));
  634. if (!($xml->Naglowek->KodUrzedu = $this->BO['kodUrzeduSkarbowego'])) throw new Exception("blędne dane podmiotu - brak kodu urzędu skarbowego");
  635. if (!($xml->Podmiot1->IdentyfikatorPodmiotu->children($ns['etd'])->NIP = trim(str_replace("-", "", $this->BO['nip'])))) throw new Exception("blędne dane podmiotu - brak NIP");
  636. if (!($xml->Podmiot1->IdentyfikatorPodmiotu->children($ns['etd'])->PelnaNazwa = $this->BO['name1'])) throw new Exception("blędne dane podmiotu - brak nazwy podmiotu");
  637. if ($this->BO['name2']) $xml->Podmiot1->IdentyfikatorPodmiotu->children($ns['etd'])->PelnaNazwa .= " " . $this->BO['name2'];
  638. if (!($xml->Podmiot1->IdentyfikatorPodmiotu->children($ns['etd'])->REGON = $this->BO['regon'])) unset($xml->Podmiot1->IdentyfikatorPodmiotu->children($ns['etd'])->REGON);
  639. if (!($xml->Podmiot1->AdresPodmiotu->KodKraju = $this->BO['kodKraju'])) throw new Exception("blędne dane podmiotu - brak kodu kraju");
  640. if (!($xml->Podmiot1->AdresPodmiotu->Wojewodztwo = $this->BO['wojewodztwo'])) unset($xml->Podmiot1->AdresPodmiotu->Wojewodztwo);
  641. if (!($xml->Podmiot1->AdresPodmiotu->Powiat = $this->BO['powiat'])) unset($xml->Podmiot1->AdresPodmiotu->Powiat);
  642. if (!($xml->Podmiot1->AdresPodmiotu->Gmina = $this->BO['gmina'])) unset($xml->Podmiot1->AdresPodmiotu->Gmina);
  643. if (!($xml->Podmiot1->AdresPodmiotu->Ulica = $this->BO['ulica'])) unset($xml->Podmiot1->AdresPodmiotu->Ulica);
  644. if (!($xml->Podmiot1->AdresPodmiotu->NrDomu = $this->BO['numer_dom'])) unset($xml->Podmiot1->AdresPodmiotu->NrDomu);
  645. if (!($xml->Podmiot1->AdresPodmiotu->NrLokalu = $this->BO['numer_pos'])) unset($xml->Podmiot1->AdresPodmiotu->NrLokalu);
  646. if (!($xml->Podmiot1->AdresPodmiotu->Miejscowosc = $this->BO['miasto'])) throw new Exception("blędne dane podmiotu - brak nazwy miejscowości");
  647. if (!($xml->Podmiot1->AdresPodmiotu->KodPocztowy = $this->BO['kod'])) unset($xml->Podmiot1->AdresPodmiotu->KodPocztowy);
  648. if (!($xml->Podmiot1->AdresPodmiotu->Poczta = $this->BO['poczta'])) unset($xml->Podmiot1->AdresPodmiotu->Poczta);
  649. $data = array();
  650. $allVAT = 0;
  651. $result = DB::getPDO(931)->fetchall($queryFVAT);
  652. foreach ($result as $row) {
  653. $data[$row['BN_ID']][0]['NrKontrahenta'] = $row['NrKontrahenta'];
  654. $data[$row['BN_ID']][0]['NazwaKontrahenta'] = $row['NazwaKontrahenta'];
  655. $data[$row['BN_ID']][0]['AdresKontrahenta'] = $row['AdresKontrahenta'];
  656. $data[$row['BN_ID']][0]['DowodSprzedazy'] = $row['DowodSprzedazy'];
  657. $data[$row['BN_ID']][0]['DataWystawienia'] = $row['DataWystawienia'];
  658. if (!in_array($row['VAT_NAME'],array_keys($xmlVAT))) throw new Exception("Problem ze stawką VAT (1)");
  659. $data[$row['BN_ID']][1][$xmlVAT[$row['VAT_NAME']]['netto']] += $row['Netto'];
  660. if ($row['VAT']) {
  661. if (!$xmlVAT[$row['VAT_NAME']]['vat']) throw new Exception("Problem ze stawką VAT (2)");
  662. $data[$row['BN_ID']][1][$xmlVAT[$row['VAT_NAME']]['vat']] += $row['VAT'];
  663. $allVAT += $row['VAT'];
  664. }
  665. }
  666. $result = DB::getPDO(931)->fetchall($queryKORV);
  667. foreach ($result as $row) {
  668. $data[$row['BN_ID']][0]['NrKontrahenta'] = $row['NrKontrahenta'];
  669. $data[$row['BN_ID']][0]['NazwaKontrahenta'] = $row['NazwaKontrahenta'];
  670. $data[$row['BN_ID']][0]['AdresKontrahenta'] = $row['AdresKontrahenta'];
  671. $data[$row['BN_ID']][0]['DowodSprzedazy'] = $row['DowodSprzedazy'];
  672. $data[$row['BN_ID']][0]['DataWystawienia'] = $row['DataWystawienia'];
  673. $data[$row['BN_ID']][0]['DataSprzedazy'] = $row['DataSprzedazy'];
  674. if (!(in_array($row['VAT_NAME'], array_keys($xmlVAT)) && in_array($row['N_VAT_NAME'], array_keys($xmlVAT)))) throw new Exception("Problem ze stawką VAT (1)");
  675. if (($row['VAT'] && !($xmlVAT[$row['VAT_NAME']]['vat'])) || ($row['N_VAT'] && !($xmlVAT[$row['N_VAT_NAME']]['vat']))) throw new Exception("Problem ze stawką VAT (2)");
  676. if ($row['VAT_NAME'] == $row['N_VAT_NAME']) {
  677. $data[$row['BN_ID']][1][$xmlVAT[$row['VAT_NAME']]['netto']] += round($row['AMMOUNT']*$row['PRICE'],2);
  678. if ($row['VAT']) {
  679. $data[$row['BN_ID']][1][$xmlVAT[$row['VAT_NAME']]['vat']] += round(round($row['AMMOUNT']*$row['PRICE'],2)*$row['VAT']/100,2);
  680. $allVAT += round(round($row['AMMOUNT']*$row['PRICE'],2)*$row['VAT']/100,2);
  681. }
  682. } else {
  683. $data[$row['BN_ID']][1][$xmlVAT[$row['VAT_NAME']]['netto']] += round($row['N_AMMOUNT']*$row['N_PRICE'],2) + round($row['AMMOUNT']*$row['PRICE'],2);
  684. $data[$row['BN_ID']][1][$xmlVAT[$row['N_VAT_NAME']]['netto']] -= round($row['N_AMMOUNT']*$row['N_PRICE'],2);
  685. if ($row['VAT']) {
  686. $data[$row['BN_ID']][1][$xmlVAT[$row['VAT_NAME']]['vat']] += round(round($row['N_AMMOUNT']*$row['N_PRICE'],2)*$row['VAT']/100,2)
  687. + round(round($row['AMMOUNT']*$row['PRICE'],2)*$row['VAT']/100,2);
  688. $allVAT += round(round($row['N_AMMOUNT']*$row['N_PRICE'],2)*$row['VAT']/100,2) + round(round($row['AMMOUNT']*$row['PRICE'],2)*$row['VAT']/100,2);
  689. }
  690. if ($row['N_VAT']) {
  691. $data[$row['BN_ID']][1][$xmlVAT[$row['N_VAT_NAME']]['vat']] -= round(round($row['N_AMMOUNT']*$row['N_PRICE'],2)*$row['N_VAT']/100,2);
  692. $allVAT -= round(round($row['N_AMMOUNT']*$row['N_PRICE'],2)*$row['N_VAT']/100,2);
  693. }
  694. }
  695. }
  696. ksort($data);
  697. function addCdata(&$node, $value) {
  698. $dom_node = dom_import_simplexml($node);
  699. $dom_owner = $dom_node->ownerDocument;
  700. $dom_node->appendChild($dom_owner->createCDATASection($value));
  701. }
  702. $i = 0;
  703. foreach ($data as $pos) {
  704. $x = $xml->addChild('SprzedazWiersz');
  705. $x->addAttribute('typ', 'G');
  706. $x->addChild('LpSprzedazy', ++$i);
  707. ksort($pos[1]);
  708. foreach ($pos as $subpos) foreach ($subpos as $key => $value) {
  709. $x->addChild($key, $value);
  710. if (!strlen($x->$key)) addCdata($x->$key, $value);
  711. }
  712. }
  713. $xml->SprzedazCtrl->LiczbaWierszySprzedazy = count($data);
  714. $xml->SprzedazCtrl->PodatekNalezny = $allVAT;
  715. $this->validateJPK_VAT($xml);
  716. if ($this->JPK['IN_INSERT']) $info = "Zaimportowano dane z Insert i L1";
  717. else $info = "Zaimportowano dane z L1";
  718. $sqlObj = new stdClass();
  719. $sqlObj->ID = $this->JPK['ID'];
  720. $sqlObj->A_STATUS_INFO = $info;
  721. $sqlObj->IN_L1 = $xml->asXml();
  722. if (!$affected = DB::getDB()->UPDATE_OBJ('JPK', $sqlObj)) throw new Exception("Wystąpił nieznany błąd bazy danych");
  723. $this->handleAuth();
  724. $this->edit();
  725. } catch (Exception $e) {
  726. SE_Layout::gora();
  727. SE_Layout::menu();
  728. SE_Layout::alert('danger', "Błąd w trakcie importu danych z L1. {$e->getMessage()}");
  729. ?>
  730. <div class="container" style="text-align:center">
  731. <form method="post" action="<?=$this->LAST_REFERER?>">
  732. <input type="hidden" name="REFERER" value="<?=$this->REFERER?>"/>
  733. <button type="submit" class="btn btn-primary">Powrót</button>
  734. </form>
  735. </div>
  736. <?php
  737. SE_Layout::dol();
  738. }
  739. }
  740. private function delete_l1_jpk() {
  741. try {
  742. $info = "Usunięto dane z L1";
  743. if ($this->JPK['IN_INSERT']) $info .= " (pozostawiono dane z Insert)";
  744. $sqlObj = new stdClass();
  745. $sqlObj->ID = $this->JPK['ID'];
  746. $sqlObj->A_STATUS_INFO = $info;
  747. $sqlObj->IN_L1 = null;
  748. $sqlObj->OUT_MERGED = null;
  749. if (!$affected = DB::getDB()->UPDATE_OBJ('JPK', $sqlObj)) throw new Exception("Wystąpił nieznany błąd");
  750. $this->handleAuth();
  751. $this->edit();
  752. } catch (Exception $e) {
  753. SE_Layout::gora();
  754. SE_Layout::menu();
  755. SE_Layout::alert('danger', $e->getMessage());
  756. ?>
  757. <div class="container" style="text-align:center">
  758. <form method="post" action="<?=$this->LAST_REFERER?>">
  759. <input type="hidden" name="REFERER" value="<?=$this->REFERER?>"/>
  760. <button type="submit" class="btn btn-primary">Powrót</button>
  761. </form>
  762. </div>
  763. <?php
  764. SE_Layout::dol();
  765. }
  766. }
  767. private function generate_merged_jpk() {
  768. $xmlSchema = <<<EOT
  769. <?xml version="1.0" encoding="UTF-8" standalone="no"?>
  770. <JPK xmlns="http://jpk.mf.gov.pl/wzor/2016/10/26/10261/" xmlns:etd="http://crd.gov.pl/xml/schematy/dziedzinowe/mf/2016/01/25/eD/DefinicjeTypy/" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance">
  771. </JPK>
  772. EOT;
  773. function xml_append(SimpleXMLElement $to, SimpleXMLElement $from) {
  774. $toDom = dom_import_simplexml($to);
  775. $fromDom = dom_import_simplexml($from);
  776. $toDom->appendChild($toDom->ownerDocument->importNode($fromDom, true));
  777. }
  778. try {
  779. if (!($this->JPK['IN_INSERT'] && $this->JPK['IN_L1'])) throw new Exception("Błąd danych");
  780. $xmlInsert = simplexml_load_string($this->JPK['IN_INSERT']);
  781. $xmlL1 = simplexml_load_string($this->JPK['IN_L1']);
  782. $xml = simplexml_load_string($xmlSchema);
  783. switch (V::get('SRC_PODMIOT','',$_POST)) {
  784. case "Insert":
  785. xml_append($xml, $xmlInsert->Naglowek);
  786. xml_append($xml, $xmlInsert->Podmiot1);
  787. break;
  788. case "L1":
  789. xml_append($xml, $xmlL1->Naglowek);
  790. xml_append($xml, $xmlL1->Podmiot1);
  791. break;
  792. default:
  793. throw new Exception("Błąd formularza");
  794. }
  795. $xml->Naglowek->DataWytworzeniaJPK = date("Y-m-d\TH:i:s");
  796. $i = 0;
  797. foreach ($xmlInsert->SprzedazWiersz as $sprzedazWiersz) {
  798. $sprzedazWiersz->LpSprzedazy = ++$i;
  799. xml_append($xml, $sprzedazWiersz);
  800. }
  801. foreach ($xmlL1->SprzedazWiersz as $sprzedazWiersz) {
  802. $sprzedazWiersz->LpSprzedazy = ++$i;
  803. xml_append($xml, $sprzedazWiersz);
  804. }
  805. $xml->addChild("SprzedazCtrl");
  806. $i = 0;
  807. foreach ($xmlInsert->ZakupWiersz as $zakupWiersz) {
  808. $zakupWiersz->LpZakupu = ++$i;
  809. xml_append($xml, $zakupWiersz);
  810. }
  811. foreach ($xmlL1->ZakupWiersz as $zakupWiersz) {
  812. $zakupWiersz->LpZakupu = ++$i;
  813. xml_append($xml, $zakupWiersz);
  814. }
  815. $xml->addChild("ZakupCtrl");
  816. $sumaryJPK_VAT = $this->getSummaryJPK_VAT($xml);
  817. $xml->SprzedazCtrl->LiczbaWierszySprzedazy = $sumaryJPK_VAT['LiczbaWierszySprzedazy'];
  818. $xml->SprzedazCtrl->PodatekNalezny = $sumaryJPK_VAT['PodatekNalezny'];
  819. $xml->ZakupCtrl->LiczbaWierszyZakupow = $sumaryJPK_VAT['LiczbaWierszyZakupow'];
  820. $xml->ZakupCtrl->PodatekNaliczony = $sumaryJPK_VAT['PodatekNaliczony'];
  821. $this->validateJPK_VAT($xml);
  822. $sqlObj = new stdClass();
  823. $sqlObj->ID = $this->JPK['ID'];
  824. $sqlObj->A_STATUS_INFO = "Wygenerowano wynikowy plik JPK";
  825. $sqlObj->OUT_MERGED = $xml->asXml();
  826. if (!$affected = DB::getDB()->UPDATE_OBJ('JPK', $sqlObj)) throw new Exception("Wystąpił nieznany błąd bazy danych");
  827. $this->handleAuth();
  828. $this->edit();
  829. } catch (Exception $e) {
  830. SE_Layout::gora();
  831. SE_Layout::menu();
  832. SE_Layout::alert('danger', $e->getMessage());
  833. ?>
  834. <div class="container" style="text-align:center">
  835. <form method="post" action="<?=$this->LAST_REFERER?>">
  836. <input type="hidden" name="REFERER" value="<?=$this->REFERER?>"/>
  837. <button type="submit" class="btn btn-primary">Powrót</button>
  838. </form>
  839. </div>
  840. <?php
  841. SE_Layout::dol();
  842. }
  843. }
  844. private function close_jpk() {
  845. try {
  846. $sqlObj = new stdClass();
  847. $sqlObj->ID = $this->JPK['ID'];
  848. $sqlObj->A_STATUS = 'OFF_HARD';
  849. $sqlObj->A_STATUS_INFO = "Zamknięto deklarację JPK";
  850. if (!$affected = DB::getDB()->UPDATE_OBJ('JPK', $sqlObj)) throw new Exception("Wystąpił nieznany błąd bazy danych");
  851. $this->handleAuth();
  852. $this->show();
  853. } catch (Exception $e) {
  854. SE_Layout::gora();
  855. SE_Layout::menu();
  856. SE_Layout::alert('danger', $e->getMessage());
  857. ?>
  858. <div class="container" style="text-align:center">
  859. <form method="post" action="<?=$this->LAST_REFERER?>">
  860. <input type="hidden" name="REFERER" value="<?=$this->REFERER?>"/>
  861. <button type="submit" class="btn btn-primary">Powrót</button>
  862. </form>
  863. </div>
  864. <?php
  865. SE_Layout::dol();
  866. }
  867. }
  868. private function reinitialize() {
  869. $sqlObj = new stdClass();
  870. $sqlObj->ID = $this->JPK['ID'];
  871. $sqlObj->A_STATUS = 'WAITING';
  872. $sqlObj->A_STATUS_INFO = "Oczekuje na inicjalizację";
  873. $sqlObj->MONTH = "NULL";
  874. $sqlObj->PURPOSE = "NULL";
  875. DB::getDB()->UPDATE_OBJ('JPK', $sqlObj);
  876. $this->initialize();
  877. }
  878. public function defaultAction() {
  879. switch ($this->JPK['A_STATUS']) {
  880. case "WAITING":
  881. $this->initialize();
  882. break;
  883. case "NORMAL":
  884. $this->edit();
  885. break;
  886. case "OFF_HARD":
  887. $this->show();
  888. break;
  889. default:
  890. SE_Layout::alert('danger', "Błędny status rekordu.");
  891. }
  892. }
  893. }