firebed / aade-mydata

Interface for ΑΑΔΕ myDATA invoicing REST API. It handles all the boilerplate code for sending, cancelling and requesting invoices.
https://docs.invoicemaker.gr/getting-started
MIT License
61 stars 21 forks source link

v1.0.8 #12

Closed memisibram closed 8 months ago

memisibram commented 9 months ago

Changes for adding a Delivery note to an invoice. Added isDeliveryNote and components that can be used with it. Check out the SendInvoices sample code.

$putDeliveryNote = true; //set true for put Delivery Note

//***************************************************//Στοιχεία Εκδότη
$issuer = new Issuer(); //Στοιχεία Εκδότη
$issuer->setVatNumber('000000000'); //Οποιοσδήποτε έγκυρος ΑΦΜ εκδότη
$issuer->setCountry('GR'); //Ο κωδικός της χώρας
$issuer->setBranch(0); //Αρ. Εγκατάσ. Σε περίπτωση που η εγκατάσταση του εκδότη είναι η έδρα ή δεν υφίσταται, το πεδίο να έχει την τιμή 0

if($putDeliveryNote){
$issuer->setName('Επωνυμία εκδότη');//Επωνυμία εκδότη, είναι αποδεκτό στην περίπτωση Ένδειξη Παραστατικού Διακίνησης isDeliveryNote=rtue
    $address = new Address(); //Διεύθυνση
    $address->setStreet('Οδός Οδός'); //Οδός
    $address->setNumber('40'); //Αριθμός Οδού
    $address->setPostalCode('11855'); //Ταχυδρομικός Κώδικας
    $address->setCity('Αθήνα'); //Όνομα πόλης
$issuer->setAddress($address); //Διεύθυνση εκδότη, είναι αποδεκτό στην περίπτωση Ένδειξη Παραστατικού Διακίνησης isDeliveryNote=rtue
}

//***************************************************//Στοιχεία Λήπτη
$counterpart = new Counterpart(); //Στοιχεία Λήπτη
$counterpart->setVatNumber('000000000'); //Οποιοσδήποτε έγκυρος ΑΦΜ εκδότη
$counterpart->setCountry('GR'); //Ο κωδικός της χώρας
$counterpart->setBranch(0);//Αρ. Εγκατάσ. Σε περίπτωση που η εγκατάσταση του εκδότη είναι η έδρα ή δεν υφίσταται, το πεδίο να έχει την τιμή 0
if($putDeliveryNote){
$counterpart->setName('Επωνυμία λήπτη');//Επωνυμία λήπτη, είναι αποδεκτό στην περίπτωση Ένδειξη Παραστατικού Διακίνησης isDeliveryNote=rtue
    $address = new Address(); //Διεύθυνση
    $address->setStreet('Οδός Οδός'); //Οδός
    $address->setNumber('45'); //Αριθμός Οδού
    $address->setPostalCode('11855'); //Ταχυδρομικός Κώδικας
    $address->setCity('Αθήνα'); //Όνομα πόλης
$counterpart->setAddress($address); //Διεύθυνση λήπτη, είναι αποδεκτό στην περίπτωση Ένδειξη Παραστατικού Διακίνησης isDeliveryNote=rtue
}

//***************************************************//Γενικά Στοιχεία παραστατικού
$invoiceHeader = new InvoiceHeader(); //Γενικά Στοιχεία παραστατικού
$invoiceHeader->setSeries('0'); //Σειρά παραστατικού, Σε περίπτωση μή έκδοσης σειράς παραστατικού, το πεδίο series πρέπει να έχει την τιμή 0
$invoiceHeader->setAa('1'); //ΑΑ Παραστατικού, μέγιστο επιτρεπτό μήκος 50
$invoiceHeader->setIssueDate('2024-02-03'); //Ημερομηνία Έκδοσης Παραστατικού
$invoiceHeader->setInvoiceType('1.1'); //Είδος Παραστατικού
$invoiceHeader->setCurrency('EUR'); //Νόμισμα, Ο κωδικός νομισμάτων προέρχεται από την αντίστοιχη λίστα σύμφωνα με το πρότυπο ISO4217.

if($putDeliveryNote){
$invoiceHeader->setMovePurpose('1'); //Σκοπός Διακίνησης
$otherDeliveryNoteHeader = new OtherDeliveryNoteHeader(); //Λοιπά Γενικά Στοιχεία Διακίνησης
    $loadaddress = new LoadingAddress(); //Διεύθυνση Φόρτωσης
    $loadaddress->setStreet('Οδός Οδός'); //Οδός
    $loadaddress->setNumber('40'); //Αριθμός Οδού
    $loadaddress->setPostalCode('11855'); //Ταχυδρομικός Κώδικας
    $loadaddress->setCity('Αθήνα'); //Όνομα πόλης
$otherDeliveryNoteHeader->setLoadingAddress($loadaddress); //Ορισμός, Διεύθυνση Φόρτωσης
    $delivryaddress = new DeliveryAddress(); //Διεύθυνση Παράδοσης
    $delivryaddress->setStreet('Οδός Οδός'); //Οδός
    $delivryaddress->setNumber('45'); //Αριθμός Οδού
    $delivryaddress->setPostalCode('11855'); //Ταχυδρομικός Κώδικας
    $delivryaddress->setCity('Αθήνα'); //Όνομα πόλης
$otherDeliveryNoteHeader->setDeliveryAddress($delivryaddress); //Ορισμός, Διεύθυνση Παράδοσης
$invoiceHeader->setOtherDeliveryNoteHeader($otherDeliveryNoteHeader); //Ορισμός, Λοιπά Γενικά Στοιχεία Διακίνησης
$invoiceHeader->setIsDeliveryNote(true); //Ένδειξη Παραστατικού Διακίνησης
}

//***************************************************//Στοιχεία Πληρωμών
$paymentMethod = new PaymentMethodDetail(); //Στοιχεία Πληρωμών
$paymentMethod->setType('3'); //Τύπος Πληρωμής
$paymentMethod->setAmount(124.00); //Αναλογούν Ποσό
$paymentMethod->setPaymentMethodInfo('Μετρητά'); //Λοιπές Πληροφορίες (Τρόπος Πληρωμής)

//***************************************************//Λεπτομέρειες Παραστατικού
//Add one new product
$invoiceDetails = new InvoiceDetails(); //Λεπτομέρειες Παραστατικού
$invoiceDetails->setLineNumber(1); //ΑΑ Γραμμής
if($putDeliveryNote){
$invoiceDetails->setItemCode('KE58'); //Κωδικός Είδους
$invoiceDetails->setItemDescr('Είδος KE58'); //Περιγραφή Είδους
$invoiceDetails->setQuantity(1); //Ποσότητα
$invoiceDetails->setMeasurementUnit('1'); //Είδος Ποσότητας
}
$invoiceDetails->setNetValue(100.00); //Καθαρή Αξία
$invoiceDetails->setVatCategory('1'); //Κατηγορία ΦΠΑ
$invoiceDetails->setVatAmount(24.00); //Ποσό ΦΠΑ

$incomeClassification = new IncomeClassification(); //Λίστα Χαρακτηρισμών Εσόδων
$incomeClassification->setClassificationType('E3_561_001'); //Κωδικός Χαρακτηρισμού
$incomeClassification->setClassificationCategory('category1_1'); //Κατηγορία Χαρακτηρισμού
$incomeClassification->setAmount(100.00); //Ποσό
$invoiceDetails->addIncomeClassification($incomeClassification); //Ορισμός, Λίστα Χαρακτηρισμών Εσόδων

//Continue to new product or multiple products
//ok let's add the second one too
$invoiceDetailsb = new InvoiceDetails(); //Λεπτομέρειες Παραστατικού
$invoiceDetailsb->setLineNumber(2); //ΑΑ Γραμμής
if($putDeliveryNote){
$invoiceDetailsb->setItemCode('BE51'); //Κωδικός Είδους
$invoiceDetailsb->setItemDescr('Είδος BE51'); //Περιγραφή Είδους
$invoiceDetailsb->setQuantity(1); //Ποσότητα
$invoiceDetailsb->setMeasurementUnit('1'); //Είδος Ποσότητας
}
$invoiceDetailsb->setNetValue(100.00); //Καθαρή Αξία
$invoiceDetailsb->setVatCategory('1'); //Κατηγορία ΦΠΑ
$invoiceDetailsb->setVatAmount(24.00); //Ποσό ΦΠΑ

$incomeClassification = new IncomeClassification(); //Λίστα Χαρακτηρισμών Εσόδων
$incomeClassification->setClassificationType('E3_561_001'); //Κωδικός Χαρακτηρισμού
$incomeClassification->setClassificationCategory('category1_2'); //Κατηγορία Χαρακτηρισμού
$incomeClassification->setAmount(100.00); //Ποσό
$invoiceDetailsb->addIncomeClassification($incomeClassification); //Ορισμός, Λίστα Χαρακτηρισμών Εσόδων

//***************************************************//Συγκεντρωτικά Στοιχεία
$invoiceSummary = new InvoiceSummary(); //Συγκεντρωτικά Στοιχεία
$invoiceSummary->setTotalNetValue(200.00); //Σύνολο Καθαρής Αξίας
$invoiceSummary->setTotalVatAmount(48.00); //Σύνολο ΦΠΑ
$invoiceSummary->setTotalWithheldAmount(0.00); //Σύνολο Παρακρατήσεων Φόρων
$invoiceSummary->setTotalFeesAmount(0.00); //Σύνολο Τελών
$invoiceSummary->setTotalStampDutyAmount(0.00); //Σύνολο Χαρτοσήμου
$invoiceSummary->setTotalOtherTaxesAmount(0.00); //Σύνολο Λοιπών Φόρων
$invoiceSummary->setTotalDeductionsAmount(0.00); //Σύνολο Κρατήσεων
$invoiceSummary->setTotalGrossValue(248.00); //Συνολική Αξία

//IncomeClassification for first product
$incomeClassification = new IncomeClassification(); //Λίστα Χαρακτηρισμών Εσόδων
$incomeClassification->setClassificationType('E3_561_001'); //Κωδικός Χαρακτηρισμού
$incomeClassification->setClassificationCategory('category1_1'); //Κατηγορία Χαρακτηρισμού
$incomeClassification->setAmount(100.00); //Ποσό
$invoiceSummary->addIncomeClassification($incomeClassification); //Ορισμός, Λίστα Χαρακτηρισμών Εσόδων

//IncomeClassification for second product
$incomeClassification = new IncomeClassification(); //Λίστα Χαρακτηρισμών Εσόδων
$incomeClassification->setClassificationType('E3_561_001'); //Κωδικός Χαρακτηρισμού
$incomeClassification->setClassificationCategory('category1_2'); //Κατηγορία Χαρακτηρισμού
$incomeClassification->setAmount(100.00); //Ποσό
$invoiceSummary->addIncomeClassification($incomeClassification); //Ορισμός, Λίστα Χαρακτηρισμών Εσόδων

//Continue IncomeClassification for multiple products 

$invoice = new Invoice();
$invoice->setIssuer($issuer); // Firebed\AadeMyData\Models\Issuer
$invoice->setCounterpart($counterpart); // Firebed\AadeMyData\Models\Counterpart
$invoice->setInvoiceHeader($invoiceHeader); // Firebed\AadeMyData\Models\InvoiceHeader
$invoice->addPaymentMethod($paymentMethod); // Firebed\AadeMyData\Models\PaymentMethodDetail
$invoice->addInvoiceDetails($invoiceDetails); // Firebed\AadeMyData\Models\InvoiceDetails
$invoice->addInvoiceDetails($invoiceDetailsb); // Firebed\AadeMyData\Models\InvoiceDetails
$invoice->setInvoiceSummary($invoiceSummary); // Firebed\AadeMyData\Models\InvoiceSummary

$invoicesDoc = new InvoicesDoc();
$invoicesDoc->addInvoice($invoice);
// You can add multiple invoices at once

/*
var_dump($invoicesDoc);
exit();
*/

// Create the request
$sendInvoices = new SendInvoices();
$response = $sendInvoices->handle($invoicesDoc);

function dd($testtt){
    var_dump($testtt);
}

$errors = [];
foreach ($response as $responseType) {
    if ($responseType->isSuccessful()) {
        // This invoice was successfully registered. Typically, you should have an invoice object of your
        // own and an invoice reference from myDATA, and you will have to relate these together. 
        // Each responseType has an index value which corresponds to the index of the invoice in 
        // the $invoicesDoc object, you can use this index value to find the invoice it is referred to.
        // Retrieve the invoice's uid, mark, qr and other values from the responseType,
        // then establish the correlation with your local invoice and persist these details in your database.
        $index = $responseType->getIndex();
        $uid = $responseType->getInvoiceUid();
        $mark = $responseType->getInvoiceMark();
        $cancelledByMark = $responseType->getCancellationMark();
        $qrUrl = $responseType->getQrUrl();

        dd(compact('index', 'uid', 'mark', 'cancelledByMark', 'qrUrl'));
    } else {
        // There were some errors for this specific invoice. See errors for details.
        foreach ($responseType->getErrors() as $error) {
            $errors[$responseType->getIndex()][] = $error->getCode() . ': ' . $error->getMessage();
        }
    }
}

if (!empty($errors)) {
    dd(["Errors: " => $errors]);
}
firebed commented 9 months ago

Can you please provide the official myData documentation and the relevant legislation for sending Delivery Notes (Δελτία Αποστολής) that supports this PR?

memisibram commented 9 months ago

Article 37 mentioned on page 27

https://www.aade.gr/sites/default/files/2023-04/%CE%9F.%203029-2023.pdf

Άρθρο 37 «Χηφιακή έκδοση παραστατικών διακίνησης αγαθών – Σροποποίηση άρθρου 5 ν. 4308/2014»

Με το άρθρο 37 του κοινοποιούμενου νόμου προστέθηκαν στο άρθρο 5 του ν. 4308/2014 (Α΄ 251), περί ελληνικών λογιστικών προτύπων, παρ. 9Α, 9Β και 9Γ, ως εξής: 28 «9Α. Για την εκπλήρωση των υποχρεώσεων διακίνησης αγαθών των παρ. 8 και 9, τα σχετικά παραστατικά εκδίδονται ψηφιακά, φέρουν συγκεκριμένες προδιαγραφές και σημάνσεις και διαβιβάζονται απευθείας στην Ανεξάρτητη Αρχή Δημοσίων Εσόδων (Α.Α.Δ.Ε.). 9Β. Με κοινή απόφαση του Τπουργού Οικονομικών και του Διοικητή της Α.Α.Δ.Ε. εξειδικεύεται η έκταση εφαρμογής και καθορίζονται ο χρόνος διαβίβασης, οι εξαιρέσεις και η έναρξη ισχύος των υποχρεώσεων της παρ. 9Α. 9Γ. Με απόφαση του Διοικητή της Α.Α.Δ.Ε. καθορίζονται οι ειδικότερες υποχρεώσεις των υπόχρεων οντοτήτων της παρ. 9Α, οι προδιαγραφές, το περιεχόμενο και ο μορφότυπος των ψηφιακών παραστατικών διακίνησης, ο τρόπος και τα κανάλια διαβίβασης αυτών στην Α.Α.Δ.Ε., καθώς και οι διαδικασίες και λεπτομέρειες για την εφαρμογή των υποχρεώσεων της παρ. 9Α.»

You can also read this article dated 01/11/23. https://www.e-forologia.gr/cms/viewContents.aspx?id=230864

Official documentation for v1.0.8 https://www.aade.gr/epiheiriseis/mydata-ilektronika-biblia-aade/mydata/dokimastiko-periballon

Technical description of REST API v1.0.8 interfaces for transmitting & receiving data for ERP users -> paragraph 5.3.2 https://www.aade.gr/sites/default/files/2023-12/myDATA%20API%20Documentation%20v1.0.8_preofficial_erp_1.pdf

I am not a lawyer and I do not speak English. I communicate through translation. Please excuse any incomprehensible or complex sentences.

firebed commented 9 months ago

Looks like this PR only implements a part of the upcoming changes and there are some other changes that must be done in order to make the next release fully compatible with the mydata's v1.0.8 release. I've created a new branch and intend to merge this PR there and make the necessary changes until we cover everything on the new version. Is that ok with you?

memisibram commented 9 months ago

No problem from my perspective. I found this package while preparing something myself with xml data. Saved me a lot of trouble with a little tweaking, thanks for sharing.

There are definitely other changes that need to be made, I only added the Delivery Notes (Δελτία Αποστολής) section that was necessary for me. The strange thing is that they requested this in the relevant legislation, but even in the timologio application, there is no such option yet. :) Welcome to the mess created by the Greek government.

Finally, I am adding a photo of the output from the qrUrl result. I don't know if we should close this conversation or not. This is the first time I forked something on GitHub. Screenshot 2024-02-07 014458 Screenshot 2024-02-07 014621

firebed commented 9 months ago

Thanks for the feedback. I will make the necessary adjustments to your v3.1.7 branch. Please feel free to make your own commits to that branch. Hopefully if it all goes well we will make this PR to the production. Thank you!

firebed commented 8 months ago

Moving to branch https://github.com/firebed/aade-mydata/tree/v1.0.8