Panowie potrzebuję jakiejś świeżej głowy do rozwiązania tego problemu ponieważ, nie wiem już jak się do tego zabrać. Próbowałem różnych rozwiązań ale niestety nie udało mi się tego dokonać aktualnie.

Krótko opisując temat. Mam sobie widok w którym matchuje sobie lewą stronę z prawą. Matchowanie może zachodzić jeden do jeden, wiele do jeden i wiele do wiele. I teraz przejdźmy do kodu:

Prawa strona ma większą wartość niż lewa:

  1. $tickets = [
  2. [
  3. 'issue_id' => 'ZAKUPY-1070',
  4. 'amount' => '100'
  5. ],
  6. [
  7. 'issue_id' => 'ZAKUPY-1043',
  8. 'amount' => '100'
  9. ]
  10. ];
  11.  
  12. $invoices = [
  13. [
  14. 'document_id' => '12998638134790357761.1',
  15. 'amount' => '150'
  16. ],
  17. [
  18. 'document_id' => '12998638134790357761.2',
  19. 'amount' => '100'
  20. ]
  21. ];
  22.  
  23. $result = [
  24. [
  25. 'issue_id' => 'ZAKUPY-1070',
  26. 'document_id' => '12998638134790357761.1',
  27. 'issue_amount' => '100.0000',
  28. 'document_amount' => '100.0000'
  29. ],
  30. [
  31. 'issue_id' => 'ZAKUPY-1043',
  32. 'document_id' => '12998638134790357761.1',
  33. 'issue_amount' => '50.0000',
  34. 'document_amount' => '50.0000'
  35. ],
  36. [
  37. 'issue_id' => 'ZAKUPY-1070',
  38. 'document_id' => '12998638134790357761.2',
  39. 'issue_amount' => '0.0000',
  40. 'document_amount' => '0.0000'
  41. ],
  42. [
  43. 'issue_id' => 'ZAKUPY-1043',
  44. 'document_id' => '12998638134790357761.2',
  45. 'issue_amount' => '50.0000',
  46. 'document_amount' => '50.0000'
  47. ]
  48. ];


Lewa strona ma większą wartość niż prawa:

  1. $tickets = [
  2. [
  3. 'issue_id' => 'ZAKUPY-1070',
  4. 'amount' => '150'
  5. ],
  6. [
  7. 'issue_id' => 'ZAKUPY-1043',
  8. 'amount' => '100'
  9. ]
  10. ];
  11.  
  12. $invoices = [
  13. [
  14. 'document_id' => '12998638134790357761.1',
  15. 'amount' => '100'
  16. ],
  17. [
  18. 'document_id' => '12998638134790357761.2',
  19. 'amount' => '100'
  20. ]
  21. ];
  22.  
  23. $result = [
  24. [
  25. 'issue_id' => 'ZAKUPY-1070',
  26. 'document_id' => '12998638134790357761.1',
  27. 'issue_amount' => '100.0000',
  28. 'document_amount' => '100.0000'
  29. ],
  30. [
  31. 'issue_id' => 'ZAKUPY-1043',
  32. 'document_id' => '12998638134790357761.1',
  33. 'issue_amount' => '0.0000',
  34. 'document_amount' => '0.0000'
  35. ],
  36. [
  37. 'issue_id' => 'ZAKUPY-1070',
  38. 'document_id' => '12998638134790357761.2',
  39. 'issue_amount' => '50.0000',
  40. 'document_amount' => '50.0000'
  41. ],
  42. [
  43. 'issue_id' => 'ZAKUPY-1043',
  44. 'document_id' => '12998638134790357761.2',
  45. 'issue_amount' => '50.0000',
  46. 'document_amount' => '50.0000'
  47. ]
  48. ];


Obie strony są równe:

  1. $tickets = [
  2. [
  3. 'issue_id' => 'ZAKUPY-1070',
  4. 'amount' => '120'
  5. ],
  6. [
  7. 'issue_id' => 'ZAKUPY-1043',
  8. 'amount' => '80'
  9. ]
  10. ];
  11.  
  12. $invoices = [
  13. [
  14. 'document_id' => '12998638134790357761.1',
  15. 'amount' => '80'
  16. ],
  17. [
  18. 'document_id' => '12998638134790357761.2',
  19. 'amount' => '120'
  20. ]
  21. ];
  22.  
  23. $result = [
  24. [
  25. 'issue_id' => 'ZAKUPY-1070',
  26. 'document_id' => '12998638134790357761.1',
  27. 'issue_amount' => '80.0000',
  28. 'document_amount' => '80.0000'
  29. ],
  30. [
  31. 'issue_id' => 'ZAKUPY-1043',
  32. 'document_id' => '12998638134790357761.1',
  33. 'issue_amount' => '0.0000',
  34. 'document_amount' => '0.0000'
  35. ],
  36. [
  37. 'issue_id' => 'ZAKUPY-1070',
  38. 'document_id' => '12998638134790357761.2',
  39. 'issue_amount' => '40.0000',
  40. 'document_amount' => '40.0000'
  41. ],
  42. [
  43. 'issue_id' => 'ZAKUPY-1043',
  44. 'document_id' => '12998638134790357761.2',
  45. 'issue_amount' => '80.0000',
  46. 'document_amount' => '80.0000'
  47. ]
  48. ];


Obecnie stanałem na rozwiązaniu:

  1. $ticketsSummary = 0;
  2.  
  3. foreach ($tickets as $ticket) {
  4. $baseTickets[$ticket['issue_id']] = $ticket;
  5. $ticketsSummary += $ticket['amount'];
  6. }
  7.  
  8. $invoicesSummary = 0;
  9.  
  10. foreach ($invoices as $invoice) {
  11. $baseInvoices[$invoice['document_id']] = $invoice;
  12. $invoicesSummary += $invoice['amount'];
  13. }
  14.  
  15. foreach ($invoices as $invoice) {
  16. foreach ($tickets as $ticket) {
  17. if (!isset($invoiceAmountCounter[$invoice['document_id']])) {
  18. $invoiceAmountCounter[$invoice['document_id']] = 0;
  19. }
  20.  
  21. $invoiceAmountCounter[$invoice['document_id']] =
  22. $invoiceAmountCounter[$invoice['document_id']] + $ticket['amount'];
  23.  
  24. if ($invoiceAmountCounter[$invoice['document_id']] >= $baseInvoices[$invoice['document_id']]['amount']) {
  25. $ticket['amount'] = $ticket['amount'] - ($invoiceAmountCounter[$invoice['document_id']] -
  26. $baseInvoices[$invoice['document_id']]['amount']);
  27. $ticket['amount'] = $ticket['amount'] < 0 ? 0 : $ticket['amount'];
  28. }
  29.  
  30. $result[] = [
  31. 'issue_id' => $ticket['issue_id'],
  32. 'document_id' => $invoice['document_id'],
  33. 'document_amount' => $ticket['amount'],
  34. 'issue_amount' => $ticket['amount'],
  35. ];
  36. }
  37. }


Problem rozwiązany:

  1. $right = $invoices;
  2. $rightColIndex = 0;
  3. $results = [];
  4.  
  5. foreach ($tickets as $leftPos) {
  6.  
  7. $ticketSum = 0;
  8.  
  9. while (isset($right[$rightColIndex]) && $leftPos['amount'] > $ticketSum) {
  10.  
  11. $rightPos = $right[$rightColIndex];
  12.  
  13. $ticketSum += $rightPos['amount'];
  14.  
  15. $results[] = [
  16. 'document_id' => $rightPos['document_id'],
  17. 'issue_id' => $leftPos['issue_id'],
  18. 'issue_amount' => $rightPos['amount'],
  19. 'document_amount' => $rightPos['amount'],
  20. ];
  21.  
  22. $rightColIndex++;
  23. }
  24.  
  25. if ($ticketSum > $leftPos['amount']) {
  26. $rightColIndex--;
  27.  
  28. $diffAmount = $ticketSum - $leftPos['amount'];
  29.  
  30.  
  31. $results[count($results) - 1]['document_amount'] = $right[$rightColIndex]['amount'] - $diffAmount;
  32. $results[count($results) - 1]['issue_amount'] = $right[$rightColIndex]['amount'] - $diffAmount;
  33.  
  34. $right[$rightColIndex]['amount'] = $diffAmount;
  35.  
  36. }
  37. }