1: 2: 3: 4: 5: 6: 7: 8: 9: 10: 11: 12: 13: 14: 15: 16: 17: 18: 19: 20: 21: 22: 23: 24: 25: 26: 27: 28: 29: 30: 31: 32: 33: 34: 35: 36: 37: 38: 39: 40: 41: 42: 43: 44: 45: 46: 47: 48: 49: 50: 51: 52: 53: 54: 55: 56: 57: 58: 59: 60: 61: 62: 63: 64: 65: 66: 67: 68: 69: 70: 71: 72: 73: 74: 75: 76: 77: 78: 79: 80: 81: 82: 83: 84: 85: 86: 87: 88: 89: 90: 91: 92: 93: 94: 95: 96: 97: 98: 99: 100: 101: 102: 103: 104: 105: 106: 107: 108: 109: 110: 111: 112: 113: 114: 115: 116: 117: 118: 119: 120: 121: 122: 123: 124: 125: 126: 127: 128: 129: 130: 131: 132: 133: 134: 135: 136: 137: 138: 139: 140: 141: 142: 143: 144: 145: 146: 147: 148: 149: 150: 151: 152: 153: 154: 155: 156: 157: 158: 159: 160: 161: 162: 163: 164: 165: 166: 167: 168: 169: 170: 171: 172: 173: 174: 175: 176: 177: 178: 179: 180: 181: 182: 183: 184: 185: 186: 187: 188: 189: 190: 191: 192: 193: 194: 195: 196: 197: 198: 199: 200: 201: 202: 203: 204: 205: 206: 207: 208: 209: 210: 211: 212: 213: 214: 215: 216: 217: 218: 219: 220: 221: 222: 223: 224: 225: 226: 227: 228: 229: 230: 231: 232: 233: 234: 235: 236: 237: 238: 239: 240: 241: 242: 243: 244: 245: 246: 247: 248: 249: 250: 251: 252: 253: 254: 255: 256: 257: 258: 259: 260: 261: 262: 263: 264: 265: 266: 267: 268: 269: 270: 271: 272: 273: 274: 275: 276: 277: 278: 279: 280: 281: 282: 283: 284: 285: 286: 287: 288: 289: 290: 291: 292: 293: 294: 295: 296: 297: 298: 299: 300: 301: 302: 303: 304: 305: 306: 307: 308: 309: 310: 311: 312: 313: 314: 315: 316: 317: 318: 319: 320: 321: 322: 323: 324: 325: 326: 327: 328: 329: 330: 331: 332: 333: 334: 335: 336: 337: 338: 339: 340: 341: 342: 343: 344: 345: 346: 347: 348: 349: 350: 351: 352: 353: 354: 355: 356: 357: 358: 359: 360: 361: 362: 363: 364: 365: 366: 367: 368: 369: 370: 371: 372: 373: 374: 375: 376: 377: 378: 379: 380: 381: 382: 383: 384: 385: 386: 387: 388: 389: 390: 391: 392: 393: 394: 395: 396: 397: 398: 399: 400: 401: 402: 403: 404: 405: 406: 407: 408: 409: 410: 411: 412: 413: 414: 415: 416: 417: 418: 419: 420: 421: 422: 423: 424: 425: 426: 427: 428: 429: 430: 431: 432: 433: 434: 435: 436: 437: 438: 439: 440: 441: 442: 443: 444: 445: 446: 447: 448: 449: 450: 451: 452: 453: 454: 455: 456: 457: 458: 459: 460: 461: 462: 463: 464: 465: 466: 467: 468: 469: 470: 471: 472: 473: 474: 475: 476: 477: 478: 479: 480: 481: 482: 483: 484: 485: 486: 487: 488: 489: 490: 491: 492: 493: 494: 495: 496: 497: 498: 499: 500: 501: 502: 503: 504: 505: 506: 507: 508: 509: 510: 511: 512: 513: 514: 515: 516: 517: 518: 519: 520: 521: 522: 523: 524: 525: 526: 527: 528: 529: 530: 531: 532: 533: 534: 535: 536: 537: 538: 539: 540: 541: 542: 543: 544: 545: 546: 547: 548: 549: 550: 551: 552: 553: 554: 555: 556: 557: 558: 559: 560: 561: 562: 563: 564: 565: 566: 567: 568: 569: 570: 571: 572: 573: 574: 575: 576: 577: 578: 579: 580: 581: 582: 583: 584: 585: 586: 587: 588: 589: 590: 591: 592: 593: 594: 595: 596: 597: 598: 599: 600: 601: 602: 603: 604: 605: 606: 607: 608: 609: 610: 611: 612: 613: 614: 615: 616: 617: 618: 619: 620: 621: 622: 623: 624: 625: 626: 627: 628: 629: 630: 631: 632: 633: 634: 635: 636: 637: 638: 639: 640: 641: 642: 643: 644: 645: 646: 647: 648: 649: 650: 651: 652: 653: 654: 655: 656: 657: 658: 659: 660: 661: 662: 663: 664: 665: 666: 667: 668: 669: 670: 671: 672: 673: 674: 675: 676: 677: 678: 679: 680: 681: 682: 683: 684: 685: 686: 687: 688: 689: 690: 691: 692: 693: 694: 695: 696: 697: 698: 699: 700: 701: 702: 703: 704: 705: 706: 707: 708: 709: 710: 711: 712: 713: 714: 715: 716: 717: 718: 719: 720: 721: 722: 723: 724: 725: 726: 727: 728: 729: 730: 731: 732: 733: 734: 735: 736: 737: 738: 739: 740: 741: 742: 743: 744: 745: 746: 747: 748: 749: 750: 751: 752: 753: 754: 755: 756: 757: 758: 759: 760: 761: 762: 763: 764: 765: 766: 767: 768: 769: 770: 771: 772: 773: 774: 775: 776: 777: 778: 779: 780: 781: 782: 783: 784: 785: 786: 787: 788: 789: 790: 791: 792: 793: 794: 795: 796: 797: 798: 799: 800: 801: 802: 803: 804: 805: 806: 807: 808: 809: 810: 811: 812: 813: 814: 815: 816: 817: 818: 819: 820: 821: 822: 823: 824: 825: 826: 827: 828: 829: 830: 831: 832: 833: 834: 835: 836: 837: 838: 839: 840: 841: 842: 843: 844: 845: 846: 847: 848: 849: 850: 851: 852: 853: 854: 855: 856: 857: 858: 859: 860: 861: 862: 863: 864: 865: 866: 867: 868: 869: 870: 871: 872: 873: 874: 875: 876: 877: 878: 879: 880: 881: 882: 883: 884: 885: 886: 887: 888: 889: 890: 891: 892: 893: 894: 895: 896: 897: 898: 899: 900: 901: 902: 903: 904: 905: 906: 907: 908: 909: 910: 911: 912: 913: 914: 915: 916: 917: 918: 919: 920: 921: 922: 923: 924: 925: 926: 927: 928: 929: 930: 931: 932: 933: 934: 935: 936: 937: 938: 939: 940: 941: 942: 943: 944: 945: 946: 947: 948: 949: 950: 951: 952: 953: 954: 955: 956: 957: 958: 959: 960: 961: 962: 963: 964: 965: 966: 967: 968: 969: 970: 971: 972: 973: 974: 975: 976: 977: 978: 979: 980: 981: 982: 983: 984: 985: 986: 987: 988: 989: 990: 991: 992: 993: 994: 995: 996: 997: 998: 999: 1000: 1001: 1002: 1003: 1004: 1005: 1006: 1007: 1008: 1009: 1010: 1011: 1012: 1013: 1014: 1015: 1016: 1017: 1018: 1019: 1020: 1021: 1022: 1023: 1024: 1025: 1026: 1027: 1028: 1029: 1030: 1031: 1032: 1033: 1034: 1035: 1036: 1037: 1038: 1039: 1040: 1041: 1042: 1043: 1044: 1045: 1046: 1047: 1048: 1049: 1050: 1051: 1052: 1053: 1054: 1055: 1056: 1057: 1058: 1059: 1060: 1061: 1062: 1063:
<?php
namespace FlexiPeeHP\Bricks;
class ParovacFaktur extends \Ease\Sand
{
private $invoicer;
public $banker;
public $daysBack = 1;
private $config = [];
public $cfgRequed = ["LABEL_PREPLATEK", "LABEL_CHYBIFAKTURA", "LABEL_NEIDENTIFIKOVANO"];
public function __construct($configuration = [])
{
$this->config = array_merge($this->config, $configuration);
foreach ($this->cfgRequed as $key) {
if ((array_key_exists($key, $this->config) === false) || empty($this->config[$key])) {
throw new \Ease\Exception(sprintf(_('Configuration key %s is not set'),
$key));
}
}
parent::__construct();
$this->banker = new \FlexiPeeHP\Banka(null, $this->config);
}
public function setStartDay($daysBack)
{
if (!is_null($daysBack)) {
$this->addStatusMessage('Start Date '.date('Y-m-d',
mktime(0, 0, 0, date("m"), date("d") - $daysBack, date("Y"))));
}
$this->daysBack = $daysBack;
}
public function getInvoicer()
{
if (!is_object($this->invoicer)) {
$this->invoicer = new \FlexiPeeHP\FakturaVydana(null, $this->config);
}
return $this->invoicer;
}
public function getPaymentsToProcess($daysBack = 1, $direction = 'in')
{
$result = [];
$this->banker->defaultUrlParams['order'] = 'datVyst@A';
$payments = $this->banker->getColumnsFromFlexibee([
'id',
'kod',
'varSym',
'specSym',
'sumCelkem',
'buc',
'smerKod',
'mena',
'datVyst'],
["sparovano eq false AND typPohybuK eq '".(($direction == 'out') ? 'typPohybu.vydej'
: 'typPohybu.prijem' )."' AND storno eq false ".
(is_null($daysBack) ? '' :
"AND datVyst eq '".\FlexiPeeHP\FlexiBeeRW::timestampToFlexiDate(mktime(0,
0, 0, date("m"), date("d") - $daysBack, date("Y")))."' ")
], 'id');
if ($this->banker->lastResponseCode == 200) {
if (empty($payments)) {
$result = [];
} else {
$result = $payments;
}
}
return $result;
}
public function getPaymentsWithinPeriod(\DatePeriod $period,
$direction = 'in')
{
$result = [];
$this->banker->defaultUrlParams['order'] = 'datVyst@A';
$conds['storno'] = false;
$conds['sparovano'] = false;
$conds['typPohybuK'] = ($direction == 'out') ? 'typPohybu.vydej' : 'typPohybu.prijem';
$conds['datVyst'] = $period;
$payments = $this->banker->getColumnsFromFlexibee([
'id',
'kod',
'buc',
'smerKod',
'varSym',
'specSym',
'sumCelkem',
'mena',
'datVyst'], $conds, 'id');
if ($this->banker->lastResponseCode == 200) {
if (empty($payments)) {
$result = [];
} else {
$result = $payments;
}
}
return $result;
}
public function getInvoicesToProcess()
{
$this->getInvoicer();
$this->invoicer->defaultUrlParams['includes'] = '/faktura-vydana/typDokl';
return $this->searchInvoices(["(stavUhrK is null OR stavUhrK eq 'stavUhr.castUhr') AND storno eq false"]);
}
public function outInvoicesMatchingByBank()
{
$this->getInvoicer();
foreach ($this->getPaymentsToProcess($this->daysBack, 'in') as $paymentData) {
$this->addStatusMessage(sprintf('Processing Payment %s %s %s vs: %s ss: %s %s',
$paymentData['kod'], $paymentData['sumCelkem'],
\FlexiPeeHP\FlexiBeeRO::uncode($paymentData['mena']),
$paymentData['varSym'], $paymentData['specSym'],
$this->banker->url.'/c/'.$this->banker->company.'/'.$this->banker->getEvidence().'/'.$paymentData['id']),
'info');
$invoices = $this->findInvoices($paymentData);
if (count($invoices) && count(current($invoices))) {
$prijatoCelkem = floatval($paymentData['sumCelkem']);
$payment = new \FlexiPeeHP\Banka($paymentData,
$this->config);
foreach ($invoices as $invoiceID => $invoiceData) {
$typDokl = $invoiceData['typDokl'][0];
$docType = $typDokl['typDoklK'];
$invoiceData['typDokl'] = \FlexiPeeHP\FlexiBeeRO::code($typDokl['kod']);
$invoice = new \FlexiPeeHP\FakturaVydana($invoiceData,
$this->config);
$matched = false;
switch ($docType) {
case 'typDokladu.zalohFaktura':
case 'typDokladu.faktura':
$matched = $this->settleInvoice($invoice, $payment);
break;
case 'typDokladu.proforma':
$matched = $this->settleProforma($invoice,
$paymentData);
break;
case 'typDokladu.dobropis':
$matched = $this->settleCreditNote($invoice,
$paymentData);
break;
default:
$this->addStatusMessage(
sprintf(_('Unsupported document type: %s %s'),
$typDokl['typDoklK@showAs'].' ('.$docType.'): '.$invoiceData['typDokl'],
$invoice->getApiURL()
), 'warning');
break;
}
if ($matched && $this->savePayerAccount($invoice->getDataValue('firma'),
$payment)) {
$this->addStatusMessage(sprintf(_('new Bank account %s assigned to Address %s'),
$payment->getDataValue('buc').'/'.\FlexiPeeHP\FlexiBeeRO::uncode($payment->getDataValue('smerKod')),
$invoice->getDataValue('firma@showAs')));
}
$this->banker->loadFromFlexiBee($paymentData['id']);
if ($this->banker->getDataValue('sparovano') == true) {
break;
}
}
} else {
if (!empty($paymentData['varSym'])) {
if (!empty($paymentData['varSym'])) {
$vInvoices = $this->searchInvoices(['varSym' => $paymentData['varSym']]);
}
}
if (!empty($paymentData['specSym'])) {
if (!empty($paymentData['specSym'])) {
$sInvoices = $this->searchInvoices(['specSym' => $paymentData['specSym']]);
}
}
}
}
}
public function paymentToZDD($invoiceData)
{
$return = $this->invoiceCopy($invoiceData, 'ZDD');
}
public function inInvoicesMatchingByBank(\DatePeriod $range = null)
{
$this->invoicer = new \FlexiPeeHP\FakturaPrijata(null, $this->config);
foreach ($this->getPaymentsWithinPeriod($range, 'out') as $outPaymentId => $outPaymentData) {
$this->banker->setData($outPaymentData, true);
$this->banker->setMyKey($outPaymentId);
$this->addStatusMessage(sprintf('Processing Outcoming Payment %s %s %s vs: %s ss: %s %s',
$outPaymentData['kod'], $outPaymentData['sumCelkem'],
\FlexiPeeHP\FlexiBeeRO::uncode($outPaymentData['mena']),
$outPaymentData['varSym'], $outPaymentData['specSym'],
$this->banker->getApiURL()), 'info');
$inInvoicesToMatch = $this->findInvoices($outPaymentData);
switch (count($inInvoicesToMatch)) {
case 0:
$this->addStatusMessage(_('No incoming invoice found for outcoming payment'));
break;
case 1:
$invoiceData = current($inInvoicesToMatch);
$invoiceID = key($inInvoicesToMatch);
$inInvoice = new \FlexiPeeHP\FakturaVydana($invoiceData,
array_merge($this->config,
['evidence' => 'faktura-prijata']));
if ($this->settleInvoice($inInvoice, $this->banker)) {
}
break;
default :
if (self::isSameCompany($inInvoicesToMatch)) {
foreach ($inInvoicesToMatch as $invoiceID => $invoiceData) {
$inInvoice = new \FlexiPeeHP\FakturaVydana($invoiceData,
array_merge($this->config,
['evidence' => 'faktura-prijata']));
if ($this->settleInvoice($inInvoice, $this->banker)) {
}
}
} else {
$this->addStatusMessage(_('Match by bank here'));
foreach ($inInvoicesToMatch as $invoiceID => $invoiceData) {
$inInvoice = new \FlexiPeeHP\FakturaVydana($invoiceData,
array_merge($this->config,
['evidence' => 'faktura-prijata']));
}
}
break;
}
if (count($inInvoicesToMatch) && count(current($inInvoicesToMatch))) {
$uhrazenoCelkem = floatval($outPaymentData['sumCelkem']);
$payment = new \FlexiPeeHP\Banka($outPaymentData,
$this->config);
}
}
}
public function getCompanyForBUC($account, $bankCode = null)
{
$bucer = new \FlexiPeeHP\FlexiBeeRW(null,
['evidence' => 'adresar-bankovni-ucet']);
$companyRaw = $bucer->getColumnsFromFlexibee(['firma'],
empty($bankCode) ? ['buc' => $account] : ['buc' => $account, 'smerKod' => $bankCode]);
return array_key_exists(0, $companyRaw) ? $companyRaw[0]['firma'] : null;
}
public static function isSameCompany($documents)
{
return count(self::reindexArrayBy($documents, 'firma')) == 1;
}
public static function isSameAccount($documents)
{
return count(self::reindexArrayBy($documents, 'buc')) == 1;
}
public function invoicesMatchingByInvoices()
{
foreach ($this->getInvoicesToProcess() as $invoiceData) {
$payments = $this->findPayments($invoiceData);
if (!empty($payments) && count(current($payments))) {
$typDokl = $invoiceData['typDokl'][0];
$docType = $typDokl['typDoklK'];
$invoiceData['typDokl'] = \FlexiPeeHP\FlexiBeeRO::code($typDokl['kod']);
$invoice = new \FlexiPeeHP\FakturaVydana($invoiceData,
$this->config);
$this->invoicer->setMyKey($invoiceData['id']);
foreach ($payments as $paymentData) {
$payment = new \FlexiPeeHP\Banka($paymentData, $this->config);
switch ($docType) {
case 'typDokladu.zalohFaktura':
case 'typDokladu.faktura':
if ($this->settleInvoice($invoice, $payment)) {
}
break;
case 'typDokladu.proforma':
$this->settleProforma($invoice, $payments);
break;
case 'typDokladu.dobropis':
$this->settleCreditNote($invoice, $payments);
break;
default:
$this->addStatusMessage(
sprintf(_('Unsupported document type: %s %s'),
$typDokl['typDoklK@showAs'].' ('.$docType.'): '.$invoiceData['typDokl'],
$invoice->getApiURL()
), 'warning');
break;
}
}
}
}
}
public function settleCreditNote($invoice, $payment)
{
$success = 0;
$prijataCastka = (float) $payment->getDataValue('sumCelkem');
if ($prijataCastka < $invoice->getDataValue('zbyvaUhradit')) {
$this->addStatusMessages(sprinf(_('Castecna uhrada - DOBROPIS: prijato: %s ma byt zaplaceno %s'),
$prijataCastka, $invoice->getDataValue('zbyvaUhradit')),
'warning');
}
if ($prijataCastka > $invoice->getDataValue('zbyvaUhradit')) {
$this->addStatusMessages(sprinf(_('Přeplatek - DOBROPIS: prijato: %s ma byt zaplaceno %s'),
$prijataCastka, $invoice->getDataValue('zbyvaUhradit')),
'warning');
$this->banker->dataReset();
$this->banker->setDataValue('id', $payment['id']);
$this->banker->setDataValue('stitky',
$this->config['LABEL_PREPLATEK']);
$this->banker->insertToFlexiBee();
}
if ($invoice->sparujPlatbu($payment, 'castecnaUhrada')) {
$success = 1;
$invoice->addStatusMessage(sprintf(_('Platba %s %s byla sparovana s dobropisem %s'),
(string) $payment, $prijataCastka, (string) $invoice),
'success');
}
return $success;
}
public function settleProforma($zaloha, $payment)
{
$success = 0;
$prijataCastka = (float) $payment['sumCelkem'];
$platba = new \FlexiPeeHP\Banka((int) $payment['id'], $this->config);
if ($zaloha->sparujPlatbu($platba, 'castecnaUhrada')) {
$success = 1;
$zaloha->addStatusMessage(sprintf(_('Platba %s %s %s byla sparovana s zalohou %s'),
\FlexiPeeHP\FlexiBeeRO::uncode($platba), $prijataCastka,
\FlexiPeeHP\FlexiBeeRO::uncode($payment['mena']),
(string) $zaloha), 'success');
if ($zaloha->getDataValue('zbyvaUhradit') > $prijataCastka) {
$zaloha->addStatusMessage(sprintf(_('Částečná úhrada %s'),
self::apiUrlToLink($zaloha->apiURL)), 'warning');
$zaloha->addStatusMessage(sprintf(_('Vytvoř ZDD: %s'),
self::apiUrlToLink($platba->apiURL.'/vytvor-zdd')),
'debug');
} else {
if ($prijataCastka > $zaloha->getDataValue('zbyvaUhradit')) {
$zaloha->addStatusMessage(sprintf(_('Přeplatek %s'),
self::apiUrlToLink($platba->apiURL)), 'warning');
}
$faktura2 = $this->invoiceCopy($zaloha,
['duzpUcto' => $platba->getDataValue('datVyst'), 'datVyst' => $platba->getDataValue('datVyst')]);
$id = (int) $faktura2->getLastInsertedId();
$faktura2->loadFromFlexiBee($id);
$kod = $faktura2->getDataValue('kod');
$faktura2->dataReset();
$faktura2->setDataValue('id', 'code:'.$kod);
$faktura2->setDataValue('typDokl', 'code:FAKTURA');
$result = $faktura2->odpocetZalohy($zaloha);
if (isset($result['success']) && ($result['success'] == 'true')) {
$success = 2;
$zaloha->addStatusMessage(sprintf(_('Faktura #%s byla sparovana'),
$kod), 'success');
} else {
$success = -1;
$zaloha->addStatusMessage(sprintf(_('Faktura #%s nebyla sparovana'),
$kod), 'error');
}
}
}
return $success;
}
public function settleInvoice($invoice, $payment)
{
$success = 0;
$zbytek = 'ne';
$prijataCastka = (float) $payment->getDataValue('sumCelkem');
$zbyvaUhradit = $invoice->getDataValue('zbyvaUhradit');
if ($prijataCastka < $zbyvaUhradit) {
$this->addStatusMessage(sprintf(_('Castecna uhrada - FAKTURA: prijato: %s %s ma byt zaplaceno %s %s'),
$prijataCastka,
\FlexiPeeHP\FlexiBeeRO::uncode($payment->getDataValue('mena')),
$zbyvaUhradit,
\FlexiPeeHP\FlexiBeeRO::uncode($invoice->getDataValue('mena'))),
'warning');
$zbytek = 'castecnaUhrada';
}
if ($prijataCastka > $zbyvaUhradit) {
$this->addStatusMessage(sprintf(_('Přeplatek - FAKTURA: prijato: %s %s ma byt zaplaceno %s %s'),
$prijataCastka,
\FlexiPeeHP\FlexiBeeRO::uncode($payment->getDataValue('mena')),
$zbyvaUhradit,
\FlexiPeeHP\FlexiBeeRO::uncode($invoice->getDataValue('mena'))),
'warning');
$zbytek = 'ignorovat';
}
if ($invoice->sparujPlatbu($payment, $zbytek)) {
$success = 1;
$invoice->insertToFlexiBee(['id' => (string) $invoice, 'stavMailK' => 'stavMail.odeslat']);
$invoice->addStatusMessage(sprintf(_('Platba %s %s %s byla sparovana s fakturou %s'),
\FlexiPeeHP\FlexiBeeRO::uncode($payment->getRecordIdent()),
$prijataCastka,
\FlexiPeeHP\FlexiBeeRO::uncode($payment->getDataValue('mena')),
\FlexiPeeHP\FlexiBeeRO::uncode($invoice->getRecordIdent())),
'success');
}
return $success;
}
function invoiceCopy($invoice, $extraValues = [])
{
$invoice2 = new \FlexiPeeHP\FakturaVydana(array_merge($invoice->getData(),
array_merge($this->config, $extraValues)));
$invoice2->setDataValue('typDokl', 'code:FAKTURA');
$invoice2->unsetDataValue('id');
$invoice2->unsetDataValue('kod');
if ($invoice2->getDataValue('stavUhrK') != 'stavUhr.uhrazenoRucne') {
$invoice2->unsetDataValue('stavUhrK');
}
$polozky = $invoice2->getDataValue('polozkyFaktury');
if (count($polozky)) {
foreach ($polozky as $pid => $polozka) {
unset($polozky[$pid]['id']);
unset($polozky[$pid]['datUcto']);
unset($polozky[$pid]['doklFak']);
unset($polozky[$pid]['doklFak@showAs']);
unset($polozky[$pid]['doklFak@ref']);
$polozky[$pid]['ucetni'] = true;
}
}
$invoice2->setDataValue('polozkyFaktury', $polozky);
$invoice2->unsetDataValue('external-ids');
if (isset($extraValues['datVyst'])) {
$today = $extraValues['datVyst'];
} else {
$today = date('Y-m-d');
}
$invoice2->setDataValue('duzpPuv', $today);
$invoice2->setDataValue('duzpUcto', $today);
$invoice2->setDataValue('datUcto', $today);
$invoice2->setDataValue('stavMailK', 'stavMail.odeslat');
$invoice2->insertToFlexiBee();
if ($invoice2->lastResponseCode == 201) {
$invoice->addStatusMessage(sprintf(_('Faktura %s byla vytvořena z dokladu %s'),
self::apiUrlToLink($invoice2->apiURL),
self::apiUrlToLink($invoice->apiURL)), 'success');
}
return $invoice2;
}
function hotfixDeductionOfAdvances()
{
}
static public function unifyInvoices($vInvoices, &$invoices)
{
if (!empty($vInvoices) && count($vInvoices)) {
foreach ($vInvoices as $invoiceID => $invoice) {
if (!array_key_exists($invoiceID, $invoices)) {
$invoices[$invoiceID] = $invoice;
}
}
}
}
public function findInvoices($paymentData)
{
$invoices = [];
$vInvoices = [];
$sInvoices = [];
$uInvoices = [];
$bInvoices = [];
if (!empty($paymentData['varSym'])) {
$vInvoices = $this->findInvoice(['varSym' => $paymentData['varSym']]);
}
if (empty($vInvoices)) {
if (!empty($paymentData['specSym'])) {
$uInvoices = $this->findInvoice(['firma' => sprintf("code:%05s",
$paymentData['specSym'])]);
}
if (!empty($paymentData['specSym'])) {
$sInvoices = $this->findInvoice(['specSym' => $paymentData['specSym']]);
}
if ($paymentData['buc']) {
$bInvoices = $this->findInvoice(['buc' => $paymentData['buc']]);
}
}
self::unifyInvoices($vInvoices, $invoices);
self::unifyInvoices($uInvoices, $invoices);
self::unifyInvoices($sInvoices, $invoices);
self::unifyInvoices($bInvoices, $invoices);
$invoices = self::reorderInvoicesByAge($invoices);
if (empty($paymentData['varSym']) && empty($paymentData['specSym'])) {
$this->banker->dataReset();
$this->banker->setDataValue('id', $paymentData['id']);
$this->banker->setDataValue('stitky', 'NEIDENTIFIKOVANO');
$this->addStatusMessage(_('Neidentifikovaná platba').': '.$this->banker->getApiURL(),
'warning');
$this->banker->insertToFlexiBee();
} elseif (count($invoices) == 0) {
$this->banker->dataReset();
$this->banker->setDataValue('id', $paymentData['id']);
$this->banker->setDataValue('stitky', 'CHYBIFAKTURA');
$this->addStatusMessage(_('Platba bez faktury').': '.$this->banker->getApiURL(),
'warning');
$this->banker->insertToFlexiBee();
}
return $invoices;
}
public static function reorderInvoicesByAge($invoices)
{
$invoicesByAge = [];
$invoicesByAgeRaw = [];
foreach ($invoices as $invoiceData) {
$invoicesByAgeRaw[\FlexiPeeHP\FlexiBeeRW::flexiDateToDateTime($invoiceData['datVyst'])->getTimestamp()]
= $invoiceData;
}
ksort($invoicesByAgeRaw);
foreach ($invoicesByAgeRaw as $invoiceData) {
$invoicesByAge[$invoiceData['kod']] = $invoiceData;
}
return $invoicesByAge;
}
public function findPayments($invoiceData)
{
$pays = [];
$sPays = [];
$bPays = [];
if (array_key_exists('varSym', $invoiceData) && !empty($invoiceData['varSym'])) {
$sPays = $this->findPayment(['varSym' => $invoiceData['varSym']]);
if (is_array($sPays)) {
$pays = $sPays;
}
}
if (array_key_exists('specSym', $invoiceData) && !empty($invoiceData['specSym'])) {
$sPays = $this->findPayment(['specSym' => $invoiceData['specSym']]);
if (is_array($bPays)) {
$pays = $bPays;
}
}
if (array_key_exists('buc', $invoiceData) && !empty($invoiceData['buc'])) {
$bPays = $this->findPayment(['buc' => $invoiceData['buc']]);
if ($bPays) {
foreach ($bPays as $payID => $payment) {
if (!array_key_exists($payID, $pays)) {
$pays[$payID] = $payment;
}
}
}
}
return $pays;
}
public function findInvoice($what)
{
return $this->searchInvoices(["(".\FlexiPeeHP\FlexiBeeRO::flexiUrl($what,
'or').") AND (stavUhrK is null OR stavUhrK eq 'stavUhr.castUhr') AND storno eq false"]);
}
public function searchInvoices($what)
{
$result = null;
$this->invoicer->defaultUrlParams['order'] = 'datVyst@A';
$this->invoicer->defaultUrlParams['includes'] = '/faktura-vydana/typDokl';
$invoices = $this->invoicer->getColumnsFromFlexibee([
'id',
'kod',
'stavUhrK',
'zbyvaUhradit',
'firma',
'buc',
'mena',
'varSym',
'specSym',
'typDokl(typDoklK,kod)',
'sumCelkem',
'duzpPuv',
'stitky',
'typDokl',
'datVyst'
], $what, 'id');
if ($this->invoicer->lastResponseCode == 200) {
$result = $invoices;
}
unset($this->invoicer->defaultUrlParams['includes']);
return $result;
}
public function findPayment($what)
{
$result = null;
$this->banker->defaultUrlParams['order'] = 'datVyst@A';
$payments = $this->banker->getColumnsFromFlexibee([
'id',
'varSym',
'specSym',
'buc',
'sumCelkem',
'mena',
'stitky',
'datVyst'],
["(".\FlexiPeeHP\FlexiBeeRO::flexiUrl($what, 'or').") AND sparovano eq 'false'"],
'id');
if ($this->banker->lastResponseCode == 200) {
$result = $payments;
}
return $result;
}
public function findBestPayment($payments, $invoice)
{
$value = $invoice->getDataValue('sumCelkem');
foreach ($payments as $paymentID => $payment) {
if ($payment['sumCelkem'] == $value) {
return new \FlexiPeeHP\Banka(\FlexiPeeHP\FlexiBeeRO::code($payments[$paymentID]['kod']),
$this->config);
}
}
$symbol = $invoice->getDataValue('specSym');
$this->addStatusMessage(sprintf(_('Platba pro fakturu %s nebyla dohledána'),
self::apiUrlToLink($invoice->apiURL)), 'warning');
return null;
}
public static function apiUrlToLink($apiURL)
{
return str_replace('.json?limit=0', '',
preg_replace("#(^|[\n ])([\w]+?://[\w\#$%&~/.\-;:=,?@\[\]+]*)#is",
"\\1<a href=\"\\2\" target=\"_blank\" rel=\"nofollow\">\\2</a>",
$apiURL));
}
public function getOriginDocumentType($typDokl)
{
if (empty($this->docTypes)) {
$this->docTypes = $this->getDocumentTypes();
}
$documentType = \FlexiPeeHP\FlexiBeeRO::uncode($typDokl);
return array_key_exists($documentType, $this->docTypes) ? $this->docTypes[$documentType]
: 'typDokladu.neznamy';
}
public function savePayerAccount($payer, $payment)
{
$result = null;
$buc = $payment->getDataValue('buc');
if (!empty($buc) && !empty($payer) && $this->isKnownBankAccountForAddress($payer,
$buc)) {
$result = $this->assignBankAccountToAddress($payer, $payment);
}
return $result;
}
public function isKnownBankAccountForAddress($address, $buc)
{
$result = null;
$accounts = [];
$bucer = new \FlexiPeeHP\FlexiBeeRW(null,
['evidence' => 'adresar-bankovni-ucet']);
$accountsRaw = $bucer->getColumnsFromFlexibee(['buc', 'smerKod'],
['firma' => $address]);
if (!empty($accountsRaw)) {
$accounts = self::reindexArrayBy($accountsRaw, 'buc');
}
return !array_key_exists($buc, $accounts);
}
public function assignBankAccountToAddress($address, $payment)
{
$bucer = new \FlexiPeeHP\FlexiBeeRW(null,
['evidence' => 'adresar-bankovni-ucet']);
$bucer->insertToFlexiBee(['firma' => $address, 'buc' => $payment->getDataValue('buc'),
'smerKod' => $payment->getDataValue('smerKod'), 'poznam' => _('Added by script')]);
return $bucer->lastResponseCode == 201;
}
}