sj_royd/efaktura_service

电子发票平台

v1.0.4 2019-10-01 06:52 UTC

This package is auto-updated.

Last update: 2024-09-29 05:42:20 UTC


README

该库允许您下载并发送文档到电子发票平台(PEF)(https://efaktura.gov.pl/)。

PEF 适用于谁

电子发票平台(PEF)用于在公共采购承包商和招标当局之间转发发票和其他结构化文档。服务由两个PEF经纪人并行提供。

已根据PEPPOL BIS 3.0和CEFACT指南准备了已发送文档的实现。

1. 安装

$ composer require sj_royd/efaktura_service

2. 使用

<?php

use SJRoyd\PEF\PEF;
use SJRoyd\PEF\Error;

try {

    $pefID = 'user id'; // API user ID
    $pefSecret = 'user secret'; // API user secret
    $pefService = PEF::BROKER_INFINITE; // available PEF::BROKER_PEFEXPERT or PEF::BROKER_INFINITE

    $pef = new PEF($pefID, $pefSecret, $pefService);

    $queueLength = 0;
    do {
        // gets the first message from the queue
        $msgGeneral = $pef->queue->getMessage();
        $msg = $msgGeneral->getMessage();

        // gets the number of messages in the queue
        $queueLength = $pef->queue->getQueueLength();

        // if the message exists
        if($msg){
            // if the message indicates the existence of a document
            if($msgGeneral->getDocumentContent){
                // gets the content of the document
                $content = $pef->document->getDocumentContent($msg->documentId);

                // sets the status of the document to read
                $pef->document->readDocument($msg->documentId);

                // do something with the document, ex. save in a storage
            }

            // sets the status of the message to read last
            // because document->getDocumentContent() can throw
            // an Error\ClientError or Error\ServerError and we
            // can go back to the message next time
            $pef->queue->sendMessageAck($msg->messageId);
        }

    } while($queueLength > 1);

} catch (Error\AuthError $ex) {
    echo 'Auth error';
} catch (Error\ClientError $ex) {
    echo 'Client error';
} catch (Error\ServerError $ex) {
    echo 'Server error';
}

3. 操作

  • getMessage() 等待消息队列;位置 $pef->queue

    对于外部系统(标识为外部系统帐户),PEF系统维护一个指向它的消息队列。操作允许下载队列中的第一条消息。再次调用此操作将返回相同的消息,直到外部系统使用sendMessageAck()操作确认已正确处理该消息。

  • sendMessageAck() 确认接收消息;位置 $pef->queue

    操作允许确认最后下载的消息已被正确处理。调用此操作后,将会有新的消息(如果有的话)出现在消息队列中。调用此操作也意味着接收文档(在关于新传入文档的消息的上下文中)。

  • getQueueLength() 队列中消息的数量;位置 $pef->queue

    操作返回在执行操作getMessage()后队列中等待的消息数量。

  • sendDocument() 发送文档;位置 $pef->document

    操作允许将文档发送到PEF系统。

    您可以选择发送以下六种文档类型之一 - 辅助 Document\Type

    文档以Ubl或Cefact格式提供 - 辅助 Document\Format

    文档的接收者根据文档内容确定。PEF系统异步将文档发送给接收者。可以从消息队列中检索发送文档的状态信息。如果PEF系统正确接受文档,则此操作返回文档标识符(documentId)。该标识符应由外部系统保存,以便将消息队列中未来出现的关于该文档的消息关联起来。

  • getDocumentContent() 获取文档内容;位置 $pef->document

    操作允许获取来自另一个来源接收或发送的文档的内容(在Ubl格式中)。从收到关于新文档的消息的时间起,文档内容可保留7天。

  • readDocument() 标记文档为已读;位置 $pef->document

    操作允许传达外部系统用户已阅读文档的信息。

4. 消息队列

操作getMessage()返回SJRoyd\PEF\Response\Message对象,该对象包含以下五种类型之一的消息(如下)和有关getDocumentContent的信息,告诉消息是否已分配给要使用方法getDocumentContent()获取的文档。

getMessage()操作的getMessage()方法上返回特定的消息。每个消息都有一个messageId字段,用于标识消息,documentId是文档标识符。

可以使用switch块处理消息

<?php

$msgGen = $pef->message->getMessage();
$msg = $msgGen->getMessage();
switch(true) {
    case $msg instanceof Message\ReceivedDocumentStatusChanged:
        // do something
        break;
    case $msg instanceof Message\SentDocumentStatusChanged:
        // do something
        break;
    // etc...
}

if

<?php

$msgGen = $pef->message->getMessage();
if(($msg = $msgGen->receivedDocumentStatusChangedMessage)){
    // do something
}
if(($msg = $msgGen->sentDocumentStatusChangedMessage)){
    // do something
}
// etc...

4.1 消息 Message\ReceivedDocumentStatusChanged

关于接收到的文档状态变更的消息。当文档状态通过其他渠道(WEB应用或桌面应用)更改时,将触发此消息。

消息字段

  • messageId: uuid

  • documentId: uuid

  • status: 枚举 [ RECEIVED, READ ] - 辅助 Status\DocumentReceived

4.2 消息 Message\SentDocumentStatusChanged

关于已发送文档状态变更的消息。

消息字段

  • messageId: uuid

  • documentId: uuid

  • status: 枚举 [ PENDING, SENT, RECEIVED, READ ] - 辅助 Status\DocumentSend

4.3 消息 Message\SentDocumentErrorMessage

指示文档发送过程中出现错误的消息。

消息字段

  • messageId: uuid

  • documentId: uuid

  • errors: Message\Error 列表

    • errorCode: 枚举 [ 401, 402, 403, 404, 501 ]

    • errorMessage: 字符串

errorCode 根据字典

  • 401 错误请求

  • 402 文档内容验证错误

  • 403 收件人的端点未在PEPPOL网络中注册

  • 404 收件人不支持文档类型

  • 501 文档投递错误。尽管尝试重传,文档仍无法投递。

errorMessage - 错误的技术描述。描述旨在向技术人员(而非最终用户)展示错误。

4.4 消息 Message\DocumentReceived

通知您已收到文档的消息。可以使用 getDocumentContent() 操作下载文档内容。

消息字段

  • messageId: uuid

  • documentId: uuid

  • businessValidationReport: Message\BusinessValidationReport

    • reportDate: DateTime 对象

    • warnings: 枚举 [ EMPTY_CONTRACT_ID, EMPTY_ORDER_REFERENCE, EMPTY_DESPATCH_DOCUMENT_REFERENCE, EMPTY_RECEIPT_DOCUMENT_REFERENCE, EMPTY_INVOICE_DOCUMENT_REFERENCE, REFERENCED_ORDER_NOT_FOUND, REFERENCED_DESPATCH_NOT_FOUND, REFERENCED_RECEIPT_NOT_FOUND, REFERENCED_INVOICE_NOT_FOUND ] - 辅助 Message\Warning

  • documentType: 枚举 [ CREDIT_NOTE, DESPATCH_ADVICE, INVOICE, INVOICE_CORRECTION, ORDER, RECEIPT_ADVICE ] - 辅助 Document\Type

4.5 消息 Message\DocumentSentFromOtherSource

通知表示通过系统支持的邮箱(从WEB或桌面应用)通过其他渠道发送了文档。可以使用 getDocumentContent() 操作下载文档内容。

消息字段

  • messageId: uuid

  • documentId: uuid

  • documentType: 枚举 [ CREDIT_NOTE, DESPATCH_ADVICE, INVOICE, INVOICE_CORRECTION, ORDER, RECEIPT_ADVICE ] - 辅助 Document\Type

5. 辅助类

辅助类具有静态方法

  • getList(): list - 返回类中的常量列表

  • exists($const): boolean - 返回给定值是否存在作为常量的信息

辅助类 Document\Type

<?php

namespace SJRoyd\PEF\Helper\Document;

use SJRoyd\PEF\Helper\Constants;

class Type
{
    use Constants;

    const CREDIT_NOTE        = 'CREDIT_NOTE';
    const DESPATCH_ADVICE    = 'DESPATCH_ADVICE';
    const INVOICE            = 'INVOICE';
    const INVOICE_CORRECTION = 'INVOICE_CORRECTION';
    const ORDER              = 'ORDER';
    const RECEIPT_ADVICE     = 'RECEIPT_ADVICE';

}

辅助类 Document\Format

<?php

namespace SJRoyd\PEF\Helper\Document;

use SJRoyd\PEF\Helper\Constants;

class Format
{
    use Constants;

    const UBL    = 'Ubl';
    const CEFACT = 'Cefact';

}

辅助类 Status\DocumentReceived

<?php

namespace SJRoyd\PEF\Helper\Status;

use SJRoyd\PEF\Helper\Constants;

class DocumentReceived
{
    use Constants;

    const RECEIVED  = 'RECEIVED';
    const READ      = 'READ';

}

辅助类 Status\DocumentSend

<?php

namespace SJRoyd\PEF\Helper\Status;

use SJRoyd\PEF\Helper\Constants;

class DocumentSend
{
    use Constants;

    const PENDING   = 'PENDING';
    const SENT      = 'SENT';
    const RECEIVED  = 'RECEIVED';
    const READ      = 'READ';

}

辅助类 Message\Warning

<?php

namespace SJRoyd\PEF\Helper\Message;

use SJRoyd\PEF\Helper\Constants;

class Warning
{
    use Constants;

    const EMPTY_CONTRACT_ID                 = 'EMPTY_CONTRACT_ID';
    const EMPTY_ORDER_REFERENCE             = 'EMPTY_ORDER_REFERENCE';
    const EMPTY_DESPATCH_DOCUMENT_REFERENCE = 'EMPTY_DESPATCH_DOCUMENT_REFERENCE';
    const EMPTY_RECEIPT_DOCUMENT_REFERENCE  = 'EMPTY_RECEIPT_DOCUMENT_REFERENCE';
    const EMPTY_INVOICE_DOCUMENT_REFERENCE  = 'EMPTY_INVOICE_DOCUMENT_REFERENCE';
    const REFERENCED_ORDER_NOT_FOUND        = 'REFERENCED_ORDER_NOT_FOUND';
    const REFERENCED_DESPATCH_NOT_FOUND     = 'REFERENCED_DESPATCH_NOT_FOUND';
    const REFERENCED_RECEIPT_NOT_FOUND      = 'REFERENCED_RECEIPT_NOT_FOUND';
    const REFERENCED_INVOICE_NOT_FOUND      = 'REFERENCED_INVOICE_NOT_FOUND';
}