1
0
mirror of synced 2024-12-04 10:46:02 +03:00

Refactoring bundle

This commit is contained in:
Ivan Lutokhin 2020-11-01 16:29:28 +03:00 committed by Ivan Lutokhin
parent 55d762ca82
commit 27382bc04c
159 changed files with 2778 additions and 6653 deletions

View File

@ -12,7 +12,9 @@ before_script:
- composer install $flags
script:
- php vendor/bin/php-cs-fixer fix --diff --dry-run --using-cache no --config .php_cs
- php vendor/bin/psalm
- php vendor/bin/php-cs-fixer fix --diff --dry-run --using-cache=no --config=.php_cs
- php vendor/bin/phpunit -c phpunit.xml
after_success:
- bash <(curl -s https://codecov.io/bash)
- bash <(curl -s https://codecov.io/bash)

View File

@ -1,99 +0,0 @@
<?php
namespace RetailCrm\DeliveryModuleBundle\Command;
use Doctrine\ORM\Tools\Pagination\Paginator;
use RetailCrm\DeliveryModuleBundle\Exception\AbstractModuleException;
use RetailCrm\DeliveryModuleBundle\Service\AccountManager;
use RetailCrm\DeliveryModuleBundle\Service\ModuleManagerInterface;
use Symfony\Component\Console\Command\Command;
use Symfony\Component\Console\Command\LockableTrait;
use Symfony\Component\Console\Input\InputArgument;
use Symfony\Component\Console\Input\InputInterface;
use Symfony\Component\Console\Output\OutputInterface;
class StatusesCommand extends Command
{
use LockableTrait;
/**
* @var ModuleManagerInterface
*/
private $moduleManager;
/**
* @var AccountManager
*/
private $accountManager;
/**
* {@inheritdoc}
*/
protected function configure()
{
$this
->setName('statuses:update')
->setDescription('Update statuses')
->addArgument('accountId', InputArgument::OPTIONAL, 'Choose account, or make it for all');
}
public function __construct(ModuleManagerInterface $moduleManager, AccountManager $accountManager)
{
$this->moduleManager = $moduleManager;
$this->accountManager = $accountManager;
parent::__construct();
}
/**
* {@inheritdoc}
*/
protected function execute(InputInterface $input, OutputInterface $output)
{
if (!$this->lock()) {
$output->writeln('The command is already running in another process.');
return 0;
}
$accountId = $input->getArgument('accountId')
? (int) $input->getArgument('accountId')
: null;
$paginator = [];
if (null !== $accountId) {
$paginator = [$this->accountManager - find($accountId)];
} else {
$accountQuery = $this->accountManager->getRepository()
->createQueryBuilder('account')
->where('account.active = true')
->andWhere('account.freeze != true')
->addOrderBy('account.id')
->getQuery()
->setFirstResult(0)
->setMaxResults(100);
$paginator = new Paginator($accountQuery);
}
$count = 0;
foreach ($paginator as $account) {
try {
$count += $this->moduleManager
->setAccount($account)
->updateStatuses()
;
} catch (AbstractModuleException $e) {
$output->writeln(
"<error>Failed to update statuses for account {$account->getCrmUrl()}[{$account->getId()}]</error>"
);
$output->writeln("<error>Error: {$e->getMessage()}</error>");
}
}
$output->writeln("<info>{$count} statuses updated.</info>");
$this->release();
return 0;
}
}

View File

@ -1,99 +0,0 @@
<?php
namespace RetailCrm\DeliveryModuleBundle\Command;
use Doctrine\ORM\Tools\Pagination\Paginator;
use RetailCrm\DeliveryModuleBundle\Service\AccountManager;
use RetailCrm\DeliveryModuleBundle\Service\ModuleManagerInterface;
use Symfony\Component\Console\Command\Command;
use Symfony\Component\Console\Command\LockableTrait;
use Symfony\Component\Console\Input\InputArgument;
use Symfony\Component\Console\Input\InputInterface;
use Symfony\Component\Console\Output\OutputInterface;
class UpdateModuleCommand extends Command
{
use LockableTrait;
/**
* @var ModuleManagerInterface
*/
private $moduleManager;
/**
* @var AccountManager
*/
private $accountManager;
/**
* {@inheritdoc}
*/
protected function configure()
{
$this
->setName('module:update')
->setDescription('Update module')
->addArgument('accountId', InputArgument::OPTIONAL, 'Choose account, or make it for all');
}
public function __construct(ModuleManagerInterface $moduleManager, AccountManager $accountManager)
{
$this->moduleManager = $moduleManager;
$this->accountManager = $accountManager;
parent::__construct();
}
/**
* {@inheritdoc}
*/
protected function execute(InputInterface $input, OutputInterface $output)
{
if (!$this->lock()) {
$output->writeln('The command is already running in another process.');
return 0;
}
$accountId = $input->getArgument('accountId')
? $input->getArgument('accountId')
: null;
$paginator = [];
if (null !== $accountId) {
$paginator = [$this->accountManager->find($accountId)];
} else {
$accountQuery = $this->accountManager->getRepository()
->createQueryBuilder('account')
->where('account.active = true')
->andWhere('account.freeze != true')
->addOrderBy('account.id')
->getQuery()
->setFirstResult(0)
->setMaxResults(100);
$paginator = new Paginator($accountQuery);
}
$count = 0;
foreach ($paginator as $account) {
try {
$this->moduleManager
->setAccount($account)
->updateModuleConfiguration()
;
++$count;
} catch (\Exception $e) {
$output->writeln(
"<error>Failed to update configuration for account {$account->getCrmUrl()}[{$account->getId()}]</error>"
);
$output->writeln("<error>Error: {$e->getMessage()}</error>");
}
}
$output->writeln("<info>{$count} modules updated.</info>");
$this->release();
return 0;
}
}

View File

@ -1,462 +0,0 @@
<?php
namespace RetailCrm\DeliveryModuleBundle\Controller;
use JMS\Serializer\DeserializationContext;
use JMS\Serializer\Exception\Exception as JmsException;
use JMS\Serializer\SerializationContext;
use JMS\Serializer\SerializerInterface;
use RetailCrm\DeliveryModuleBundle\Exception;
use RetailCrm\DeliveryModuleBundle\Model\AbstractResponseSuccessful;
use RetailCrm\DeliveryModuleBundle\Model\Calculate;
use RetailCrm\DeliveryModuleBundle\Model\Entity\DeliveryOrder;
use RetailCrm\DeliveryModuleBundle\Model\IntegrationModule;
use RetailCrm\DeliveryModuleBundle\Model\RequestCalculate;
use RetailCrm\DeliveryModuleBundle\Model\RequestDelete;
use RetailCrm\DeliveryModuleBundle\Model\RequestPrint;
use RetailCrm\DeliveryModuleBundle\Model\RequestSave;
use RetailCrm\DeliveryModuleBundle\Model\RequestShipmentDelete;
use RetailCrm\DeliveryModuleBundle\Model\RequestShipmentPointList;
use RetailCrm\DeliveryModuleBundle\Model\RequestShipmentSave;
use RetailCrm\DeliveryModuleBundle\Model\ResponseCalculateSuccessful;
use RetailCrm\DeliveryModuleBundle\Model\ResponseLoadDeliveryData;
use RetailCrm\DeliveryModuleBundle\Model\ResponseSave;
use RetailCrm\DeliveryModuleBundle\Model\ResponseShipmentPointListSuccessful;
use RetailCrm\DeliveryModuleBundle\Model\ResponseShipmentSave;
use RetailCrm\DeliveryModuleBundle\Model\ResponseSuccessful;
use RetailCrm\DeliveryModuleBundle\Service\AccountManager;
use RetailCrm\DeliveryModuleBundle\Service\DeliveryOrderManager;
use RetailCrm\DeliveryModuleBundle\Service\ModuleManager;
use RetailCrm\DeliveryModuleBundle\Service\ModuleManagerInterface;
use Symfony\Bundle\FrameworkBundle\Controller\AbstractController;
use Symfony\Component\HttpFoundation\JsonResponse;
use Symfony\Component\HttpFoundation\Request;
use Symfony\Component\HttpFoundation\RequestStack;
use Symfony\Component\HttpFoundation\Response;
use Symfony\Component\HttpKernel\Exception as SymfonyException;
class ApiController extends AbstractController implements ClientIdSecuredControllerInterface
{
/**
* @var SerializerInterface
*/
protected $jmsSerializer;
/**
* @var ModuleManager
*/
protected $moduleManager;
/**
* @var AccountManager
*/
protected $accountManager;
/**
* @var DeliveryOrderManager
*/
protected $deliveryOrderManager;
public function __construct(
SerializerInterface $jmsSerializer,
ModuleManagerInterface $moduleManager,
AccountManager $accountManager,
DeliveryOrderManager $deliveryOrderManager,
RequestStack $requestStack
) {
$this->jmsSerializer = $jmsSerializer;
$this->moduleManager = $moduleManager;
$this->accountManager = $accountManager;
$this->deliveryOrderManager = $deliveryOrderManager;
}
public function activity(Request $request): JsonResponse
{
if (!is_string($request->request->get('activity'))) {
return $this->getInvalidResponse('Parameter "activity" must be json', 400);
}
$activity = $request->request->get('activity');
try {
$requestModel = $this->jmsSerializer->deserialize(
$activity,
IntegrationModule::class,
'json',
DeserializationContext::create()->setGroups(['activity'])
);
} catch (JmsException $e) {
return $this->getInvalidResponse($e->getMessage(), 400);
}
$this->moduleManager->getAccount()->setActive($requestModel->active);
$this->moduleManager->getAccount()->setFreeze($requestModel->freeze);
$systemUrl = $request->request->get('systemUrl');
$this->moduleManager->getAccount()->setCrmUrl($systemUrl);
$this->accountManager->flush();
return $this->getSucessfullResponse();
}
public function calculate(Request $request): JsonResponse
{
if (!is_string($request->request->get('calculate'))) {
return $this->getInvalidResponse('Parameter "calculate" must be json', 400);
}
$requestData = $request->request->get('calculate');
try {
$requestModel = $this->jmsSerializer->deserialize(
$requestData,
RequestCalculate::class,
'json',
DeserializationContext::create()->setGroups(['get', 'request'])
);
} catch (JmsException $e) {
return $this->getInvalidResponse($e->getMessage(), 400);
}
try {
$responseModel = $this->doCalculate($requestModel);
} catch (Exception\ServerUnreachableException $e) {
return $this->getInvalidResponse($e->getMessage(), 521);
} catch (Exception\AbstractModuleException $e) {
return $this->getInvalidResponse($e->getMessage(), 400);
}
$response = new ResponseCalculateSuccessful($responseModel);
$response->result = $responseModel;
return $this->getSucessfullResponse($response);
}
public function save(Request $request): JsonResponse
{
if (!is_string($request->request->get('save'))) {
return $this->getInvalidResponse('Parameter "save" must be json', 400);
}
$requestData = $request->request->get('save');
try {
$requestModel = $this->jmsSerializer->deserialize(
$requestData,
RequestSave::class,
'json',
DeserializationContext::create()->setGroups(['get', 'request'])
);
} catch (JmsException $e) {
return $this->getInvalidResponse($e->getMessage(), 400);
}
if (null === $requestModel->delivery) {
return $this->getInvalidResponse('Invalid request format', 400);
}
$delivery = $this->deliveryOrderManager->findOneBy([
'account' => $this->moduleManager->getAccount(),
'orderId' => $requestModel->order,
]);
// ищем доставки, созданные без заказа в запросе get
if (null === $delivery) {
$delivery = $this->deliveryOrderManager
->findOneBy([
'account' => $this->moduleManager->getAccount(),
'externalId' => $requestModel->deliveryId,
]);
}
try {
$responseModel = $this->doSave($requestModel, $delivery);
} catch (Exception\ServerUnreachableException $e) {
return $this->getInvalidResponse($e->getMessage(), 521);
} catch (Exception\AbstractModuleException $e) {
return $this->getInvalidResponse($e->getMessage(), 400);
}
if (null === $delivery) {
$delivery = $this->deliveryOrderManager->create();
}
$delivery
->setAccount($this->moduleManager->getAccount())
->setOrderId($requestModel->order)
->setExternalId($responseModel->deliveryId)
;
if ($responseModel->trackNumber) {
$delivery->setTrackNumber($responseModel->trackNumber);
}
if (is_array($responseModel->additionalData)) {
foreach ($responseModel->additionalData as $key => $value) {
$setter = 'set' . ucfirst($key);
if (is_callable([$delivery, $setter])) {
$delivery->$setter($value);
}
}
}
if (empty($delivery->getId())) {
$this->deliveryOrderManager->persist($delivery);
}
$this->deliveryOrderManager->flush();
return $this->getSucessfullResponse($responseModel);
}
public function getDeliveryOrder(Request $request): JsonResponse
{
$externalId = $request->query->get('deliveryId');
if (null === $externalId || empty($externalId)) {
return $this->getInvalidResponse('DeliveryId is required', 400);
}
try {
$responseModel = $this->doGet($externalId);
} catch (Exception\ServerUnreachableException $e) {
return $this->getInvalidResponse($e->getMessage(), 521);
} catch (Exception\AbstractModuleException $e) {
return $this->getInvalidResponse($e->getMessage(), 400);
}
return $this->getSucessfullResponse($responseModel);
}
public function delete(Request $request): JsonResponse
{
if (!is_string($request->request->get('delete'))) {
return $this->getInvalidResponse('Parameter "delete" must be json', 400);
}
$requestData = $request->request->get('delete');
try {
$requestModel = $this->jmsSerializer->deserialize(
$requestData,
RequestDelete::class,
'json',
DeserializationContext::create()->setGroups(['get', 'request'])
);
} catch (JmsException $e) {
return $this->getInvalidResponse($e->getMessage(), 400);
}
$delivery = $this->deliveryOrderManager->findOneBy([
'account' => $this->moduleManager->getAccount(),
'externalId' => $requestModel->deliveryId,
]);
if (null === $delivery) {
return $this->getInvalidResponse("Delivery '{$requestModel->deliveryId}' not found", 404);
}
try {
$this->doDelete($requestModel, $delivery);
} catch (Exception\ServerUnreachableException $e) {
return $this->getInvalidResponse($e->getMessage(), 521);
} catch (Exception\AbstractModuleException $e) {
return $this->getInvalidResponse($e->getMessage(), 400);
}
$this->deliveryOrderManager->remove($delivery);
$this->deliveryOrderManager->flush();
return $this->getSucessfullResponse();
}
public function shipmentPointList(Request $request): JsonResponse
{
$requestData = json_encode($request->query->all());
try {
$requestModel = $this->jmsSerializer->deserialize(
$requestData,
RequestShipmentPointList::class,
'json',
DeserializationContext::create()->setGroups(['get', 'request'])
);
} catch (JmsException $e) {
return $this->getInvalidResponse($e->getMessage(), 400);
}
try {
$responseModel = $this->doShipmentPointList($requestModel);
} catch (Exception\ServerUnreachableException $e) {
return $this->getInvalidResponse($e->getMessage(), 521);
} catch (Exception\AbstractModuleException $e) {
return $this->getInvalidResponse($e->getMessage(), 400);
}
$response = new ResponseShipmentPointListSuccessful($responseModel);
$response->result = $responseModel;
return $this->getSucessfullResponse($response);
}
public function print(Request $request): Response
{
if (!is_string($request->request->get('print'))) {
return $this->getInvalidResponse('Parameter "print" must be json', 400);
}
$requestData = $request->request->get('print');
try {
$requestModel = $this->jmsSerializer->deserialize(
$requestData,
RequestPrint::class,
'json',
DeserializationContext::create()->setGroups(['get', 'request'])
);
} catch (JmsException $e) {
return $this->getInvalidResponse($e->getMessage(), 400);
}
try {
$plateData = $this->doPrint($requestModel);
} catch (Exception\ServerUnreachableException $e) {
return $this->getInvalidResponse($e->getMessage(), 521);
} catch (Exception\NotFoundException $e) {
return $this->getInvalidResponse($e->getMessage(), 404);
} catch (Exception\AbstractModuleException $e) {
return $this->getInvalidResponse($e->getMessage(), 400);
}
if (count($plateData) > 1) {
$tmpFilename = tempnam(sys_get_temp_dir(), 'zip');
$labelArchive = new \ZipArchive();
$labelArchive->open($tmpFilename, \ZipArchive::CREATE);
foreach ($plateData as $fileName => $plate) {
$labelArchive->addFromString($fileName, $plate);
}
$labelArchive->close();
$contents = file_get_contents($tmpFilename);
unlink($tmpFilename);
$response = new Response($contents);
$response->headers->set('Content-Type', 'application/zip');
} else {
$response = new Response(reset($plateData));
$response->headers->set('Content-Type', 'application/pdf');
}
return $response;
}
public function shipmentSave(Request $request): JsonResponse
{
if (!is_string($request->request->get('shipmentSave'))) {
return $this->getInvalidResponse('Parameter "shipmentSave" must be json', 400);
}
$requestData = $request->request->get('shipmentSave');
try {
$requestModel = $this->jmsSerializer->deserialize(
$requestData,
RequestShipmentSave::class,
'json',
DeserializationContext::create()->setGroups(['get', 'request'])
);
} catch (JmsException $e) {
return $this->getInvalidResponse($e->getMessage(), 400);
}
try {
$responseModel = $this->doShipmentSave($requestModel);
} catch (Exception\ServerUnreachableException $e) {
return $this->getInvalidResponse($e->getMessage(), 521);
} catch (Exception\AbstractModuleException $e) {
return $this->getInvalidResponse($e->getMessage(), 400);
}
return $this->getSucessfullResponse($responseModel);
}
public function shipmentDelete(Request $request): JsonResponse
{
if (!is_string($request->request->get('shipmentDelete'))) {
return $this->getInvalidResponse('Parameter "shipmentDelete" must be json', 400);
}
$requestData = $request->request->get('shipmentDelete');
try {
$requestModel = $this->jmsSerializer->deserialize(
$requestData,
RequestShipmentDelete::class,
'json',
DeserializationContext::create()->setGroups(['get', 'request'])
);
} catch (JmsException $e) {
return $this->getInvalidResponse($e->getMessage(), 400);
}
try {
$this->doShipmentDelete($requestModel);
} catch (Exception\ServerUnreachableException $e) {
return $this->getInvalidResponse($e->getMessage(), 521);
} catch (Exception\AbstractModuleException $e) {
return $this->getInvalidResponse($e->getMessage(), 400);
}
return $this->getSucessfullResponse();
}
protected function getSucessfullResponse(object $responseResult = null): JsonResponse
{
if (!$responseResult instanceof AbstractResponseSuccessful) {
$response = new ResponseSuccessful();
$response->result = $responseResult;
} else {
$response = $responseResult;
}
$responseData = $this->jmsSerializer
->serialize($response, 'json', SerializationContext::create()->setGroups(['response']));
return new JsonResponse(json_decode($responseData, true));
}
protected function getInvalidResponse(string $message, int $statusCode): JsonResponse
{
if ($statusCode >= 500) {
//корректно отдается в crm только в окружении prod
throw new SymfonyException\HttpException($statusCode, json_encode(['success' => false, 'errorMsg' => $message]));
}
return new JsonResponse([
'success' => false,
'errorMsg' => $message,
], $statusCode);
}
protected function doCalculate(RequestCalculate $requestModel): array
{
return $this->moduleManager->calculateDelivery($requestModel);
}
protected function doGet(string $externalId): ResponseLoadDeliveryData
{
return $this->moduleManager->getDelivery($externalId);
}
protected function doSave(RequestSave $requestModel, DeliveryOrder $delivery = null): ResponseSave
{
return $this->moduleManager->saveDelivery($requestModel, $delivery);
}
protected function doDelete(RequestDelete $requestModel, DeliveryOrder $delivery): bool
{
return $this->moduleManager->deleteDelivery($requestModel, $delivery);
}
protected function doShipmentPointList(RequestShipmentPointList $requestModel): array
{
return $this->moduleManager->shipmentPointList($requestModel);
}
protected function doShipmentSave(RequestShipmentSave $requestModel): ResponseShipmentSave
{
return $this->moduleManager->saveShipment($requestModel);
}
protected function doShipmentDelete(RequestShipmentDelete $requestModel): bool
{
return $this->moduleManager->deleteShipment($requestModel);
}
protected function doPrint(RequestPrint $requestModel)
{
return $this->moduleManager->printDocument($requestModel);
}
}

View File

@ -1,7 +0,0 @@
<?php
namespace RetailCrm\DeliveryModuleBundle\Controller;
interface ClientIdSecuredControllerInterface
{
}

View File

@ -1,70 +0,0 @@
<?php
namespace RetailCrm\DeliveryModuleBundle\DependencyInjection;
use Symfony\Component\Config\Definition\Builder\TreeBuilder;
use Symfony\Component\Config\Definition\ConfigurationInterface;
class Configuration implements ConfigurationInterface
{
protected static $availableLocales = ['ru', 'en', 'es'];
/**
* {@inheritdoc}
*/
public function getConfigTreeBuilder()
{
$treeBuilder = new TreeBuilder('retail_crm_delivery_module');
$rootNode = $treeBuilder->getRootNode();
$rootNode
->children()
->scalarNode('module_manager_class')
->cannotBeEmpty()
->end()
->scalarNode('account_class')
->isRequired()
->cannotBeEmpty()
->end()
->scalarNode('delivery_order_class')
->isRequired()
->cannotBeEmpty()
->end()
->arrayNode('configuration')
->children()
->scalarNode('integration_code')
->cannotBeEmpty()
->end()
->arrayNode('countries')
->prototype('scalar')->end()
->requiresAtLeastOneElement()
->defaultValue(['ru'])
->end()
->arrayNode('locales')
->requiresAtLeastOneElement()
->useAttributeAsKey('locale')
->arrayPrototype()
->children()
->scalarNode('name')
->isRequired()
->end()
->scalarNode('logo')
->isRequired()
->end()
->end()
->end()
->end()
->variableNode('parameters')->end()
->end()
->end()
->end()
;
return $treeBuilder;
}
}

View File

@ -1,75 +0,0 @@
<?php
namespace RetailCrm\DeliveryModuleBundle\DependencyInjection;
use RetailCrm\DeliveryModuleBundle\Model\Entity\Account;
use RetailCrm\DeliveryModuleBundle\Model\Entity\DeliveryOrder;
use RetailCrm\DeliveryModuleBundle\Service\ModuleManagerInterface;
use Symfony\Component\Config\FileLocator;
use Symfony\Component\DependencyInjection\ContainerBuilder;
use Symfony\Component\DependencyInjection\Extension\Extension;
use Symfony\Component\DependencyInjection\Loader;
/**
* This is the class that loads and manages your bundle configuration.
*
* To learn more see {@link http://symfony.com/doc/current/cookbook/bundles/extension.html}
*/
class RetailCrmDeliveryModuleExtension extends Extension
{
/**
* {@inheritdoc}
*/
public function load(array $configs, ContainerBuilder $container)
{
$loader = new Loader\YamlFileLoader(
$container,
new FileLocator(dirname(__DIR__) . '/Resources/config')
);
$loader->load('services.yaml');
$configuration = new Configuration();
$config = $this->processConfiguration($configuration, $configs);
$container->setParameter(
'retailcrm.delivery_module.configuration',
$config['configuration']
);
$moduleManagerClass = $config['module_manager_class'];
if (!class_exists($moduleManagerClass)) {
throw new \InvalidArgumentException("module_manager_class '{$moduleManagerClass}' does not exists");
}
if (!is_subclass_of($moduleManagerClass, ModuleManagerInterface::class)) {
throw new \InvalidArgumentException("module_manager_class '{$moduleManagerClass}' must implement ModuleManagerInterace");
}
$container->setParameter(
'retailcrm.delivery_module.module_manager.class',
$moduleManagerClass
);
$accountClass = $config['account_class'];
if (!class_exists($accountClass)) {
throw new \InvalidArgumentException("account_class'] '{$accountClass}' does not exists");
}
if (!is_subclass_of($accountClass, Account::class)) {
throw new \InvalidArgumentException("account_class '{$accountClass}' must extend " . Account::class);
}
$container->setParameter(
'retailcrm.delivery_module.account.class',
$accountClass
);
$deliveryOrderClass = $config['delivery_order_class'];
if (!class_exists($deliveryOrderClass)) {
throw new \InvalidArgumentException("delivery_order_class'] '{$deliveryOrderClass}' does not exists");
}
if (!is_subclass_of($deliveryOrderClass, DeliveryOrder::class)) {
throw new \InvalidArgumentException("delivery_order_class '{$deliveryOrderClass}' must extend " . DeliveryOrder::class);
}
$container->setParameter(
'retailcrm.delivery_module.delivery_order.class',
$config['delivery_order_class']
);
}
}

View File

@ -1,72 +0,0 @@
<?php
namespace RetailCrm\DeliveryModuleBundle\EventSubscriber;
use Ramsey\Uuid\Uuid;
use RetailCrm\DeliveryModuleBundle\Controller\ClientIdSecuredControllerInterface;
use RetailCrm\DeliveryModuleBundle\Service\AccountManager;
use RetailCrm\DeliveryModuleBundle\Service\ModuleManagerInterface;
use Symfony\Component\EventDispatcher\EventSubscriberInterface;
use Symfony\Component\HttpKernel\Event\ControllerEvent;
use Symfony\Component\HttpKernel\Exception\AccessDeniedHttpException;
use Symfony\Component\HttpKernel\KernelEvents;
class ClientIdSubscriber implements EventSubscriberInterface
{
/**
* @var AccountManager
*/
private $accountManager;
/**
* @var ModuleManagerInterface
*/
private $moduleManager;
public function __construct(AccountManager $accountManager, ModuleManagerInterface $moduleManager)
{
$this->accountManager = $accountManager;
$this->moduleManager = $moduleManager;
}
public static function getSubscribedEvents()
{
return [
KernelEvents::CONTROLLER => 'onKernelController',
];
}
public function onKernelController(ControllerEvent $event)
{
$controller = $event->getController();
if (is_array($controller)) {
$controller = $controller[0];
}
if (!$controller instanceof ClientIdSecuredControllerInterface) {
return;
}
$request = $event->getRequest();
if ($request->isMethod('post')) {
$clientId = $request->request->get('clientId');
} else {
$clientId = $request->query->get('clientId');
}
if (empty($clientId)) {
throw new AccessDeniedHttpException('ClientId required');
}
if (!Uuid::isValid($clientId)) {
throw new AccessDeniedHttpException('ClientId is not valid');
}
$account = $this->accountManager->findOneBy(['clientId' => $clientId]);
if (null === $account) {
throw new AccessDeniedHttpException('ClientId not found');
}
$this->moduleManager->setAccount($account);
}
}

View File

@ -1,27 +0,0 @@
<?php
namespace RetailCrm\DeliveryModuleBundle\EventSubscriber;
use JMS\Serializer\EventDispatcher\Events;
use JMS\Serializer\EventDispatcher\EventSubscriberInterface;
use JMS\Serializer\EventDispatcher\PreSerializeEvent;
use RetailCrm\DeliveryModuleBundle\Model\ResponseResult;
class SerializeListener implements EventSubscriberInterface
{
public static function getSubscribedEvents()
{
return [
['event' => Events::PRE_SERIALIZE, 'method' => 'onPreSerialize', 'class' => ResponseResult::class],
];
}
public function onPreSerialize(PreSerializeEvent $event)
{
if (is_object($event->getObject())) {
$event->setType(get_class($event->getObject()));
} else {
$event->setType('string');
}
}
}

View File

@ -1,7 +0,0 @@
<?php
namespace RetailCrm\DeliveryModuleBundle\Exception;
abstract class AbstractModuleException extends \Exception
{
}

View File

@ -1,7 +0,0 @@
<?php
namespace RetailCrm\DeliveryModuleBundle\Exception;
class ApiException extends AbstractModuleException
{
}

View File

@ -1,7 +0,0 @@
<?php
namespace RetailCrm\DeliveryModuleBundle\Exception;
class NotFoundException extends AbstractModuleException
{
}

View File

@ -1,7 +0,0 @@
<?php
namespace RetailCrm\DeliveryModuleBundle\Exception;
class RetailCrmApiException extends \Exception
{
}

View File

@ -1,7 +0,0 @@
<?php
namespace RetailCrm\DeliveryModuleBundle\Exception;
class ServerUnreachableException extends AbstractModuleException
{
}

View File

@ -1,7 +0,0 @@
<?php
namespace RetailCrm\DeliveryModuleBundle\Exception;
class ValidationException extends AbstractModuleException
{
}

View File

@ -1,17 +0,0 @@
<?php
namespace RetailCrm\DeliveryModuleBundle\Model;
use JMS\Serializer\Annotation as Serializer;
abstract class AbstractResponseSuccessful
{
/**
* @var bool
*
* @Serializer\Groups({"get", "response"})
* @Serializer\SerializedName("success")
* @Serializer\Type("boolean")
*/
public $success = true;
}

View File

@ -1,207 +0,0 @@
<?php
namespace RetailCrm\DeliveryModuleBundle\Model;
use JMS\Serializer\Annotation as Serializer;
class Configuration
{
const PAYER_TYPE_RECEIVER = 'receiver';
const PAYER_TYPE_SENDER = 'sender';
const ACTION_CALCULATE = 'calculate';
const ACTION_SAVE = 'save';
const ACTION_GET = 'get';
const ACTION_DELETE = 'delete';
const ACTION_PRINT = 'print';
const ACTION_SHIPMENT_SAVE = 'shipmentSave';
const ACTION_SHIPMENT_DELETE = 'shipmentDelete';
const ACTION_SHIPMENT_POINT_LIST = 'shipmentPointList';
/**
* Описание подключения.
*
* @var string
*
* @Serializer\Groups({"set", "get"})
* @Serializer\SerializedName("description")
* @Serializer\Type("string")
*/
public $description;
/**
* Относительные пути от базового URL до конкретных методов.
*
* @var array
*
* @Serializer\Groups({"set", "get"})
* @Serializer\SerializedName("actions")
* @Serializer\Type("array<string, string>")
*/
public $actions;
/**
* Допустивые типы плательщиков за доставку.
*
* @var array
*
* @Serializer\Groups({"set", "get"})
* @Serializer\SerializedName("payerType")
* @Serializer\Type("array")
*/
public $payerType;
/**
* Максимальное количество заказов при печати документов.
*
* @var int
*
* @Serializer\Groups({"set", "get"})
* @Serializer\SerializedName("platePrintLimit")
* @Serializer\Type("integer")
*/
public $platePrintLimit = 100;
/**
* В методе calculate расчитывается стоимость доставки.
*
* @var bool
*
* @Serializer\Groups({"set", "get"})
* @Serializer\SerializedName("rateDeliveryCost")
* @Serializer\Type("boolean")
*/
public $rateDeliveryCost = true;
/**
* Разрешить использование упаковок.
*
* @var bool
*
* @Serializer\Groups({"set", "get"})
* @Serializer\SerializedName("allowPackages")
* @Serializer\Type("boolean")
*/
public $allowPackages = false;
/**
* Доставка наложенным платежом доступна/не доступна.
*
* @var bool
*
* @Serializer\Groups({"set", "get"})
* @Serializer\SerializedName("codAvailable")
* @Serializer\Type("boolean")
*/
public $codAvailable = false;
/**
* Возможен самопривоз на терминал.
*
* @var bool
*
* @Serializer\Groups({"set", "get"})
* @Serializer\SerializedName("selfShipmentAvailable")
* @Serializer\Type("boolean")
*/
public $selfShipmentAvailable = false;
/**
* Возможность работы с заказом, содержащим несколько позиций с одинаковым торговым предложением
*
* @var bool
*
* @Serializer\Groups({"set", "get"})
* @Serializer\SerializedName("duplicateOrderProductSupported")
* @Serializer\Type("boolean")
*/
public $duplicateOrderProductSupported = true;
/**
* Разрешить отдельно передавать трек номер
*
* @var string
*
* @Serializer\Groups({"set", "get"})
* @Serializer\SerializedName("allowTrackNumber")
* @Serializer\Type("boolean")
*/
public $allowTrackNumber;
/**
* Список стран откуда можно отправить посылку. Если массив пустой, то нет ограничения на страны.
*
* @var array
*
* @Serializer\Groups({"set", "get"})
* @Serializer\SerializedName("availableCountries")
* @Serializer\Type("array")
*/
public $availableCountries;
/**
* Список обязательных полей заказа.
*
* @var array
*
* @Serializer\Groups({"set", "get"})
* @Serializer\SerializedName("requiredFields")
* @Serializer\Type("array")
*/
public $requiredFields;
/**
* Список статусов службы доставки.
*
* @var Status[]
*
* @Serializer\Groups({"set", "get"})
* @Serializer\SerializedName("statusList")
* @Serializer\Type("array<RetailCrm\DeliveryModuleBundle\Model\Status>")
*/
public $statusList;
/**
* Список печатных форм, предоставляемых службой.
*
* @var Plate[]
*
* @Serializer\Groups({"set", "get"})
* @Serializer\SerializedName("plateList")
* @Serializer\Type("array<RetailCrm\DeliveryModuleBundle\Model\Plate>")
*/
public $plateList;
/**
* Список дополнительных полей, необходимых для оформления доставки.
*
* @var DeliveryDataField[]
*
* @Serializer\Groups({"set", "get"})
* @Serializer\SerializedName("deliveryDataFieldList")
* @Serializer\Type("array<RetailCrm\DeliveryModuleBundle\Model\DeliveryDataField>")
*/
public $deliveryDataFieldList;
/**
* Список дополнительных полей, необходимых для заявки на отгрузку.
*
* @var DeliveryDataField[]
*
* @Serializer\Groups({"set", "get"})
* @Serializer\SerializedName("shipmentDataFieldList")
* @Serializer\Type("array<RetailCrm\DeliveryModuleBundle\Model\DeliveryDataField>")
*/
public $shipmentDataFieldList;
/**
* Массив настроек модуля
*
* @var Settings
*
* @Serializer\Groups({"set", "get"})
* @Serializer\SerializedName("settings")
* @Serializer\Type("RetailCrm\DeliveryModuleBundle\Model\Settings")
*/
public $settings;
}

View File

@ -1,68 +0,0 @@
<?php
namespace RetailCrm\DeliveryModuleBundle\Model;
use JMS\Serializer\Annotation as Serializer;
class Contragent
{
const TYPE_INDIVIDUAL = 'individual'; // физ. лицо
const TYPE_LEGAL_ENTITY = 'legal-entity'; // юр. лицо
const TYPE_ENTERPRENEUR = 'enterpreneur'; // инд. предприниматель
/**
* @Serializer\Groups({"get"})
* @Serializer\SerializedName("type")
* @Serializer\Type("string")
*/
public $type;
/**
* @Serializer\Groups({"get"})
* @Serializer\SerializedName("legalName")
* @Serializer\Type("string")
*/
public $legalName;
/**
* @Serializer\Groups({"get"})
* @Serializer\SerializedName("legalAddress")
* @Serializer\Type("string")
*/
public $legalAddress;
/**
* @Serializer\Groups({"get"})
* @Serializer\SerializedName("INN")
* @Serializer\Type("string")
*/
public $INN;
/**
* @Serializer\Groups({"get"})
* @Serializer\SerializedName("OKPO")
* @Serializer\Type("string")
*/
public $OKPO;
/**
* @Serializer\Groups({"get"})
* @Serializer\SerializedName("KPP")
* @Serializer\Type("string")
*/
public $KPP;
/**
* @Serializer\Groups({"get"})
* @Serializer\SerializedName("OGRN")
* @Serializer\Type("string")
*/
public $OGRN;
/**
* @Serializer\Groups({"get"})
* @Serializer\SerializedName("OGRNIP")
* @Serializer\Type("string")
*/
public $OGRNIP;
}

View File

@ -1,30 +0,0 @@
<?php
namespace RetailCrm\DeliveryModuleBundle\Model;
use JMS\Serializer\Annotation as Serializer;
class Coordinates
{
/**
* Широта
*
* @var float
*
* @Serializer\Groups({"get", "response"})
* @Serializer\SerializedName("latitude")
* @Serializer\Type("float")
*/
public $latitude;
/**
* Долгота
*
* @var float
*
* @Serializer\Groups({"get", "response"})
* @Serializer\SerializedName("longitude")
* @Serializer\Type("float")
*/
public $longitude;
}

View File

@ -1,94 +0,0 @@
<?php
namespace RetailCrm\DeliveryModuleBundle\Model;
use JMS\Serializer\Annotation as Serializer;
class Customer
{
/**
* Идентификатор покупателя.
*
* @var int
*
* @Serializer\Groups({"get"})
* @Serializer\SerializedName("id")
* @Serializer\Type("integer")
*/
public $id;
/**
* Фамилия.
*
* @var string
*
* @Serializer\Groups({"get"})
* @Serializer\SerializedName("lastName")
* @Serializer\Type("string")
*/
public $lastName;
/**
* Имя.
*
* @var string
*
* @Serializer\Groups({"get"})
* @Serializer\SerializedName("firstName")
* @Serializer\Type("string")
*/
public $firstName;
/**
* Отчество.
*
* @var string
*
* @Serializer\Groups({"get"})
* @Serializer\SerializedName("patronymic")
* @Serializer\Type("string")
*/
public $patronymic;
/**
* Телефоны.
*
* @var array
*
* @Serializer\Groups({"get"})
* @Serializer\SerializedName("phones")
* @Serializer\Type("array<string>")
*/
public $phones;
/**
* E-mail.
*
* @var string
*
* @Serializer\Groups({"get"})
* @Serializer\SerializedName("email")
* @Serializer\Type("string")
*/
public $email;
/**
* Данные контрагента.
*
* @var Contragent
*
* @Serializer\Groups({"get"})
* @Serializer\SerializedName("contragent")
* @Serializer\Type("RetailCrm\DeliveryModuleBundle\Model\Model\Contragent")
*/
public $contragent;
public function getNickName(): ?string
{
$result = trim(
$this->lastName . ' ' . $this->firstName . ' ' . $this->patronymic
);
return $result;
}
}

View File

@ -1,250 +0,0 @@
<?php
namespace RetailCrm\DeliveryModuleBundle\Model;
use JMS\Serializer\Annotation as Serializer;
class DeliveryAddress
{
/**
* Почтовый индекс
*
* @var string
*
* @Serializer\Groups({"get", "set", "response"})
* @Serializer\SerializedName("index")
* @Serializer\Type("string")
*/
public $index;
/**
* ISO код страны (ISO 3166-1 alpha-2).
*
* @var string
*
* @Serializer\Groups({"get", "set", "response"})
* @Serializer\SerializedName("countryIso")
* @Serializer\Type("string")
*/
public $country;
/**
* Область/край.
*
* @var string
*
* @Serializer\Groups({"get", "set", "response"})
* @Serializer\SerializedName("region")
* @Serializer\Type("string")
*/
public $region;
/**
* Идентификатор региона в Geohelper.
*
* @var int
*
* @Serializer\Groups({"get", "set", "response"})
* @Serializer\SerializedName("regionId")
* @Serializer\Type("integer")
*/
public $regionId;
/**
* Город.
*
* @var string
*
* @Serializer\Groups({"get", "set", "response"})
* @Serializer\SerializedName("city")
* @Serializer\Type("string")
*/
public $city;
/**
* Идентификатор города в Geohelper.
*
* @var int
*
* @Serializer\Groups({"get", "set", "response"})
* @Serializer\SerializedName("cityId")
* @Serializer\Type("integer")
*/
public $cityId;
/**
* Тип населенного пункта.
*
* @var string
*
* @Serializer\Groups({"get", "set", "response"})
* @Serializer\SerializedName("cityType")
* @Serializer\Type("string")
*/
public $cityType;
/**
* Название улицы, шоссе, проспекта, проезда.
*
* @var string
*
* @Serializer\Groups({"get", "set", "response"})
* @Serializer\SerializedName("street")
* @Serializer\Type("string")
*/
public $street;
/**
* Идентификатор улицы в Geohelper.
*
* @var int
*
* @Serializer\Groups({"get", "set", "response"})
* @Serializer\SerializedName("streetId")
* @Serializer\Type("integer")
*/
public $streetId;
/**
* Тип улицы.
*
* @var string
*
* @Serializer\Groups({"get", "set", "response"})
* @Serializer\SerializedName("streetType")
* @Serializer\Type("string")
*/
public $streetType;
/**
* Дом
*
* @var string
*
* @Serializer\Groups({"get", "set", "response"})
* @Serializer\SerializedName("building")
* @Serializer\Type("string")
*/
public $building;
/**
* Номер квартиры или офиса.
*
* @var string
*
* @Serializer\Groups({"get", "set", "response"})
* @Serializer\SerializedName("flat")
* @Serializer\Type("string")
*/
public $flat;
/**
* Код домофона.
*
* @var string
*
* @Serializer\Groups({"get", "set", "response"})
* @Serializer\SerializedName("intercomCode")
* @Serializer\Type("string")
*/
public $intercomCode;
/**
* Этаж.
*
* @var int
*
* @Serializer\Groups({"get", "set", "response"})
* @Serializer\SerializedName("floor")
* @Serializer\Type("integer")
*/
public $floor;
/**
* Подъезд.
*
* @var int
*
* @Serializer\Groups({"get", "set", "response"})
* @Serializer\SerializedName("block")
* @Serializer\Type("integer")
*/
public $block;
/**
* Строение.
*
* @var string
*
* @Serializer\Groups({"get", "set", "response"})
* @Serializer\SerializedName("house")
* @Serializer\Type("string")
*/
public $house;
/**
* Корпус
*
* @var string
*
* @Serializer\Groups({"get", "set", "response"})
* @Serializer\SerializedName("housing")
* @Serializer\Type("string")
*/
public $housing;
/**
* Метро.
*
* @var string
*
* @Serializer\Groups({"get", "set", "response"})
* @Serializer\SerializedName("metro")
* @Serializer\Type("string")
*/
public $metro;
/**
* Дополнительные заметки.
*
* @var string
*
* @Serializer\Groups({"get", "set", "response"})
* @Serializer\SerializedName("notes")
* @Serializer\Type("string")
*/
public $notes;
/**
* Адрес в виде строки.
*
* @var string
*
* @Serializer\Groups({"get", "set", "response"})
* @Serializer\SerializedName("text")
* @Serializer\Type("string")
*/
public $text;
/**
* Код терминала отгрузки/доставки.
*
* @var string
*
* @Serializer\Groups({"get", "request", "response"})
* @Serializer\SerializedName("terminal")
* @Serializer\Type("string")
*/
public $terminal;
/**
* Данные терминала.
*
* @var Terminal
*
* @Serializer\Groups({"response"})
* @Serializer\SerializedName("terminalData")
* @Serializer\Type("RetailCrm\DeliveryModuleBundle\Model\Terminal")
*/
public $terminalData;
}

View File

@ -1,157 +0,0 @@
<?php
namespace RetailCrm\DeliveryModuleBundle\Model;
use JMS\Serializer\Annotation as Serializer;
class DeliveryDataField
{
const TYPE_INTEGER = 'integer';
const TYPE_TEXT = 'text';
const TYPE_AUTOCOMPLETE = 'autocomplete';
const TYPE_CHECKBOX = 'checkbox';
const TYPE_CHOICE = 'choice';
const TYPE_DATE = 'date';
/**
* Код поля.
*
* @var string
*
* @Serializer\Groups({"get", "set"})
* @Serializer\SerializedName("code")
* @Serializer\Type("string")
*/
public $code;
/**
* Имя поля.
*
* @var string
*
* @Serializer\Groups({"get", "set"})
* @Serializer\SerializedName("label")
* @Serializer\Type("string")
*/
public $label;
/**
* Пояснение к полю.
*
* @var string
*
* @Serializer\Groups({"get", "set"})
* @Serializer\SerializedName("hint")
* @Serializer\Type("string")
*/
public $hint;
/**
* Тип поля. Возможны варианты (
* integer - числовое поле,
* text - текстовое поле,
* autocomplete - автокомплит поле,
* checkbox,
* choice - выпадающий список,
* date - поле с датой).
*
* @var string
*
* @Serializer\Groups({"get", "set"})
* @Serializer\SerializedName("type")
* @Serializer\Type("string")
*/
public $type;
/**
* Указывается для типа поля choice. Означает что можно выбирать несколько вариантов.
*
* @var bool
*
* @Serializer\Groups({"get", "set"})
* @Serializer\SerializedName("multiple")
* @Serializer\Type("boolean")
*/
public $multiple = false;
/**
* Указывается для типа поля choice. Список возможных вариантов в выпадающем списке. Обязателен если тип поля choice.
*
* @var array
*
* @Serializer\Groups({"get", "set"})
* @Serializer\SerializedName("choices")
* @Serializer\Type("array")
*/
public $choices;
/**
* Указывается для типа поля autocomplete. Адрес, по окторому можно получить данные для автокомплит поля.
*
* @var string
*
* @Serializer\Groups({"get", "set"})
* @Serializer\SerializedName("autocompleteUrl")
* @Serializer\Type("string")
*/
public $autocompleteUrl;
/**
* Указывается для типа поля autocomplete. Можно искать без указания строки поиска
* (при нажатии на поле сразу вывалится список с вариантами).
*
* @var bool
*
* @Serializer\Groups({"get", "set"})
* @Serializer\SerializedName("allowedEmptyTerm")
* @Serializer\Type("boolean")
*/
public $allowedEmptyTerm = false;
/**
* Видимость поля на форме.
*
* @var bool
*
* @Serializer\Groups({"get", "set"})
* @Serializer\SerializedName("visible")
* @Serializer\Type("boolean")
*/
public $isVisible = true;
/**
* Поле обязательно для заполнения.
*
* @var bool
*
* @Serializer\Groups({"get", "set"})
* @Serializer\SerializedName("required")
* @Serializer\Type("boolean")
*/
public $isRequired = false;
/**
* Поле влияет на стоимость доставки. Если true - значение поля используется в методе calculate.
*
* @var bool
*
* @Serializer\Groups({"get", "set"})
* @Serializer\SerializedName("affectsCost")
* @Serializer\Type("boolean")
*/
public $isAffectsCost = false;
/**
* Разрешено ли редактировать поле.
* Если false - поле информационное - заполняется только данными,
* полученными напрямую от службы доставки (
* например стоимость страховки - может заполняться после оформления доставки или при расчете стоимости).
*
* @var bool
*
* @Serializer\Groups({"get", "set"})
* @Serializer\SerializedName("editable")
* @Serializer\Type("boolean")
*/
public $isEditable = true;
}

View File

@ -1,339 +0,0 @@
<?php
namespace RetailCrm\DeliveryModuleBundle\Model;
use JMS\Serializer\Annotation as Serializer;
class DeliveryTime
{
/**
* Время доставки "с"
*
* @Serializer\SerializedName("from")
* @Serializer\Type("DateTime<'H:i'>")
* @Serializer\Groups({"set", "get", "orderHistory", "history-reference", "calculate"})
* @Serializer\Accessor(getter="getFrom", setter="setFrom")
*
* @var \DateTime|null
*/
protected $from;
/**
* Время доставки "до"
*
* @Serializer\SerializedName("to")
* @Serializer\Type("DateTime<'H:i'>")
* @Serializer\Groups({"set", "get", "orderHistory", "history-reference", "calculate"})
* @Serializer\Accessor(getter="getTo", setter="setTo")
*
* @var \DateTime|null
*/
protected $to;
/**
* Время доставки (произвольный текст)
*
* @Serializer\SerializedName("custom")
* @Serializer\Type("string")
* @Serializer\Groups({"set", "get", "orderHistory", "history-reference", "calculate"})
*
* @var string|null
*/
protected $custom;
/**
* @param string|\DateTime|null $from
* @param string|\DateTime|null $to
* @param string|null $custom
*
* @return self
*/
public function __construct($from = null, $to = null, $custom = null)
{
$this->setFrom($from);
$this->setTo($to);
$this->setCustom($custom);
}
/**
* Разбор строки со временем доставки
*
* @param string $time
*
* @return self
*/
public static function fromString($time)
{
$result = new self();
$result->setString($time);
return $result;
}
/**
* @return \DateTime|null
*/
public function getFrom()
{
if ($this->from) {
$this->from->setDate(1970, 01, 01);
if ('00:00:00' === $this->from->format('H:i:s')) {
return null;
}
}
return $this->from;
}
/**
* @param \DateTime|string|null $from
*
* @return $this
*/
public function setFrom($from)
{
$this->from = $this->ensureTime($from);
$this->ensureConsistency();
return $this;
}
/**
* @return \DateTime|null
*/
public function getTo()
{
if ($this->to) {
$this->to->setDate(1970, 01, 01);
if ('23:59:59' === $this->to->format('H:i:s')) {
return null;
}
}
return $this->to;
}
/**
* @param \DateTime|string|null $to
*
* @return $this
*/
public function setTo($to)
{
$this->to = $this->ensureTime($to);
$this->ensureConsistency();
return $this;
}
/**
* @return string
*/
public function getCustom()
{
return $this->custom;
}
/**
* @param string $custom
*
* @return $this
*/
public function setCustom($custom)
{
$this->custom = $custom;
return $this;
}
/**
* @param string $time
*
* @return $this
*/
public function setString($time)
{
// точное время: 12.30, 12:30
$exactPattern = '/^в?\s*(\d{2}[:\.]\d{2})$/u';
// диапазон времени: 12-13, c 12.00 по 13:00
$rangePattern = '/^с?\s*(?P<from>\d{2}[:\.]?\d{0,2})\s*(-|по|до)\s*(?P<to>\d{2}[:\.]?\d{0,2})/u';
// диапазон времени: c 12.00
$rangeFromPattern = '/^с?\s*(?P<from>\d{2}[:\.]?\d{0,2})/u';
// диапазон времени: до 13:00
$rangeToPattern = '/^(-|по|до)\s*(?P<to>\d{2}[:\.]?\d{0,2})/u';
if (preg_match($exactPattern, $time, $matches)) {
$timeObj = new \DateTime($matches[1]);
$this->setFrom(clone $timeObj);
$this->setTo(clone $timeObj);
} elseif (preg_match($rangePattern, $time, $matches)) {
$from = $matches['from'];
$to = $matches['to'];
$from = preg_match($exactPattern, $from) ? $from : $from . ':00';
$to = preg_match($exactPattern, $to) ? $to : $to . ':00';
try {
$this->setFrom(new \DateTime($from));
$this->setTo(new \DateTime($to));
} catch (\Exception $e) {
$this->setFrom(null);
$this->setTo(null);
$this->setCustom($time);
}
} elseif (preg_match($rangeFromPattern, $time, $matches)) {
$from = $matches['from'];
$from = preg_match($exactPattern, $from) ? $from : $from . ':00';
try {
$this->setFrom(new \DateTime($from));
$this->setTo(null);
} catch (\Exception $e) {
$this->setFrom(null);
$this->setTo(null);
$this->setCustom($time);
}
} elseif (preg_match($rangeToPattern, $time, $matches)) {
$to = $matches['to'];
$to = preg_match($exactPattern, $to) ? $to : $to . ':00';
try {
$this->setFrom(null);
$this->setTo(new \DateTime($to));
} catch (\Exception $e) {
$this->setFrom(null);
$this->setTo(null);
$this->setCustom($time);
}
} else {
$this->setFrom(null);
$this->setTo(null);
$this->setCustom($time);
}
return $this;
}
/**
* @return string
*/
public function getString()
{
$from = $this->getFrom();
$to = $this->getTo();
$custom = $this->getCustom();
if (!($from || $to)) {
return (string) $custom;
}
$fromPrint = $from ? $from->format('H:i') : null;
$toPrint = $to ? $to->format('H:i') : null;
if ($fromPrint && $fromPrint === $toPrint) {
return 'в ' . $fromPrint;
}
$str = '';
if ($fromPrint) {
$str .= 'с ' . $fromPrint;
}
if ($toPrint) {
$str .= ' до ' . $toPrint;
}
return trim($str);
}
/**
* Проверяет, соответствует ли время доставки диапазону из настроек
*
* @return bool
*/
public function equalsRange(array $range)
{
$fromEquals = false;
$toEquals = false;
$from = $this->getFrom();
$to = $this->getTo();
if ($from) {
if (isset($range['from'])) {
$fromEquals = $from->format('H:i') === $range['from'];
}
} else {
if (!isset($range['from']) ||
!$range['from'] ||
'00:00' === $range['from'] ||
'00:00:00' === $range['from']
) {
$fromEquals = true;
}
}
if ($to) {
if (isset($range['to'])) {
$toEquals = $to->format('H:i') === $range['to'];
}
} else {
if (!isset($range['to']) ||
!$range['to'] ||
'23:59' === $range['from'] ||
'23:59:59' === $range['from']
) {
$toEquals = true;
}
}
return $fromEquals && $toEquals;
}
/**
* @return bool
*/
public function isEmpty()
{
return !($this->from || $this->to || $this->custom);
}
/**
* @return string
*/
public function __toString()
{
return $this->getString();
}
protected function ensureTime($time)
{
if ($time) {
if (!$time instanceof \DateTime) {
$time = new \DateTime((string) $time);
}
$time->setDate(1970, 01, 01);
}
return $time;
}
/**
* Если для времени доставки указана только одна граница диапазона, то присвоим другой значение по умолчанию
*/
protected function ensureConsistency()
{
$from = $this->getFrom();
$to = $this->getTo();
if (null === $from && null !== $to) {
$this->from = new \DateTime('1970-01-01T00:00:00');
} elseif (null === $to && null !== $from) {
$this->to = new \DateTime('1970-01-01T23:59:59');
} elseif (null === $to && null === $from) {
$this->to = null;
$this->from = null;
}
}
}

View File

@ -1,165 +0,0 @@
<?php
namespace RetailCrm\DeliveryModuleBundle\Model\Entity;
use JMS\Serializer\Annotation as Serializer;
use Ramsey\Uuid\Uuid;
use Ramsey\Uuid\UuidInterface;
abstract class Account
{
/**
* @Serializer\Groups({"get"})
* @Serializer\Type("string")
*/
protected $id;
protected $clientId;
/**
* @var \DateTime
*
* @Serializer\Groups({"get"})
* @Serializer\Type("DateTime<'Y-m-d H:i:s'>")
*/
protected $createdAt;
/**
* @var string
*
* @Serializer\Groups({"get", "connect"})
* @Serializer\Type("string")
*/
protected $crmUrl;
/**
* @var string
*
* @Serializer\Groups({"get", "connect"})
* @Serializer\Type("string")
*/
protected $crmApiKey;
/**
* @var bool
*/
protected $active;
/**
* @var bool
*/
protected $freeze;
/**
* @var string
*/
protected $language;
public function __construct()
{
$this->clientId = Uuid::uuid4();
$this->createdAt = new \DateTime();
$this->active = false;
$this->freeze = false;
}
public function getId(): int
{
return $this->id;
}
public function setClientId(UuidInterface $clientId): self
{
$this->clientId = $clientId;
return $this;
}
public function getClientId(): ?UuidInterface
{
return $this->clientId;
}
public function getCreatedAt(): \DateTime
{
return $this->createdAt;
}
public function setCreatedAt(\DateTime $createdAt): self
{
$this->createdAt = $createdAt;
return $this;
}
public function getCrmUrl(): ?string
{
return $this->crmUrl;
}
public function setCrmUrl(?string $crmUrl): self
{
$this->crmUrl = rtrim($crmUrl, '/');
return $this;
}
public function getCrmApiKey(): ?string
{
return $this->crmApiKey;
}
public function setCrmApiKey(?string $crmApiKey): self
{
$this->crmApiKey = $crmApiKey;
return $this;
}
public function setActive(bool $active): self
{
$this->active = $active;
return $this;
}
public function isActive(): bool
{
return $this->active;
}
public function setFreeze(bool $freeze): self
{
$this->freeze = $freeze;
return $this;
}
public function isFreeze(): bool
{
return $this->freeze;
}
/**
* @Serializer\VirtualProperty
* @Serializer\Type("boolean")
* @Serializer\Groups({"get"})
* @Serializer\SerializedName("isEnabled")
*/
public function isEnabled(): bool
{
return !$this->freeze && $this->active;
}
public function setLanguage(string $language): self
{
$this->language = $language;
return $this;
}
public function getLanguage(): ?string
{
return $this->language;
}
}

View File

@ -1,140 +0,0 @@
<?php
namespace RetailCrm\DeliveryModuleBundle\Model;
use JMS\Serializer\Annotation as Serializer;
class IntegrationModule
{
/**
* Код экземпляра модуля
*
* @var string
*
* @Serializer\Groups({"set", "get"})
* @Serializer\SerializedName("code")
* @Serializer\Type("string")
*/
public $code;
/**
* Общий символьный код модуля
*
* @var string
*
* @Serializer\Groups({"set", "get"})
* @Serializer\SerializedName("integrationCode")
* @Serializer\Type("string")
*/
public $integrationCode;
/**
* Ключ активности модуля
*
* @var bool
*
* @Serializer\Groups({"set", "get", "activity"})
* @Serializer\SerializedName("active")
* @Serializer\Type("boolean")
*/
public $active;
/**
* Работа модуля заморожена
*
* @var bool
*
* @Serializer\Groups({"activity"})
* @Serializer\SerializedName("freeze")
* @Serializer\Type("boolean")
*/
public $freeze;
/**
* Наименование модуля
*
* @var string
*
* @Serializer\Groups({"set", "get"})
* @Serializer\SerializedName("name")
* @Serializer\Type("string")
*/
public $name;
/**
* Ссылка на svg логотип модуля
*
* @var string
*
* @Serializer\Groups({"set", "get"})
* @Serializer\SerializedName("logo")
* @Serializer\Type("string")
*/
public $logo;
/**
* ID подключения
*
* @var string
*
* @Serializer\Groups({"set", "get"})
* @Serializer\SerializedName("clientId")
* @Serializer\Type("string")
*/
public $clientId;
/**
* Базовый url, на который делает запросы RetailCRM
*
* @var string
*
* @Serializer\Groups({"set", "get"})
* @Serializer\SerializedName("baseUrl")
* @Serializer\Type("string")
*/
public $baseUrl;
/**
* Относительные пути от базового URL до конкретных методов
*
* @var array
*
* @Serializer\Groups({"set", "get"})
* @Serializer\SerializedName("actions")
* @Serializer\Type("array<string, string>")
*/
public $actions;
/**
* Список стран для которых доступен модуль
*
* @var array
*
* @Serializer\Groups({"set", "get"})
* @Serializer\SerializedName("availableCountries")
* @Serializer\Type("array")
*/
public $availableCountries;
/**
* URL настроек модуля
*
* @var string
*
* @Serializer\Groups({"set", "get"})
* @Serializer\SerializedName("accountUrl")
* @Serializer\Type("string")
*/
public $accountUrl;
/**
* Массив конфигураций интеграций
*
* @var array
*
* @Serializer\Groups({"set", "get"})
* @Serializer\SerializedName("integrations")
* @Serializer\Type("array")
*/
public $integrations;
}

View File

@ -1,83 +0,0 @@
<?php
namespace RetailCrm\DeliveryModuleBundle\Model;
use JMS\Serializer\Annotation as Serializer;
class Manager
{
/**
* Идентификатор менеджера.
*
* @var int
*
* @Serializer\Groups({"get"})
* @Serializer\SerializedName("id")
* @Serializer\Type("integer")
*/
public $id;
/**
* Фамилия.
*
* @var string
*
* @Serializer\Groups({"get"})
* @Serializer\SerializedName("lastName")
* @Serializer\Type("string")
*/
public $lastName;
/**
* Имя.
*
* @var string
*
* @Serializer\Groups({"get"})
* @Serializer\SerializedName("firstName")
* @Serializer\Type("string")
*/
public $firstName;
/**
* Отчество.
*
* @var string
*
* @Serializer\Groups({"get"})
* @Serializer\SerializedName("patronymic")
* @Serializer\Type("string")
*/
public $patronymic;
/**
* Телефон.
*
* @var string
*
* @Serializer\Groups({"get"})
* @Serializer\SerializedName("phone")
* @Serializer\Type("string")
*/
public $phone;
/**
* E-mail.
*
* @var string
*
* @Serializer\Groups({"get"})
* @Serializer\SerializedName("email")
* @Serializer\Type("string")
*/
public $email;
public function getNickName(): ?string
{
$result = trim(
$this->lastName . ' ' . $this->firstName . ' ' . $this->patronymic
);
return $result;
}
}

View File

@ -1,102 +0,0 @@
<?php
namespace RetailCrm\DeliveryModuleBundle\Model;
use JMS\Serializer\Annotation as Serializer;
use Symfony\Component\Validator\Constraints as Assert;
use Symfony\Component\Validator\Mapping\ClassMetadata;
class Package
{
/**
* Идентификатор упаковки
*
* @var string
*
* @Serializer\Groups({"request"})
* @Serializer\SerializedName("packageId")
* @Serializer\Type("string")
*/
public $packageId;
/**
* Вес г.
*
* @var float
*
* @Serializer\Groups({"request", "calculate"})
* @Serializer\SerializedName("weight")
* @Serializer\Type("float")
*/
public $weight;
/**
* Ширина мм.
*
* @var int
*
* @Serializer\Groups({"request", "calculate"})
* @Serializer\SerializedName("width")
* @Serializer\Type("integer")
*/
public $width;
/**
* Длина мм.
*
* @var int
*
* @Serializer\Groups({"request", "calculate"})
* @Serializer\SerializedName("length")
* @Serializer\Type("integer")
*/
public $length;
/**
* Высота мм.
*
* @var int
*
* @Serializer\Groups({"request", "calculate"})
* @Serializer\SerializedName("height")
* @Serializer\Type("integer")
*/
public $height;
/**
* Содержимое упаковки
*
* @var PackageItem[]
*
* @Serializer\Groups({"request"})
* @Serializer\SerializedName("items")
* @Serializer\Type("array<RetailCrm\DeliveryModuleBundle\Model\PackageItem>")
*/
public $items;
public function __construct($weight = null, $width = null, $length = null, $height = null)
{
$this->weight = $weight;
$this->width = $width;
$this->length = $length;
$this->height = $height;
}
public function getVolume()
{
if (null !== $this->length
&& null !== $this->width
&& null !== $this->height
) {
return $this->length * $this->width * $this->height;
} else {
return false;
}
}
public static function loadValidatorMetadata(ClassMetadata $metadata)
{
$metadata
->addPropertyConstraint('weight', new Assert\NotBlank());
}
}

View File

@ -1,107 +0,0 @@
<?php
namespace RetailCrm\DeliveryModuleBundle\Model;
use JMS\Serializer\Annotation as Serializer;
class PackageItem
{
/**
* Идентификатор товара.
*
* @var string
*
* @Serializer\Groups({"get"})
* @Serializer\SerializedName("offerId")
* @Serializer\Type("string")
*/
public $offerId;
/**
* Наименование товара.
*
* @var string
*
* @Serializer\Groups({"get"})
* @Serializer\SerializedName("name")
* @Serializer\Type("string")
*/
public $name;
/**
* Объявленная стоимость за единицу товара.
*
* @var string
*
* @Serializer\Groups({"get"})
* @Serializer\SerializedName("declaredValue")
* @Serializer\Type("float")
*/
public $declaredValue;
/**
* Наложенный платеж за единицу товара.
*
* @var string
*
* @Serializer\Groups({"get"})
* @Serializer\SerializedName("cod")
* @Serializer\Type("float")
*/
public $cod;
/**
* Ставка НДС
*
* @var float
*
* @Serializer\Groups({"get"})
* @Serializer\SerializedName("vatRate")
* @Serializer\Type("float")
*/
public $vatRate;
/**
* Количество товара в упаковке.
*
* @var string
*
* @Serializer\Groups({"get"})
* @Serializer\SerializedName("quantity")
* @Serializer\Type("float")
*/
public $quantity;
/**
* Единица измерения товара.
*
* @var Unit
*
* @Serializer\Groups({"get"})
* @Serializer\SerializedName("unit")
* @Serializer\Type("RetailCrm\DeliveryModuleBundle\Model\Unit")
*/
public $unit;
/**
* Стоимость товара.
*
* @var float
*
* @Serializer\Groups({"get"})
* @Serializer\SerializedName("cost")
* @Serializer\Type("float")
*/
public $cost;
/**
* Свойства товара.
*
* @var string
*
* @Serializer\Groups({"get"})
* @Serializer\SerializedName("properties")
* @Serializer\Type("array<string, array>")
*/
public $properties;
}

View File

@ -1,22 +0,0 @@
<?php
namespace RetailCrm\DeliveryModuleBundle\Model;
use JMS\Serializer\Annotation as Serializer;
class PaymentType
{
/**
* @Serializer\Groups({"request"})
* @Serializer\SerializedName("code")
* @Serializer\Type("string")
*/
public $code;
/**
* @Serializer\Groups({"request"})
* @Serializer\SerializedName("name")
* @Serializer\Type("string")
*/
public $name;
}

View File

@ -1,36 +0,0 @@
<?php
namespace RetailCrm\DeliveryModuleBundle\Model;
use JMS\Serializer\Annotation as Serializer;
class Plate
{
/**
* Код печатной формы
*
* @var string
*
* @Serializer\Groups({"get", "set"})
* @Serializer\SerializedName("code")
* @Serializer\Type("string")
*/
public $code;
/**
* Наименование печатной формы
*
* @var string
*
* @Serializer\Groups({"get", "set"})
* @Serializer\SerializedName("label")
* @Serializer\Type("string")
*/
public $label;
public function __construct($code, $label)
{
$this->code = $code;
$this->label = $label;
}
}

View File

@ -1,121 +0,0 @@
<?php
namespace RetailCrm\DeliveryModuleBundle\Model;
use Intaro\CRMBundle\Entity\Model\DeliveryTime;
use JMS\Serializer\Annotation as Serializer;
class RequestCalculate
{
use Traits\ExtraDataTrait;
/**
* Адрес отгрузки.
*
* @var RetailCrm\DeliveryModuleBundle\Model\DeliveryAddress
*
* @Serializer\Groups({"request", "calculate"})
* @Serializer\SerializedName("shipmentAddress")
* @Serializer\Type("RetailCrm\DeliveryModuleBundle\Model\DeliveryAddress")
*/
public $shipmentAddress;
/**
* Адрес доставки.
*
* @var string
*
* @Serializer\Groups({"request", "calculate"})
* @Serializer\SerializedName("deliveryAddress")
* @Serializer\Type("RetailCrm\DeliveryModuleBundle\Model\DeliveryAddress")
*/
public $deliveryAddress;
/**
* Набор упаковок.
*
* @var Intaro\CRMDeliveryBundle\Form\Model\Package[]
*
* @Serializer\Groups({"request", "calculate"})
* @Serializer\SerializedName("packages")
* @Serializer\Type("array<RetailCrm\DeliveryModuleBundle\Model\Package>")
*/
public $packages;
/**
* Объявленная стоимость.
*
* @var float
*
* @Serializer\Groups({"request", "calculate"})
* @Serializer\SerializedName("declaredValue")
* @Serializer\Type("float")
*/
public $declaredValue;
/**
* Наложенный платеж.
*
* @var float
*
* @Serializer\Groups({"request", "calculate"})
* @Serializer\SerializedName("cod")
* @Serializer\Type("float")
*/
public $cod;
/**
* Плательщик за доставку.
*
* @var string
*
* @Serializer\Groups({"request", "calculate"})
* @Serializer\SerializedName("payerType")
* @Serializer\Type("string")
*/
public $payerType;
/**
* Дата доставки.
*
* @var \DateTime
*
* @Serializer\Groups({"request", "calculate"})
* @Serializer\SerializedName("deliveryDate")
* @Serializer\Type("DateTime<'Y-m-d'>")
*/
public $deliveryDate;
/**
* Время доставки.
*
* @var DeliveryTime
*
* @Serializer\Groups({"request", "calculate"})
* @Serializer\SerializedName("deliveryTime")
* @Serializer\Type("RetailCrm\DeliveryModuleBundle\Model\DeliveryTime")
*/
public $deliveryTime;
/**
* Валюта.
*
* @var string
*
* @Serializer\Groups({"request", "calculate"})
* @Serializer\SerializedName("currency")
* @Serializer\Type("string")
*/
public $currency;
/**
* Дополнительные данные доставки.
*
* @var array
*
* @Serializer\Groups({"request", "calculate"})
* @Serializer\SerializedName("extraData")
* @Serializer\Type("array")
*/
public $extraData;
}

View File

@ -1,17 +0,0 @@
<?php
namespace RetailCrm\DeliveryModuleBundle\Model;
use JMS\Serializer\Annotation as Serializer;
class RequestDelete
{
/**
* @var string
*
* @Serializer\Groups({"request"})
* @Serializer\SerializedName("deliveryId")
* @Serializer\Type("string")
*/
public $deliveryId;
}

View File

@ -1,26 +0,0 @@
<?php
namespace RetailCrm\DeliveryModuleBundle\Model;
use JMS\Serializer\Annotation as Serializer;
class RequestPrint
{
/**
* @var string
*
* @Serializer\Groups({"request"})
* @Serializer\SerializedName("type")
* @Serializer\Type("string")
*/
public $type;
/**
* @var string[]
*
* @Serializer\Groups({"request"})
* @Serializer\SerializedName("deliveryIds")
* @Serializer\Type("array")
*/
public $deliveryIds;
}

View File

@ -1,153 +0,0 @@
<?php
namespace RetailCrm\DeliveryModuleBundle\Model;
use JMS\Serializer\Annotation as Serializer;
class RequestSave
{
/**
* Идентификатор доставки в службе доставки. Передается если требуется отредактировать уже оформленную доставку
*
* @var string
*
* @Serializer\Groups({"request"})
* @Serializer\SerializedName("deliveryId")
* @Serializer\Type("string")
*/
public $deliveryId;
/**
* Id заказа
*
* @var string
*
* @Serializer\Groups({"request"})
* @Serializer\SerializedName("order")
* @Serializer\Type("string")
*/
public $order;
/**
* Номер заказа
*
* @var string
*
* @Serializer\Groups({"request"})
* @Serializer\SerializedName("orderNumber")
* @Serializer\Type("string")
*/
public $orderNumber;
/**
* Код магазина
*
* @var string
*
* @Serializer\Groups({"request"})
* @Serializer\SerializedName("site")
* @Serializer\Type("string")
*/
public $site;
/**
* Название магазина
*
* @var string
*
* @Serializer\Groups({"request"})
* @Serializer\SerializedName("siteName")
* @Serializer\Type("string")
*/
public $siteName;
/**
* Наименование юр.лица
*
* @var string
*
* @Serializer\Groups({"request"})
* @Serializer\SerializedName("legalEntity")
* @Serializer\Type("string")
*/
public $legalEntity;
/**
* Покупатель
*
* @var Customer
*
* @Serializer\Groups({"request"})
* @Serializer\SerializedName("customer")
* @Serializer\Type("RetailCrm\DeliveryModuleBundle\Model\Customer")
*/
public $customer;
/**
* Менеджер, работающий с покупателем
*
* @var Manager
*
* @Serializer\Groups({"request"})
* @Serializer\SerializedName("manager")
* @Serializer\Type("RetailCrm\DeliveryModuleBundle\Model\Manager")
*/
public $manager;
/**
* Набор упаковок
*
* @var RetailCrm\DeliveryModuleBundle\Model\Package[]
*
* @Serializer\Groups({"request"})
* @Serializer\SerializedName("packages")
* @Serializer\Type("array<RetailCrm\DeliveryModuleBundle\Model\Package>")
*/
public $packages;
/**
* Данные доставки
*
* @var RetailCrm\DeliveryModuleBundle\Model\SaveDeliveryData
*
* @Serializer\Groups({"request"})
* @Serializer\SerializedName("delivery")
* @Serializer\Type("RetailCrm\DeliveryModuleBundle\Model\SaveDeliveryData")
*/
public $delivery;
/**
* Валюта
*
* @var string
*
* @Serializer\Groups({"request", "calculate"})
* @Serializer\SerializedName("currency")
* @Serializer\Type("string")
*/
public $currency;
public function getFullDeclaredValue()
{
$result = 0;
foreach ($this->packages as $package) {
foreach ($package->items as $item) {
$result += $item->declaredValue * $item->quantity;
}
}
return $result;
}
public function getFullItemsCodValue()
{
$result = 0;
foreach ($this->packages as $package) {
foreach ($package->items as $item) {
$result += $item->cod * $item->quantity;
}
}
return $result;
}
}

View File

@ -1,30 +0,0 @@
<?php
namespace RetailCrm\DeliveryModuleBundle\Model;
use JMS\Serializer\Annotation as Serializer;
class RequestShipmentDelete
{
/**
* Идентификатор отгрузки в службе доставки
*
* @var string
*
* @Serializer\Groups({"request"})
* @Serializer\SerializedName("shipmentId")
* @Serializer\Type("string")
*/
public $shipmentId;
/**
* Дополнительные данные отгрузки
*
* @var array
*
* @Serializer\Groups({"request"})
* @Serializer\SerializedName("extraData")
* @Serializer\Type("array")
*/
public $extraData;
}

View File

@ -1,96 +0,0 @@
<?php
namespace RetailCrm\DeliveryModuleBundle\Model;
use JMS\Serializer\Annotation as Serializer;
class RequestShipmentSave
{
use Traits\ExtraDataTrait;
/**
* Идентификатор отгрузки в службе доставки. Передается если требуется отредактировать уже оформленную отгрузку
*
* @var string
*
* @Serializer\Groups({"request"})
* @Serializer\SerializedName("shipmentId")
* @Serializer\Type("string")
*/
public $shipmentId;
/**
* Менеджер, отвечающий за отгрузку
*
* @var Manager
*
* @Serializer\Groups({"request"})
* @Serializer\SerializedName("manager")
* @Serializer\Type("RetailCrm\DeliveryModuleBundle\Model\Manager")
*/
public $manager;
/**
* Дата отгрузки
*
* @var DateTime
*
* @Serializer\Groups({"get"})
* @Serializer\SerializedName("date")
* @Serializer\Type("DateTime<'Y-m-d'>")
*/
public $date;
/**
* Время доставки ("custom" не ипользуется)
*
* @var RetailCrm\DeliveryModuleBundle\Model\DeliveryTime
*
* @Serializer\Groups({"get"})
* @Serializer\SerializedName("time")
* @Serializer\Type("RetailCrm\DeliveryModuleBundle\Model\DeliveryTime")
*/
public $time;
/**
* Адрес отгрузки
*
* @var string
*
* @Serializer\Groups({"get"})
* @Serializer\SerializedName("address")
* @Serializer\Type("RetailCrm\DeliveryModuleBundle\Model\DeliveryAddress")
*/
public $address;
/**
* Массив идентификаторов оформленных доставок в службе доставки
*
* @var array
*
* @Serializer\Groups({"get"})
* @Serializer\SerializedName("orders")
* @Serializer\Type("array<RetailCrm\DeliveryModuleBundle\Model\ShipmentOrder>")
*/
public $orders;
/**
* @var string
*
* @Serializer\Groups({"get"})
* @Serializer\SerializedName("comment")
* @Serializer\Type("string")
*/
public $comment;
/**
* Дополнительные данные отгрузки
*
* @var array
*
* @Serializer\Groups({"get"})
* @Serializer\SerializedName("extraData")
* @Serializer\Type("array")
*/
public $extraData;
}

View File

@ -1,57 +0,0 @@
<?php
namespace RetailCrm\DeliveryModuleBundle\Model;
use JMS\Serializer\Annotation as Serializer;
class RequestStatusUpdateItem
{
/**
* Идентификатор доставки с СД
*
* @var string
*
* @Serializer\Groups({"request"})
* @Serializer\SerializedName("deliveryId")
* @Serializer\Type("string")
*/
public $deliveryId;
/**
* Трек номер
*
* @var string
*
* @Serializer\Groups({"request"})
* @Serializer\SerializedName("trackNumber")
* @Serializer\Type("string")
*/
public $trackNumber;
/**
* История смены статусов доставки
*
* @var StatusInfo[]
*
* @Serializer\Groups({"request"})
* @Serializer\SerializedName("history")
* @Serializer\Type("array<RetailCrm\DeliveryModuleBundle\Model\StatusInfo>")
*/
public $history;
/**
* Массив дополнительных данных доставки
*
* @var array
*
* @Serializer\Groups({"request"})
* @Serializer\SerializedName("extraData")
* @Serializer\Type("array")
*/
public $extraData;
public function __construct()
{
$this->history = [];
}
}

View File

@ -1,120 +0,0 @@
<?php
namespace RetailCrm\DeliveryModuleBundle\Model;
use JMS\Serializer\Annotation as Serializer;
class RequestCalculate
{
use Traits\ExtraDataTrait;
/**
* Адрес отгрузки.
*
* @var RetailCrm\DeliveryModuleBundle\Model\DeliveryAddress
*
* @Serializer\Groups({"request", "calculate"})
* @Serializer\SerializedName("shipmentAddress")
* @Serializer\Type("RetailCrm\DeliveryModuleBundle\Model\DeliveryAddress")
*/
public $shipmentAddress;
/**
* Адрес доставки.
*
* @var string
*
* @Serializer\Groups({"request", "calculate"})
* @Serializer\SerializedName("deliveryAddress")
* @Serializer\Type("RetailCrm\DeliveryModuleBundle\Model\DeliveryAddress")
*/
public $deliveryAddress;
/**
* Набор упаковок.
*
* @var RetailCrm\DeliveryModuleBundle\Model\Package[]
*
* @Serializer\Groups({"request", "calculate"})
* @Serializer\SerializedName("packages")
* @Serializer\Type("array<RetailCrm\DeliveryModuleBundle\Model\Package>")
*/
public $packages;
/**
* Объявленная стоимость.
*
* @var float
*
* @Serializer\Groups({"request", "calculate"})
* @Serializer\SerializedName("declaredValue")
* @Serializer\Type("float")
*/
public $declaredValue;
/**
* Наложенный платеж.
*
* @var float
*
* @Serializer\Groups({"request", "calculate"})
* @Serializer\SerializedName("cod")
* @Serializer\Type("float")
*/
public $cod;
/**
* Плательщик за доставку.
*
* @var string
*
* @Serializer\Groups({"request", "calculate"})
* @Serializer\SerializedName("payerType")
* @Serializer\Type("string")
*/
public $payerType;
/**
* Дата доставки.
*
* @var \DateTime
*
* @Serializer\Groups({"request", "calculate"})
* @Serializer\SerializedName("deliveryDate")
* @Serializer\Type("DateTime<'Y-m-d'>")
*/
public $deliveryDate;
/**
* Время доставки.
*
* @var DeliveryTime
*
* @Serializer\Groups({"request", "calculate"})
* @Serializer\SerializedName("deliveryTime")
* @Serializer\Type("RetailCrm\DeliveryModuleBundle\Model\DeliveryTime")
*/
public $deliveryTime;
/**
* Валюта.
*
* @var string
*
* @Serializer\Groups({"request", "calculate"})
* @Serializer\SerializedName("currency")
* @Serializer\Type("string")
*/
public $currency;
/**
* Дополнительные данные доставки.
*
* @var array
*
* @Serializer\Groups({"request", "calculate"})
* @Serializer\SerializedName("extraData")
* @Serializer\Type("array")
*/
public $extraData;
}

View File

@ -1,17 +0,0 @@
<?php
namespace RetailCrm\DeliveryModuleBundle\Model;
use JMS\Serializer\Annotation as Serializer;
class RequestDelete
{
/**
* @var string
*
* @Serializer\Groups({"request"})
* @Serializer\SerializedName("deliveryId")
* @Serializer\Type("string")
*/
public $deliveryId;
}

View File

@ -1,26 +0,0 @@
<?php
namespace RetailCrm\DeliveryModuleBundle\Model;
use JMS\Serializer\Annotation as Serializer;
class RequestPrint
{
/**
* @var string
*
* @Serializer\Groups({"request"})
* @Serializer\SerializedName("type")
* @Serializer\Type("string")
*/
public $type;
/**
* @var string[]
*
* @Serializer\Groups({"request"})
* @Serializer\SerializedName("deliveryIds")
* @Serializer\Type("array")
*/
public $deliveryIds;
}

View File

@ -1,164 +0,0 @@
<?php
namespace RetailCrm\DeliveryModuleBundle\Model;
use JMS\Serializer\Annotation as Serializer;
class RequestSave
{
/**
* Идентификатор доставки в службе доставки. Передается если требуется отредактировать уже оформленную доставку.
*
* @var string
*
* @Serializer\Groups({"request"})
* @Serializer\SerializedName("deliveryId")
* @Serializer\Type("string")
*/
public $deliveryId;
/**
* Id заказа.
*
* @var string
*
* @Serializer\Groups({"request"})
* @Serializer\SerializedName("order")
* @Serializer\Type("string")
*/
public $order;
/**
* Номер заказа.
*
* @var string
*
* @Serializer\Groups({"request"})
* @Serializer\SerializedName("orderNumber")
* @Serializer\Type("string")
*/
public $orderNumber;
/**
* Код магазина.
*
* @var string
*
* @Serializer\Groups({"request"})
* @Serializer\SerializedName("site")
* @Serializer\Type("string")
*/
public $site;
/**
* Название магазина.
*
* @var string
*
* @Serializer\Groups({"request"})
* @Serializer\SerializedName("siteName")
* @Serializer\Type("string")
*/
public $siteName;
/**
* Склад.
*
* @var string
*
* @Serializer\Groups({"request"})
* @Serializer\SerializedName("store")
* @Serializer\Type("RetailCrm\DeliveryModuleBundle\Model\Store")
*/
public $store;
/**
* Наименование юр.лица.
*
* @var string
*
* @Serializer\Groups({"request"})
* @Serializer\SerializedName("legalEntity")
* @Serializer\Type("string")
*/
public $legalEntity;
/**
* Покупатель.
*
* @var Customer
*
* @Serializer\Groups({"request"})
* @Serializer\SerializedName("customer")
* @Serializer\Type("RetailCrm\DeliveryModuleBundle\Model\Customer")
*/
public $customer;
/**
* Менеджер, работающий с покупателем
*
* @var Manager
*
* @Serializer\Groups({"request"})
* @Serializer\SerializedName("manager")
* @Serializer\Type("RetailCrm\DeliveryModuleBundle\Model\Manager")
*/
public $manager;
/**
* Набор упаковок.
*
* @var Package[]
*
* @Serializer\Groups({"request"})
* @Serializer\SerializedName("packages")
* @Serializer\Type("array<RetailCrm\DeliveryModuleBundle\Model\Package>")
*/
public $packages;
/**
* Данные доставки.
*
* @var SaveDeliveryData
*
* @Serializer\Groups({"request"})
* @Serializer\SerializedName("delivery")
* @Serializer\Type("RetailCrm\DeliveryModuleBundle\Model\SaveDeliveryData")
*/
public $delivery;
/**
* Валюта.
*
* @var string
*
* @Serializer\Groups({"request", "calculate"})
* @Serializer\SerializedName("currency")
* @Serializer\Type("string")
*/
public $currency;
public function getFullDeclaredValue()
{
$result = 0;
foreach ($this->packages as $package) {
foreach ($package->items as $item) {
$result += $item->declaredValue * $item->quantity;
}
}
return $result;
}
public function getFullItemsCodValue()
{
$result = 0;
foreach ($this->packages as $package) {
foreach ($package->items as $item) {
$result += $item->cod * $item->quantity;
}
}
return $result;
}
}

View File

@ -1,30 +0,0 @@
<?php
namespace RetailCrm\DeliveryModuleBundle\Model;
use JMS\Serializer\Annotation as Serializer;
class RequestShipmentDelete
{
/**
* Идентификатор отгрузки в службе доставки
*
* @var string
*
* @Serializer\Groups({"request"})
* @Serializer\SerializedName("shipmentId")
* @Serializer\Type("string")
*/
public $shipmentId;
/**
* Дополнительные данные отгрузки
*
* @var array
*
* @Serializer\Groups({"request"})
* @Serializer\SerializedName("extraData")
* @Serializer\Type("array")
*/
public $extraData;
}

View File

@ -1,49 +0,0 @@
<?php
namespace RetailCrm\DeliveryModuleBundle\Model;
use JMS\Serializer\Annotation as Serializer;
class RequestShipmentPointList
{
/**
* @var string
*
* @Serializer\Groups({"request"})
* @Serializer\SerializedName("country")
* @Serializer\Type("string")
*/
public $country;
/**
* @var string
* @Serializer\Groups({"request"})
* @Serializer\SerializedName("region")
* @Serializer\Type("string")
*/
public $region;
/**
* @var int
* @Serializer\Groups({"request"})
* @Serializer\SerializedName("regionId")
* @Serializer\Type("integer")
*/
public $regionId;
/**
* @var string
* @Serializer\Groups({"request"})
* @Serializer\SerializedName("city")
* @Serializer\Type("string")
*/
public $city;
/**
* @var int
* @Serializer\Groups({"request"})
* @Serializer\SerializedName("cityId")
* @Serializer\Type("integer")
*/
public $cityId;
}

View File

@ -1,96 +0,0 @@
<?php
namespace RetailCrm\DeliveryModuleBundle\Model;
use JMS\Serializer\Annotation as Serializer;
class RequestShipmentSave
{
use Traits\ExtraDataTrait;
/**
* Идентификатор отгрузки в службе доставки. Передается если требуется отредактировать уже оформленную отгрузку
*
* @var string
*
* @Serializer\Groups({"request"})
* @Serializer\SerializedName("shipmentId")
* @Serializer\Type("string")
*/
public $shipmentId;
/**
* Менеджер, отвечающий за отгрузку
*
* @var Manager
*
* @Serializer\Groups({"request"})
* @Serializer\SerializedName("manager")
* @Serializer\Type("RetailCrm\DeliveryModuleBundle\Model\Manager")
*/
public $manager;
/**
* Дата отгрузки
*
* @var DateTime
*
* @Serializer\Groups({"get"})
* @Serializer\SerializedName("date")
* @Serializer\Type("DateTime<'Y-m-d'>")
*/
public $date;
/**
* Время доставки ("custom" не ипользуется)
*
* @var RetailCrm\DeliveryModuleBundle\Model\DeliveryTime
*
* @Serializer\Groups({"get"})
* @Serializer\SerializedName("time")
* @Serializer\Type("RetailCrm\DeliveryModuleBundle\Model\DeliveryTime")
*/
public $time;
/**
* Адрес отгрузки
*
* @var string
*
* @Serializer\Groups({"get"})
* @Serializer\SerializedName("address")
* @Serializer\Type("RetailCrm\DeliveryModuleBundle\Model\DeliveryAddress")
*/
public $address;
/**
* Массив идентификаторов оформленных доставок в службе доставки
*
* @var array
*
* @Serializer\Groups({"get"})
* @Serializer\SerializedName("orders")
* @Serializer\Type("array<RetailCrm\DeliveryModuleBundle\Model\ShipmentOrder>")
*/
public $orders;
/**
* @var string
*
* @Serializer\Groups({"get"})
* @Serializer\SerializedName("comment")
* @Serializer\Type("string")
*/
public $comment;
/**
* Дополнительные данные отгрузки
*
* @var array
*
* @Serializer\Groups({"get"})
* @Serializer\SerializedName("extraData")
* @Serializer\Type("array")
*/
public $extraData;
}

View File

@ -1,57 +0,0 @@
<?php
namespace RetailCrm\DeliveryModuleBundle\Model;
use JMS\Serializer\Annotation as Serializer;
class RequestStatusUpdateItem
{
/**
* Идентификатор доставки с СД
*
* @var string
*
* @Serializer\Groups({"request"})
* @Serializer\SerializedName("deliveryId")
* @Serializer\Type("string")
*/
public $deliveryId;
/**
* Трек номер
*
* @var string
*
* @Serializer\Groups({"request"})
* @Serializer\SerializedName("trackNumber")
* @Serializer\Type("string")
*/
public $trackNumber;
/**
* История смены статусов доставки
*
* @var StatusInfo[]
*
* @Serializer\Groups({"request"})
* @Serializer\SerializedName("history")
* @Serializer\Type("array<RetailCrm\DeliveryModuleBundle\Model\StatusInfo>")
*/
public $history;
/**
* Массив дополнительных данных доставки
*
* @var array
*
* @Serializer\Groups({"request"})
* @Serializer\SerializedName("extraData")
* @Serializer\Type("array")
*/
public $extraData;
public function __construct()
{
$this->history = [];
}
}

View File

@ -1,42 +0,0 @@
<?php
namespace RetailCrm\DeliveryModuleBundle\Model;
use JMS\Serializer\Annotation as Serializer;
class ResponseAutocompleteItem
{
/**
* @var string
*
* @Serializer\Groups({"response"})
* @Serializer\SerializedName("value")
* @Serializer\Type("string")
*/
public $value;
/**
* @var string
*
* @Serializer\Groups({"response"})
* @Serializer\SerializedName("label")
* @Serializer\Type("string")
*/
public $label;
/**
* @var string
*
* @Serializer\Groups({"response"})
* @Serializer\SerializedName("description")
* @Serializer\Type("string")
*/
public $description;
public function __construct($value, $label, $description = null)
{
$this->value = $value;
$this->label = $label;
$this->description = $description;
}
}

View File

@ -1,26 +0,0 @@
<?php
namespace RetailCrm\DeliveryModuleBundle\Model;
use JMS\Serializer\Annotation as Serializer;
class ResponseAutocompleteSuccessful
{
/**
* @var bool
*
* @Serializer\Groups({"get", "response"})
* @Serializer\SerializedName("success")
* @Serializer\Type("boolean")
*/
public $success = true;
/**
* @var mixed
*
* @Serializer\Groups({"get", "response"})
* @Serializer\SerializedName("result")
* @Serializer\Type("array<RetailCrm\DeliveryModuleBundle\Model\ResponseAutocompleteItem>")
*/
public $result;
}

View File

@ -1,137 +0,0 @@
<?php
namespace RetailCrm\DeliveryModuleBundle\Model;
use JMS\Serializer\Annotation as Serializer;
class ResponseCalculate
{
const TARIFF_COURIER = 'courier';
const TARIFF_SELF_DELIVERY = 'selfDelivery';
/**
* Код тарифа
*
* @var string
*
* @Serializer\Groups({"response"})
* @Serializer\SerializedName("code")
* @Serializer\Type("string")
*/
public $code;
/**
* Группа тарифов
*
* @var string
*
* @Serializer\Groups({"response"})
* @Serializer\SerializedName("group")
* @Serializer\Type("string")
*/
public $group;
/**
* Наименование тарифа
*
* @var string
*
* @Serializer\Groups({"response"})
* @Serializer\SerializedName("name")
* @Serializer\Type("string")
*/
public $name;
/**
* Тип тарифа (курьерская доставка или самовывоз)
*
* @var string
*
* @Serializer\Groups({"response"})
* @Serializer\SerializedName("type")
* @Serializer\Type("string")
*/
public $type;
/**
* Описание
*
* @var string
*
* @Serializer\Groups({"response"})
* @Serializer\SerializedName("description")
* @Serializer\Type("string")
*/
public $description;
/**
* Стоимость доставки
*
* @var string
*
* @Serializer\Groups({"response"})
* @Serializer\SerializedName("cost")
* @Serializer\Type("float")
*/
public $cost;
/**
* Минимальный срок доставки
*
* @var int
*
* @Serializer\Groups({"response"})
* @Serializer\SerializedName("minTerm")
* @Serializer\Type("integer")
*/
public $minTerm;
/**
* Максимальный срок доставки
*
* @var int
*
* @Serializer\Groups({"response"})
* @Serializer\SerializedName("maxTerm")
* @Serializer\Type("integer")
*/
public $maxTerm;
/**
* Дополнительные данные доставки
*
* @var array
*
* @Serializer\Groups({"response"})
* @Serializer\SerializedName("extraData")
* @Serializer\Type("array")
*/
public $extraData;
/**
* Возможные дополнительные данные доставки
*
* @var array
*
* @Serializer\Groups({"response"})
* @Serializer\SerializedName("extraDataAvailable")
* @Serializer\Type("array")
*/
public $extraDataAvailable;
/**
* Список доступных терминалов выдачи посылки
*
* @var Terminal[]
*
* @Serializer\Groups({"response"})
* @Serializer\SerializedName("pickuppointList")
* @Serializer\Type("array<RetailCrm\DeliveryModuleBundle\Model\Terminal>")
*/
public $pickuppointList;
public function __construct()
{
$this->extraData = [];
}
}

View File

@ -1,26 +0,0 @@
<?php
namespace RetailCrm\DeliveryModuleBundle\Model;
use JMS\Serializer\Annotation as Serializer;
class ResponseCalculateSuccessful
{
/**
* @var bool
*
* @Serializer\Groups({"get", "response"})
* @Serializer\SerializedName("success")
* @Serializer\Type("boolean")
*/
public $success = true;
/**
* @var mixed
*
* @Serializer\Groups({"get", "response"})
* @Serializer\SerializedName("result")
* @Serializer\Type("array<RetailCrm\DeliveryModuleBundle\Model\ResponseCalculate>")
*/
public $result;
}

View File

@ -1,148 +0,0 @@
<?php
namespace RetailCrm\DeliveryModuleBundle\Model;
use JMS\Serializer\Annotation as Serializer;
class ResponseLoadDeliveryData
{
/**
* Трек номер
*
* @var string
*
* @Serializer\Groups({"response"})
* @Serializer\SerializedName("trackNumber")
* @Serializer\Type("string")
*/
public $trackNumber;
/**
* Стоимость доставки
*
* @var float
*
* @Serializer\Groups({"response"})
* @Serializer\SerializedName("cost")
* @Serializer\Type("float")
*/
public $cost;
/**
* Дата отгрузки
*
* @var \DateTime
*
* @Serializer\Groups({"response"})
* @Serializer\SerializedName("shipmentDate")
* @Serializer\Type("DateTime<'Y-m-d'>")
*/
public $shipmentDate;
/**
* Дата доставки
*
* @var string
*
* @Serializer\Groups({"response"})
* @Serializer\SerializedName("deliveryDate")
* @Serializer\Type("DateTime<'Y-m-d'>")
*/
public $deliveryDate;
/**
* Время доставки
*
* @var RetailCrm\DeliveryModuleBundle\Model\DeliveryTime
*
* @Serializer\Groups({"response"})
* @Serializer\SerializedName("deliveryTime")
* @Serializer\Type("RetailCrm\DeliveryModuleBundle\Model\DeliveryTime")
*/
public $deliveryTime;
/**
* Код тарифа
*
* @var string
*
* @Serializer\Groups({"response"})
* @Serializer\SerializedName("tariff")
* @Serializer\Type("string")
*/
public $tariff;
/**
* Наименование тарифа
*
* @var string
*
* @Serializer\Groups({"response"})
* @Serializer\SerializedName("tariffName")
* @Serializer\Type("string")
*/
public $tariffName;
/**
* Плательщик за доставку
*
* @var string
*
* @Serializer\Groups({"response"})
* @Serializer\SerializedName("payerType")
* @Serializer\Type("string")
*/
public $payerType;
/**
* Текущий статус достаквки
*
* @var StatusInfo
*
* @Serializer\Groups({"response"})
* @Serializer\SerializedName("status")
* @Serializer\Type("RetailCrm\DeliveryModuleBundle\Model\StatusInfo")
*/
public $status;
/**
* Дополнительные данные доставки
*
* @var string
*
* @Serializer\Groups({"response"})
* @Serializer\SerializedName("extraData")
* @Serializer\Type("array")
*/
public $extraData;
/**
* Адрес отгрузки
*
* @var DeliveryAddress
*
* @Serializer\Groups({"response"})
* @Serializer\SerializedName("shipmentAddress")
* @Serializer\Type("RetailCrm\DeliveryModuleBundle\Model\DeliveryAddress")
*/
public $shipmentAddress;
/**
* Адрес доставки
*
* @var DeliveryAddress
*
* @Serializer\Groups({"response"})
* @Serializer\SerializedName("deliveryAddress")
* @Serializer\Type("RetailCrm\DeliveryModuleBundle\Model\DeliveryAddress")
*/
public $deliveryAddress;
public $additionalData;
public function __construct()
{
$this->extraData = [];
$this->additionalData = [];
}
}

View File

@ -1,7 +0,0 @@
<?php
namespace RetailCrm\DeliveryModuleBundle\Model;
class ResponseResult
{
}

View File

@ -1,71 +0,0 @@
<?php
namespace RetailCrm\DeliveryModuleBundle\Model;
use JMS\Serializer\Annotation as Serializer;
class ResponseSave
{
/**
* Идентификатор доставки в службе доставки
*
* @var string
*
* @Serializer\Groups({"response"})
* @Serializer\SerializedName("deliveryId")
* @Serializer\Type("string")
*/
public $deliveryId;
/**
* Трек номер
*
* @var string
*
* @Serializer\Groups({"response"})
* @Serializer\SerializedName("trackNumber")
* @Serializer\Type("string")
*/
public $trackNumber;
/**
* Стоимость доставки
*
* @var float
*
* @Serializer\Groups({"response"})
* @Serializer\SerializedName("cost")
* @Serializer\Type("float")
*/
public $cost;
/**
* Код статуса доставки
*
* @var string
*
* @Serializer\Groups({"response"})
* @Serializer\SerializedName("status")
* @Serializer\Type("string")
*/
public $status;
/**
* Дополнительные данные доставки
*
* @var string
*
* @Serializer\Groups({"response"})
* @Serializer\SerializedName("extraData")
* @Serializer\Type("array")
*/
public $extraData;
public $additionalData;
public function __construct()
{
$this->extraData = [];
$this->additionalData = [];
}
}

View File

@ -1,38 +0,0 @@
<?php
namespace RetailCrm\DeliveryModuleBundle\Model;
use JMS\Serializer\Annotation as Serializer;
use Symfony\Component\Validator\Constraints as Assert;
use Symfony\Component\Validator\Mapping\ClassMetadata;
class ResponseShipmentSave
{
/**
* Идентификатор отгрузки в службе доставки.
*
* @var string
*
* @Serializer\Groups({"response"})
* @Serializer\SerializedName("shipmentId")
* @Serializer\Type("string")
*/
public $shipmentId;
/**
* Дополнительные данные доставки
*
* @var string
*
* @Serializer\Groups({"response"})
* @Serializer\SerializedName("extraData")
* @Serializer\Type("array<string, string>")
*/
public $extraData;
public static function loadValidatorMetadata(ClassMetadata $metadata)
{
$metadata
->addPropertyConstraint('shipmentId', new Assert\NotBlank());
}
}

View File

@ -1,26 +0,0 @@
<?php
namespace RetailCrm\DeliveryModuleBundle\Model;
use JMS\Serializer\Annotation as Serializer;
class ResponseSuccessful
{
/**
* @var bool
*
* @Serializer\Groups({"get", "response"})
* @Serializer\SerializedName("success")
* @Serializer\Type("boolean")
*/
public $success = true;
/**
* @var mixed
*
* @Serializer\Groups({"get", "response"})
* @Serializer\SerializedName("result")
* @Serializer\Type("RetailCrm\DeliveryModuleBundle\Model\ResponseResult")
*/
public $result;
}

View File

@ -1,42 +0,0 @@
<?php
namespace RetailCrm\DeliveryModuleBundle\Model;
use JMS\Serializer\Annotation as Serializer;
class ResponseAutocompleteItem
{
/**
* @var string
*
* @Serializer\Groups({"response"})
* @Serializer\SerializedName("value")
* @Serializer\Type("string")
*/
public $value;
/**
* @var string
*
* @Serializer\Groups({"response"})
* @Serializer\SerializedName("label")
* @Serializer\Type("string")
*/
public $label;
/**
* @var string
*
* @Serializer\Groups({"response"})
* @Serializer\SerializedName("description")
* @Serializer\Type("string")
*/
public $description;
public function __construct($value, $label, $description = null)
{
$this->value = $value;
$this->label = $label;
$this->description = $description;
}
}

View File

@ -1,26 +0,0 @@
<?php
namespace RetailCrm\DeliveryModuleBundle\Model;
use JMS\Serializer\Annotation as Serializer;
class ResponseAutocompleteSuccessful
{
/**
* @var bool
*
* @Serializer\Groups({"get", "response"})
* @Serializer\SerializedName("success")
* @Serializer\Type("boolean")
*/
public $success = true;
/**
* @var mixed
*
* @Serializer\Groups({"get", "response"})
* @Serializer\SerializedName("result")
* @Serializer\Type("array<RetailCrm\DeliveryModuleBundle\Model\ResponseAutocompleteItem>")
*/
public $result;
}

View File

@ -1,137 +0,0 @@
<?php
namespace RetailCrm\DeliveryModuleBundle\Model;
use JMS\Serializer\Annotation as Serializer;
class ResponseCalculate
{
const TARIFF_COURIER = 'courier';
const TARIFF_SELF_DELIVERY = 'selfDelivery';
/**
* Код тарифа
*
* @var string
*
* @Serializer\Groups({"response"})
* @Serializer\SerializedName("code")
* @Serializer\Type("string")
*/
public $code;
/**
* Группа тарифов
*
* @var string
*
* @Serializer\Groups({"response"})
* @Serializer\SerializedName("group")
* @Serializer\Type("string")
*/
public $group;
/**
* Наименование тарифа
*
* @var string
*
* @Serializer\Groups({"response"})
* @Serializer\SerializedName("name")
* @Serializer\Type("string")
*/
public $name;
/**
* Тип тарифа (курьерская доставка или самовывоз)
*
* @var string
*
* @Serializer\Groups({"response"})
* @Serializer\SerializedName("type")
* @Serializer\Type("string")
*/
public $type;
/**
* Описание
*
* @var string
*
* @Serializer\Groups({"response"})
* @Serializer\SerializedName("description")
* @Serializer\Type("string")
*/
public $description;
/**
* Стоимость доставки
*
* @var string
*
* @Serializer\Groups({"response"})
* @Serializer\SerializedName("cost")
* @Serializer\Type("float")
*/
public $cost;
/**
* Минимальный срок доставки
*
* @var int
*
* @Serializer\Groups({"response"})
* @Serializer\SerializedName("minTerm")
* @Serializer\Type("integer")
*/
public $minTerm;
/**
* Максимальный срок доставки
*
* @var int
*
* @Serializer\Groups({"response"})
* @Serializer\SerializedName("maxTerm")
* @Serializer\Type("integer")
*/
public $maxTerm;
/**
* Дополнительные данные доставки
*
* @var array
*
* @Serializer\Groups({"response"})
* @Serializer\SerializedName("extraData")
* @Serializer\Type("array")
*/
public $extraData;
/**
* Возможные дополнительные данные доставки
*
* @var array
*
* @Serializer\Groups({"response"})
* @Serializer\SerializedName("extraDataAvailable")
* @Serializer\Type("array")
*/
public $extraDataAvailable;
/**
* Список доступных терминалов выдачи посылки
*
* @var Terminal[]
*
* @Serializer\Groups({"response"})
* @Serializer\SerializedName("pickuppointList")
* @Serializer\Type("array<RetailCrm\DeliveryModuleBundle\Model\Terminal>")
*/
public $pickuppointList;
public function __construct()
{
$this->extraData = [];
}
}

View File

@ -1,17 +0,0 @@
<?php
namespace RetailCrm\DeliveryModuleBundle\Model;
use JMS\Serializer\Annotation as Serializer;
class ResponseCalculateSuccessful extends AbstractResponseSuccessful
{
/**
* @var mixed
*
* @Serializer\Groups({"get", "response"})
* @Serializer\SerializedName("result")
* @Serializer\Type("array<RetailCrm\DeliveryModuleBundle\Model\ResponseCalculate>")
*/
public $result;
}

View File

@ -1,148 +0,0 @@
<?php
namespace RetailCrm\DeliveryModuleBundle\Model;
use JMS\Serializer\Annotation as Serializer;
class ResponseLoadDeliveryData
{
/**
* Трек номер
*
* @var string
*
* @Serializer\Groups({"response"})
* @Serializer\SerializedName("trackNumber")
* @Serializer\Type("string")
*/
public $trackNumber;
/**
* Стоимость доставки
*
* @var float
*
* @Serializer\Groups({"response"})
* @Serializer\SerializedName("cost")
* @Serializer\Type("float")
*/
public $cost;
/**
* Дата отгрузки
*
* @var \DateTime
*
* @Serializer\Groups({"response"})
* @Serializer\SerializedName("shipmentDate")
* @Serializer\Type("DateTime<'Y-m-d'>")
*/
public $shipmentDate;
/**
* Дата доставки
*
* @var string
*
* @Serializer\Groups({"response"})
* @Serializer\SerializedName("deliveryDate")
* @Serializer\Type("DateTime<'Y-m-d'>")
*/
public $deliveryDate;
/**
* Время доставки
*
* @var RetailCrm\DeliveryModuleBundle\Model\DeliveryTime
*
* @Serializer\Groups({"response"})
* @Serializer\SerializedName("deliveryTime")
* @Serializer\Type("RetailCrm\DeliveryModuleBundle\Model\DeliveryTime")
*/
public $deliveryTime;
/**
* Код тарифа
*
* @var string
*
* @Serializer\Groups({"response"})
* @Serializer\SerializedName("tariff")
* @Serializer\Type("string")
*/
public $tariff;
/**
* Наименование тарифа
*
* @var string
*
* @Serializer\Groups({"response"})
* @Serializer\SerializedName("tariffName")
* @Serializer\Type("string")
*/
public $tariffName;
/**
* Плательщик за доставку
*
* @var string
*
* @Serializer\Groups({"response"})
* @Serializer\SerializedName("payerType")
* @Serializer\Type("string")
*/
public $payerType;
/**
* Текущий статус достаквки
*
* @var StatusInfo
*
* @Serializer\Groups({"response"})
* @Serializer\SerializedName("status")
* @Serializer\Type("RetailCrm\DeliveryModuleBundle\Model\StatusInfo")
*/
public $status;
/**
* Дополнительные данные доставки
*
* @var string
*
* @Serializer\Groups({"response"})
* @Serializer\SerializedName("extraData")
* @Serializer\Type("array")
*/
public $extraData;
/**
* Адрес отгрузки
*
* @var DeliveryAddress
*
* @Serializer\Groups({"response"})
* @Serializer\SerializedName("shipmentAddress")
* @Serializer\Type("RetailCrm\DeliveryModuleBundle\Model\DeliveryAddress")
*/
public $shipmentAddress;
/**
* Адрес доставки
*
* @var DeliveryAddress
*
* @Serializer\Groups({"response"})
* @Serializer\SerializedName("deliveryAddress")
* @Serializer\Type("RetailCrm\DeliveryModuleBundle\Model\DeliveryAddress")
*/
public $deliveryAddress;
public $additionalData;
public function __construct()
{
$this->extraData = [];
$this->additionalData = [];
}
}

View File

@ -1,7 +0,0 @@
<?php
namespace RetailCrm\DeliveryModuleBundle\Model;
class ResponseResult
{
}

View File

@ -1,72 +0,0 @@
<?php
namespace RetailCrm\DeliveryModuleBundle\Model;
use JMS\Serializer\Annotation as Serializer;
class ResponseSave
{
/**
* Идентификатор доставки в службе доставки.
*
* @var string
*
* @Serializer\Groups({"response"})
* @Serializer\SerializedName("deliveryId")
* @Serializer\Type("string")
*/
public $deliveryId;
/**
* Трек номер
*
* @var string
*
* @Serializer\Groups({"response"})
* @Serializer\SerializedName("trackNumber")
* @Serializer\Type("string")
*/
public $trackNumber;
/**
* Стоимость доставки.
*
* @var float
*
* @Serializer\Groups({"response"})
* @Serializer\SerializedName("cost")
* @Serializer\Type("float")
*/
public $cost;
/**
* Код статуса доставки.
*
* @var string
*
* @Serializer\Groups({"response"})
* @Serializer\SerializedName("status")
* @Serializer\Type("string")
*/
public $status;
/**
* Дополнительные данные доставки.
*
* @var string
*
* @Serializer\Groups({"response"})
* @Serializer\SerializedName("extraData")
* @Serializer\Type("array")
*/
public $extraData;
public $additionalData;
public $saveDataHash;
public function __construct()
{
$this->extraData = [];
$this->additionalData = [];
}
}

View File

@ -1,17 +0,0 @@
<?php
namespace RetailCrm\DeliveryModuleBundle\Model;
use JMS\Serializer\Annotation as Serializer;
class ResponseShipmentPointListSuccessful extends AbstractResponseSuccessful
{
/**
* @var mixed
*
* @Serializer\Groups({"get", "response"})
* @Serializer\SerializedName("result")
* @Serializer\Type("array<RetailCrm\DeliveryModuleBundle\Model\Terminal>")
*/
public $result;
}

View File

@ -1,38 +0,0 @@
<?php
namespace RetailCrm\DeliveryModuleBundle\Model;
use JMS\Serializer\Annotation as Serializer;
use Symfony\Component\Validator\Constraints as Assert;
use Symfony\Component\Validator\Mapping\ClassMetadata;
class ResponseShipmentSave
{
/**
* Идентификатор отгрузки в службе доставки.
*
* @var string
*
* @Serializer\Groups({"response"})
* @Serializer\SerializedName("shipmentId")
* @Serializer\Type("string")
*/
public $shipmentId;
/**
* Дополнительные данные доставки
*
* @var string
*
* @Serializer\Groups({"response"})
* @Serializer\SerializedName("extraData")
* @Serializer\Type("array<string, string>")
*/
public $extraData;
public static function loadValidatorMetadata(ClassMetadata $metadata)
{
$metadata
->addPropertyConstraint('shipmentId', new Assert\NotBlank());
}
}

View File

@ -1,17 +0,0 @@
<?php
namespace RetailCrm\DeliveryModuleBundle\Model;
use JMS\Serializer\Annotation as Serializer;
class ResponseSuccessful extends AbstractResponseSuccessful
{
/**
* @var mixed
*
* @Serializer\Groups({"get", "response"})
* @Serializer\SerializedName("result")
* @Serializer\Type("RetailCrm\DeliveryModuleBundle\Model\ResponseResult")
*/
public $result;
}

View File

@ -1,151 +0,0 @@
<?php
namespace RetailCrm\DeliveryModuleBundle\Model;
use JMS\Serializer\Annotation as Serializer;
class SaveDeliveryData
{
/**
* Адрес отгрузки.
*
* @var string
*
* @Serializer\Groups({"get"})
* @Serializer\SerializedName("shipmentAddress")
* @Serializer\Type("RetailCrm\DeliveryModuleBundle\Model\DeliveryAddress")
*/
public $shipmentAddress;
/**
* Адрес доставки.
*
* @var string
*
* @Serializer\Groups({"get"})
* @Serializer\SerializedName("deliveryAddress")
* @Serializer\Type("RetailCrm\DeliveryModuleBundle\Model\DeliveryAddress")
*/
public $deliveryAddress;
/**
* Тип оплаты для наложенного платежа.
*
* @var PaymentType
*
* @Serializer\Groups({"get"})
* @Serializer\SerializedName("codPaymentType")
* @Serializer\Type("RetailCrm\DeliveryModuleBundle\Model\PaymentType")
*/
public $codPaymentType;
/**
* Доставка наложенным платежом
*
* @var bool
*
* @Serializer\Groups({"get"})
* @Serializer\SerializedName("withCod")
* @Serializer\Type("boolean")
*/
public $withCod;
/**
* Величина наложенного платежа за услуги доставки.
*
* @var float
*
* @Serializer\Groups({"get"})
* @Serializer\SerializedName("cod")
* @Serializer\Type("float")
*/
public $cod;
/**
* Стоимость доставки (указывается в накладной в случае предоплаты).
*
* @var float
*
* @Serializer\Groups({"get"})
* @Serializer\SerializedName("cost")
* @Serializer\Type("float")
*/
public $cost;
/**
* Ставка НДС для услуги доставки.
*
* @var float
*
* @Serializer\Groups({"get"})
* @Serializer\SerializedName("vatRate")
* @Serializer\Type("float")
*/
public $vatRate;
/**
* Код тарифа.
*
* @var string
*
* @Serializer\Groups({"get"})
* @Serializer\SerializedName("tariff")
* @Serializer\Type("string")
*/
public $tariff;
/**
* Плательщик за услуги доставки.
*
* @var string
*
* @Serializer\Groups({"get"})
* @Serializer\SerializedName("payerType")
* @Serializer\Type("string")
*/
public $payerType;
/**
* Дата отгрузки.
*
* @var \DateTime
*
* @Serializer\Groups({"get"})
* @Serializer\SerializedName("shipmentDate")
* @Serializer\Type("DateTime<'Y-m-d'>")
*/
public $shipmentDate;
/**
* Дата доставки.
*
* @var \DateTime
*
* @Serializer\Groups({"get"})
* @Serializer\SerializedName("deliveryDate")
* @Serializer\Type("DateTime<'Y-m-d'>")
*/
public $deliveryDate;
/**
* Время доставки ("custom" не ипользуется).
*
* @var \RetailCrm\DeliveryModuleBundle\Model\DeliveryTime
*
* @Serializer\Groups({"get"})
* @Serializer\SerializedName("deliveryTime")
* @Serializer\Type("RetailCrm\DeliveryModuleBundle\Model\DeliveryTime")
*/
public $deliveryTime;
/**
* Дополнительные данные доставки.
*
* @var array
*
* @Serializer\Groups({"get"})
* @Serializer\SerializedName("extraData")
* @Serializer\Type("array")
*/
public $extraData;
}

View File

@ -1,96 +0,0 @@
<?php
namespace RetailCrm\DeliveryModuleBundle\Model;
use JMS\Serializer\Annotation as Serializer;
use RetailCrm\DeliveryModuleBundle\Model\Settings\ExtraData;
use RetailCrm\DeliveryModuleBundle\Model\Settings\PaymentType;
use RetailCrm\DeliveryModuleBundle\Model\Settings\ShipmentPoint;
use RetailCrm\DeliveryModuleBundle\Model\Settings\Status;
class Settings
{
public const COST_CALCULATE_BY_MODULE = 'auto';
public const COST_CALCULATE_BY_SYSTEM = 'manual';
/**
* @var string
*
* @Serializer\Groups({"set", "get"})
* @Serializer\SerializedName("defaultPayerType")
* @Serializer\Type("string")
*/
public $defaultPayerType;
/**
* @var string
*
* @Serializer\Groups({"set", "get"})
* @Serializer\SerializedName("costCalculateBy")
* @Serializer\Type("string")
*/
public $costCalculateBy;
/**
* @var bool
*
* @Serializer\Groups({"set", "get"})
* @Serializer\SerializedName("nullDeclaredValue")
* @Serializer\Type("boolean")
*/
public $nullDeclaredValue;
/**
* @var bool
*
* @Serializer\Groups({"set", "get"})
* @Serializer\SerializedName("lockedByDefault")
* @Serializer\Type("boolean")
*/
public $lockedByDefault;
/**
* @var array|PaymentType[]
*
* @Serializer\Groups({"set", "get"})
* @Serializer\SerializedName("paymentTypes")
* @Serializer\Type("array<RetailCrm\DeliveryModuleBundle\Model\Settings\PaymentType>")
*/
public $paymentTypes;
/**
* @var array|ShipmentPoint[]
*
* @Serializer\Groups({"set", "get"})
* @Serializer\SerializedName("shipmentPoints")
* @Serializer\Type("array<RetailCrm\DeliveryModuleBundle\Model\Settings\ShipmentPoint>")
*/
public $shipmentPoints;
/**
* @var array|Status[]
*
* @Serializer\Groups({"set", "get"})
* @Serializer\SerializedName("statuses")
* @Serializer\Type("array<RetailCrm\DeliveryModuleBundle\Model\Settings\Status>")
*/
public $statuses;
/**
* @var array|ExtraData[]
*
* @Serializer\Groups({"set", "get"})
* @Serializer\SerializedName("deliveryExtraData")
* @Serializer\Type("array")
*/
public $deliveryExtraData;
/**
* @var array|ExtraData[]
*
* @Serializer\Groups({"set", "get"})
* @Serializer\SerializedName("shipmentExtraData")
* @Serializer\Type("array")
*/
public $shipmentExtraData;
}

View File

@ -1,35 +0,0 @@
<?php
namespace RetailCrm\DeliveryModuleBundle\Model\Settings;
use JMS\Serializer\Annotation as Serializer;
class PaymentType
{
/**
* @var string
*
* @Serializer\Groups({"set", "get"})
* @Serializer\SerializedName("code")
* @Serializer\Type("string")
*/
public $code;
/**
* @var bool
*
* @Serializer\Groups({"set", "get"})
* @Serializer\SerializedName("active")
* @Serializer\Type("boolean")
*/
public $active = true;
/**
* @var bool
*
* @Serializer\Groups({"set", "get"})
* @Serializer\SerializedName("cod")
* @Serializer\Type("boolean")
*/
public $cod = false;
}

View File

@ -1,35 +0,0 @@
<?php
namespace RetailCrm\DeliveryModuleBundle\Model\Settings;
use JMS\Serializer\Annotation as Serializer;
class ShipmentPoint
{
/**
* @var string
*
* @Serializer\Groups({"set", "get"})
* @Serializer\SerializedName("code")
* @Serializer\Type("string")
*/
public $code;
/**
* @var int
*
* @Serializer\Groups({"set", "get"})
* @Serializer\SerializedName("shipmentPointId")
* @Serializer\Type("integer")
*/
public $shipmentPointId;
/**
* @var string
*
* @Serializer\Groups({"set", "get"})
* @Serializer\SerializedName("shipmentPointLabel")
* @Serializer\Type("string")
*/
public $shipmentPointLabel;
}

View File

@ -1,26 +0,0 @@
<?php
namespace RetailCrm\DeliveryModuleBundle\Model\Settings;
use JMS\Serializer\Annotation as Serializer;
class Status
{
/**
* @var string
*
* @Serializer\Groups({"set", "get"})
* @Serializer\SerializedName("code")
* @Serializer\Type("string")
*/
public $code;
/**
* @var mixed
*
* @Serializer\Groups({"set", "get"})
* @Serializer\SerializedName("trackingStatusCode")
* @Serializer\Type("string")
*/
public $trackingStatusCode;
}

View File

@ -1,30 +0,0 @@
<?php
namespace RetailCrm\DeliveryModuleBundle\Model;
use JMS\Serializer\Annotation as Serializer;
class ShipmentOrder
{
/**
* Идентификатор оформленной доставки в службе доставки.
*
* @var array
*
* @Serializer\Groups({"get"})
* @Serializer\SerializedName("deliveryId")
* @Serializer\Type("string")
*/
public $deliveryId;
/**
* Набор упаковок.
*
* @var Package[]
*
* @Serializer\Groups({"request"})
* @Serializer\SerializedName("packages")
* @Serializer\Type("array<RetailCrm\DeliveryModuleBundle\Model\Package>")
*/
public $packages;
}

View File

@ -1,48 +0,0 @@
<?php
namespace RetailCrm\DeliveryModuleBundle\Model;
use JMS\Serializer\Annotation as Serializer;
class Status
{
/**
* Код статуса доставки
*
* @var string
*
* @Serializer\Groups({"get"})
* @Serializer\SerializedName("code")
* @Serializer\Type("string")
*/
public $code;
/**
* Наименование статуса
*
* @var string
*
* @Serializer\Groups({"get"})
* @Serializer\SerializedName("name")
* @Serializer\Type("string")
*/
public $name;
/**
* Если заказ находится в статусе у которого isEditable:true, это означает можно редактировать данные доставки
*
* @var bool
*
* @Serializer\Groups({"get"})
* @Serializer\SerializedName("isEditable")
* @Serializer\Type("boolean")
*/
public $isEditable = false;
public function __construct($code, $name, $isEditable)
{
$this->code = $code;
$this->name = $name;
$this->isEditable = $isEditable;
}
}

View File

@ -1,41 +0,0 @@
<?php
namespace RetailCrm\DeliveryModuleBundle\Model;
use JMS\Serializer\Annotation as Serializer;
class StatusInfo
{
/**
* Код статуса доставки
*
* @var string
*
* @Serializer\Groups({"get", "response"})
* @Serializer\SerializedName("code")
* @Serializer\Type("string")
*/
public $code;
/**
* Дата обновления статуса доставки
*
* @var \DateTime
*
* @Serializer\Groups({"get", "response"})
* @Serializer\SerializedName("updatedAt")
* @Serializer\Type("DateTime<'Y-m-d\TH:i:sP'>")
*/
public $updatedAt;
/**
* Комментарий к статусу
*
* @var string
*
* @Serializer\Groups({"get", "response"})
* @Serializer\SerializedName("comment")
* @Serializer\Type("string")
*/
public $comment;
}

View File

@ -1,26 +0,0 @@
<?php
namespace RetailCrm\DeliveryModuleBundle\Model;
use JMS\Serializer\Annotation as Serializer;
class Store
{
/**
* @var string
*
* @Serializer\Groups({"request"})
* @Serializer\SerializedName("code")
* @Serializer\Type("string")
*/
public $code;
/**
* @var string
*
* @Serializer\Groups({"request"})
* @Serializer\SerializedName("name")
* @Serializer\Type("string")
*/
public $name;
}

View File

@ -1,96 +0,0 @@
<?php
namespace RetailCrm\DeliveryModuleBundle\Model;
use JMS\Serializer\Annotation as Serializer;
class Terminal
{
/**
* Код терминала.
*
* @var string
*
* @Serializer\Groups({"get", "response"})
* @Serializer\SerializedName("code")
* @Serializer\Type("string")
*/
public $code;
/**
* Стоимость доставки до терминала, если она отличается от стоимости в целом по тарифу.
*
* @var string
*
* @Serializer\Groups({"response"})
* @Serializer\SerializedName("cost")
* @Serializer\Type("float")
*/
public $cost;
/**
* Наименование терминала.
*
* @var string
*
* @Serializer\Groups({"get", "response"})
* @Serializer\SerializedName("name")
* @Serializer\Type("string")
*/
public $name;
/**
* Адрес
*
* @var string
*
* @Serializer\Groups({"get", "response"})
* @Serializer\SerializedName("address")
* @Serializer\Type("string")
*/
public $address;
/**
* Режим работы.
*
* @var string
*
* @Serializer\Groups({"get", "response"})
* @Serializer\SerializedName("schedule")
* @Serializer\Type("string")
*/
public $schedule;
/**
* Телефон.
*
* @var string
*
* @Serializer\Groups({"get", "response"})
* @Serializer\SerializedName("phone")
* @Serializer\Type("string")
*/
public $phone;
/**
* Дополнительные данные.
*
* @var string
*
* @Serializer\Groups({"get", "response"})
* @Serializer\SerializedName("extraData")
* @Serializer\Type("array")
*/
public $extraData;
/**
* Координаты.
*
* @var Coordinates
*
* @Serializer\Groups({"get", "response"})
* @Serializer\SerializedName("coordinates")
* @Serializer\Type("RetailCrm\DeliveryModuleBundle\Model\Coordinates")
*/
public $coordinates;
}

View File

@ -1,15 +0,0 @@
<?php
namespace RetailCrm\DeliveryModuleBundle\Model\Traits;
trait ExtraDataTrait
{
public function getExtraData($fieldCode)
{
if (!isset($this->extraData[$fieldCode])) {
return null;
} else {
return $this->extraData[$fieldCode];
}
}
}

View File

@ -1,33 +0,0 @@
<?php
namespace RetailCrm\DeliveryModuleBundle\Model;
class Unit
{
/**
* @var string
*
* @Serializer\Groups({"get", "set"})
* @Serializer\SerializedName("code")
* @Serializer\Type("string")
*/
public $code;
/**
* @var string
*
* @Serializer\Groups({"get", "set"})
* @Serializer\SerializedName("name")
* @Serializer\Type("string")
*/
public $name;
/**
* @var string
*
* @Serializer\Groups({"get", "set"})
* @Serializer\SerializedName("sym")
* @Serializer\Type("string")
*/
public $sym;
}

View File

@ -0,0 +1,27 @@
The RetailCRM DeliveryModuleBundle
=============
The DeliveryModuleBundle is the fastest way to create integration delivery module for RetailCRM.
[![Build Status](https://travis-ci.com/retailcrm/DeliveryModuleBundle.svg?branch=master)](https://travis-ci.org/retailcrm/DeliveryModuleBundle)
Requirements
------------
* PHP >= 7.3
* php-curl
* php-json
* php-zip
* Symfony >= 5.1
Documentation
-------------
Documentation for this bundle is stored under `doc` in this repository.
[Read the Documentation](doc/index.md)
License
-------
This bundle is released under the [MIT license](LICENSE)

View File

@ -1,51 +0,0 @@
#############
# API
############
retailcrm_delivery_module_api_base:
path: /api
defaults: { _controller: retailcrm.delivery_module.api_controller::index }
retailcrm_delivery_module_api_activity:
path: /api/activity
defaults: { _controller: retailcrm.delivery_module.api_controller::activity }
methods: POST
retailcrm_delivery_module_api_calculate:
path: /api/calculate
defaults: { _controller: retailcrm.delivery_module.api_controller::calculate }
methods: POST
retailcrm_delivery_module_api_save:
path: /api/save
defaults: { _controller: retailcrm.delivery_module.api_controller::save }
methods: POST
retailcrm_delivery_module_api_get:
path: /api/get
defaults: { _controller: retailcrm.delivery_module.api_controller::getDeliveryOrder }
methods: GET
retailcrm_delivery_module_api_delete:
path: /api/delete
defaults: { _controller: retailcrm.delivery_module.api_controller::delete }
methods: POST
retailcrm_delivery_module_api_shipment_point_list:
path: /api/shipment-point-list
defaults: { _controller: retailcrm.delivery_module.api_controller::shipmentPointList }
methods: GET
retailcrm_delivery_module_api_print:
path: /api/print
defaults: { _controller: retailcrm.delivery_module.api_controller::print }
methods: POST
retailcrm_delivery_module_api_shipment_save:
path: /api/shipment-save
defaults: { _controller: retailcrm.delivery_module.api_controller::shipmentSave }
methods: POST
retailcrm_delivery_module_api_shipment_delete:
path: /api/shipment-delete
defaults: { _controller: retailcrm.delivery_module.api_controller::shipmentDelete }
methods: POST

View File

@ -1,58 +0,0 @@
parameters:
retailcrm.delivery_module.api_controller: RetailCrm\DeliveryModuleBundle\Controller\ApiController
services:
_defaults:
public: false
autowire: true
autoconfigure: true
retailcrm.delivery_module.api_controller:
public: true
class: '%retailcrm.delivery_module.api_controller%'
RetailCrm\DeliveryModuleBundle\Service\RetailCrmClientFactoryInterface:
class: RetailCrm\DeliveryModuleBundle\Service\RetailCrmClientFactory
RetailCrm\DeliveryModuleBundle\Service\ModuleManagerInterface:
public: true
class: '%retailcrm.delivery_module.module_manager.class%'
arguments:
- '%retailcrm.delivery_module.configuration%'
- '@RetailCrm\DeliveryModuleBundle\Service\RetailCrmClientFactoryInterface'
- '@RetailCrm\DeliveryModuleBundle\Service\DeliveryOrderManager'
- '@jms_serializer'
- '@translator'
- '@router'
RetailCrm\DeliveryModuleBundle\Service\AccountManager:
class: 'RetailCrm\DeliveryModuleBundle\Service\AccountManager'
arguments:
- '%retailcrm.delivery_module.account.class%'
- '@doctrine.orm.entity_manager'
RetailCrm\DeliveryModuleBundle\Service\DeliveryOrderManager:
class: 'RetailCrm\DeliveryModuleBundle\Service\DeliveryOrderManager'
arguments:
- '%retailcrm.delivery_module.delivery_order.class%'
- '@doctrine.orm.entity_manager'
RetailCrm\DeliveryModuleBundle\Command\StatusesCommand:
class: RetailCrm\DeliveryModuleBundle\Command\StatusesCommand
tags: ['console.command']
RetailCrm\DeliveryModuleBundle\Command\UpdateModuleCommand:
class: RetailCrm\DeliveryModuleBundle\Command\UpdateModuleCommand
tags: ['console.command']
RetailCrm\DeliveryModuleBundle\Controller\:
resource: '../../Controller'
public: true
tags: ['controller.service_arguments']
RetailCrm\DeliveryModuleBundle\EventSubscriber\SerializeListener:
tags:
- { name: jms_serializer.event_subscriber }
RetailCrm\DeliveryModuleBundle\EventSubscriber\ClientIdSubscriber:
class: RetailCrm\DeliveryModuleBundle\EventSubscriber\ClientIdSubscriber

View File

@ -1,67 +0,0 @@
header:
configureConnection: Configuration of connection with system
additionalSettings: Additional settings
adminParcelEdit: 'Edit tracking %trackId%'
adminParcelCreate: Create tracking
listConnection: Current connection
listTracking: Current tracking
serviceConnect: 'Service connection %delivery%'
adminConnectionEdit: 'Edit connection data: %uid%'
adminConnectionCreate: New connection
button:
activate: Activate
save: Save
add: Add
listConnection: List of connections
listTracking: Parcel tracking
addTracking: Add tracking
updateConfiguration: Update the configuration
label:
crmUrl: System address
crmKey: System API key
debug: Debug mode
isActive: Integration is active
isFreeze: Integration is freeze
language: Language
account_number: Account number
token: API token
isInProduction: Use production server
id: ID
connection: ID connection
orderId: ID order
trackId: ID tracking
isClosed: Tracking completed
connectionId: Connection ID
select_value:
sender: Sender
receiver: Receiver
error:
connect.failed: Data to connect to %delivery% or System API key is entered incorrectly, try again.<br/><br/><a href="%href%">Re-enter data</a>
unknown_country: Unknown country
unknown_shipping_country: Unknown shipping country
shipping_country_required: Shipping country must not be empty
shipper_postal_code_required: Shipper postal code required
delivery_postal_code_required: Delivery postal code required
manager_phone_required: Manager`s phone required
dhl:
ready_time_required: Ready time required
dury_payment_type_for_receiver: Duty Payment Type cant be sender for payer type receiver
receiver_account_number_required: Receiver account number required
plate:
label: Label
day_short:
monday: Mon
tuesday: Tue
wednesday: Wed
thursday: Thu
friday: Fri
saturday: Sat
sunday: Sun
pagination.items.name: elements

View File

@ -1,67 +0,0 @@
header:
configureConnection: Configuración de la conexión del sistema
additionalSettings: Configuración avanzada
adminParcelEdit: 'Editar seguimiento %trackId%'
adminParcelCreate: Crear seguimiento
listConnection: Conexiones actuales
listTracking: Seguimiento actual
serviceConnect: 'Conexión de Servicio %delivery%'
adminConnectionEdit: 'Editar datos del cliente: %uid%'
adminConnectionCreate: Nueva conexión
button:
activate: Activar
save: Guardar
add: Añadir
listConnection: A la lista de conexiones
listTracking: Seguimiento de paquetes
addTracking: Añadir seguimiento
updateConfiguration: Actualizar configuración
label:
crmUrl: Dirección del Sistema
crmKey: Clave API del sistema
debug: Modo de depuración
isActive: Conexión activa
isFreeze: Conexión congelada
language: Idioma
account_number: Número de cuenta
token: token API
isInProduction: Utilizar servidor normal
id: ID
connection: ID de conexión
orderId: ID de pedido
trackId: ID de seguimiento
isClosed: Seguimiento completado
connectionId: Id de conexión
select_value:
sender: Remitente
receiver: Receptor
error:
connect.failed: Datos para conectarse a %delivery% o la clave API del sistema son incorrectos, intente de nuevo.<br/><br/><a href="%href%">Introducir datos de nuevo</a>
unknown_country: País desconocido
unknown_shipping_country: Páis de envio desconocido
shipping_country_required: Debe especificar el país de envío
shipper_postal_code_required: Debe especificar el código Postal del remitente
delivery_postal_code_required: Debe especificar el código Postal del destinatario
manager_phone_required: Debe especificar el Teléfono del mánager
dhl:
ready_time_required: Debe especificar la fecha del envío
dury_payment_type_for_receiver: El remitente no puede pagar los cargos adicionales si el que paga es el destinatario
receiver_account_number_required: Debe especificar el número de cuenta del destinatario
plate:
label: Etiqueta
day_short:
monday: Lu
tuesday: Ma
wednesday: Mie
thursday: Ju
friday: Vi
saturday: Sa
sunday: Do
pagination.items.name: elementos

View File

@ -1,67 +0,0 @@
header:
configureConnection: Настройка подключения к системе
additionalSettings: Дополнительные настройки
adminParcelEdit: 'Редактировать отслеживание %trackId%'
adminParcelCreate: Создать отслеживание
listConnection: Текущие подключения
listTracking: Текущие отслеживания
serviceConnect: 'Подключение сервиса %delivery%'
adminConnectionEdit: 'Редактировать данные клиента: %uid%'
adminConnectionCreate: Новое подключение
button:
activate: Активировать
save: Сохранить
add: Добавить
listConnection: К списку подключений
listTracking: Отслеживание посылок
addTracking: Добавить отслеживание
updateConfiguration: Обновить конфигурацию
label:
crmUrl: Адрес системы
crmKey: API ключ системы
debug: Режим отладки
isActive: Подключение активно
isFreeze: Подключение заморожено
language: Язык
account_number: Номер аккаунта
token: API токен
isInProduction: Использовать боевой сервер
id: ID
connection: ID подключения
orderId: ID заказа
trackId: ID отслеживания
isClosed: Отслеживание завершено
connectionId: Идентификатор подключения
select_value:
sender: Отправитель
receiver: Получатель
error:
connect.failed: Данные для подключения к %delivery% или API ключ системы введены неверно, попробуйте еще раз.<br/><br/><a href="%href%">Ввести данные заново</a>
unknown_country: Неизвестная страна
unknown_shipping_country: Неизвестная страна отправки
shipping_country_required: Необходимо указать страну отправки
shipper_postal_code_required: Необходимо указать почтовый индекс отправителя
delivery_postal_code_required: Необходимо указать почтовый индекс получателя
manager_phone_required: Необходимо указать телефон менеджера
dhl:
ready_time_required: Необходимо указать время отгрузки
dury_payment_type_for_receiver: Отправитель не может быть плательщиком за дополнительные сборы если тип плательщика получатель
receiver_account_number_required: Необходимо указать номер аккаунта получателя
plate:
label: Наклейка
day_short:
monday: Пн
tuesday: Вт
wednesday: Ср
thursday: Чт
friday: Пт
saturday: Сб
sunday: Вс
pagination.items.name: элементов

View File

@ -1,11 +0,0 @@
integration_module_access:
server_unreachable_exception: 'Failed to connect to the integration server'
module_access_exception: 'Invalid login or password'
retailcrm_access:
access_denied: 'Access to the method "%method%" is denied'
curl_exception: 'Failed to connect to API'
service_unavailable: 'Service is temporarily unavailable'
invalid_json: 'API returned a response in an unsupported format'
requires_https: 'API address must start with https'
wrong_api_key: 'Invalid API key'

View File

@ -1,11 +0,0 @@
integration_module_access:
server_unreachable_exception: 'No se ha podido conectar al servidor de integración'
module_access_exception: 'El Usuario o la contraseña no es correcta'
retailcrm_access:
access_denied: 'Acceso al método "%method%" está prohibido'
curl_exception: 'No se ha podido conectar al API'
service_unavailable: 'Servicio no está disponible temporalmente'
invalid_json: 'API ha devuelto la respuesta en el formato no soportado'
requires_https: 'Dirección del API tiene que comenzar con https'
wrong_api_key: 'El API-key no es correcto'

View File

@ -1,11 +0,0 @@
integration_module_access:
server_unreachable_exception: 'Не удалось подключиться к интеграционному серверу'
module_access_exception: 'Не верный логин или пароль'
retailcrm_access:
access_denied: 'Доступ к методу "%method%" запрещен'
curl_exception: 'Не удалось подключиться к API'
service_unavailable: 'Сервис временно недоступен'
invalid_json: 'API вернуло ответ в неподдерживаемом формате'
requires_https: 'Адрес API должен начинаться с https'
wrong_api_key: 'Неверный API-ключ'

View File

@ -1,55 +0,0 @@
<?php
namespace RetailCrm\DeliveryModuleBundle\Service;
use Doctrine\Persistence\ObjectManager;
use Doctrine\Persistence\ObjectRepository;
use RetailCrm\DeliveryModuleBundle\Model\Entity\Account;
class AccountManager
{
protected $class;
public function __construct(string $accountClass, ObjectManager $entityManager)
{
$this->class = $accountClass;
$this->entityManager = $entityManager;
}
public function getClass(): string
{
return $this->getRepository()->getClassName();
}
public function create(): Account
{
$class = $this->getClass();
return new $class();
}
public function find(string $id): ?Account
{
return $this->getRepository()->find($id);
}
public function findBy(array $criteria, array $orderBy = null, $limit = null, $offset = null): array
{
return $this->getRepository()->findBy($criteria, $orderBy, $limit, $offset);
}
public function findOneBy(array $criteria, array $orderBy = null): ?Account
{
return $this->getRepository()->findOneBy($criteria, $orderBy);
}
public function flush(): void
{
$this->entityManager->flush();
}
public function getRepository(): ObjectRepository
{
return $this->entityManager->getRepository($this->class);
}
}

View File

@ -1,65 +0,0 @@
<?php
namespace RetailCrm\DeliveryModuleBundle\Service;
use Doctrine\Persistence\ObjectManager;
use Doctrine\Persistence\ObjectRepository;
use RetailCrm\DeliveryModuleBundle\Model\Entity\DeliveryOrder;
class DeliveryOrderManager
{
protected $class;
public function __construct(string $deliveryOrderClass, ObjectManager $entityManager)
{
$this->class = $deliveryOrderClass;
$this->entityManager = $entityManager;
}
public function getClass(): string
{
return $this->class;
}
public function create(): DeliveryOrder
{
$class = $this->getClass();
return new $class();
}
public function find(int $id): ?DeliveryOrder
{
return $this->getRepository()->find($id);
}
public function findBy(array $criteria): array
{
return $this->getRepository()->findBy($criteria);
}
public function findOneBy(array $criteria): ?DeliveryOrder
{
return $this->getRepository()->findOneBy($criteria);
}
public function persist(object $entity): void
{
$this->entityManager->persist($entity);
}
public function remove(object $entity): void
{
$this->entityManager->remove($entity);
}
public function flush(): void
{
$this->entityManager->flush();
}
public function getRepository(): ObjectRepository
{
return $this->entityManager->getRepository($this->class);
}
}

View File

@ -1,355 +0,0 @@
<?php
namespace RetailCrm\DeliveryModuleBundle\Service;
use JMS\Serializer\SerializationContext;
use JMS\Serializer\SerializerInterface;
use Psr\Log\LoggerInterface;
use RetailCrm\ApiClient;
use RetailCrm\DeliveryModuleBundle\Exception\NotFoundException;
use RetailCrm\DeliveryModuleBundle\Model\Configuration;
use RetailCrm\DeliveryModuleBundle\Model\Entity\Account;
use RetailCrm\DeliveryModuleBundle\Model\Entity\DeliveryOrder;
use RetailCrm\DeliveryModuleBundle\Model\IntegrationModule;
use RetailCrm\DeliveryModuleBundle\Model\RequestCalculate;
use RetailCrm\DeliveryModuleBundle\Model\RequestDelete;
use RetailCrm\DeliveryModuleBundle\Model\RequestPrint;
use RetailCrm\DeliveryModuleBundle\Model\RequestSave;
use RetailCrm\DeliveryModuleBundle\Model\RequestShipmentDelete;
use RetailCrm\DeliveryModuleBundle\Model\RequestShipmentPointList;
use RetailCrm\DeliveryModuleBundle\Model\RequestShipmentSave;
use RetailCrm\DeliveryModuleBundle\Model\ResponseLoadDeliveryData;
use RetailCrm\DeliveryModuleBundle\Model\ResponseSave;
use RetailCrm\DeliveryModuleBundle\Model\ResponseShipmentSave;
use Symfony\Component\Routing\Generator\UrlGeneratorInterface;
use Symfony\Contracts\Translation\TranslatorInterface;
abstract class ModuleManager implements ModuleManagerInterface
{
/**
* @var string
*/
protected $integrationCode;
/**
* @var array
*/
protected $moduleParameters;
/**
* @var RetailCrmClientFactoryInterface
*/
protected $retailCrmClientFactory;
/**
* @var Account
*/
protected $account;
/**
* @var TranslatorInterface
*/
protected $translator;
/**
* @var DeliveryOrderManager
*/
protected $deliveryManager;
/**
* @var SerializerInterface
*/
protected $jmsSerializer;
/**
* @var UrlGeneratorInterface
*/
protected $router;
/**
* @var PinbaService
*/
protected $pinbaService;
/**
* @var ApiClient
*/
private $retailCrmClient;
/**
* @var LoggerInterface
*/
private $logger;
public function __construct(
array $moduleParameters,
RetailCrmClientFactoryInterface $retailCrmClientFactory,
DeliveryOrderManager $deliveryManager,
SerializerInterface $jmsSerializer,
TranslatorInterface $translator,
UrlGeneratorInterface $router
) {
$this->integrationCode = $moduleParameters['integration_code'];
$this->moduleParameters = $moduleParameters;
$this->retailCrmClientFactory = $retailCrmClientFactory;
$this->deliveryManager = $deliveryManager;
$this->jmsSerializer = $jmsSerializer;
$this->translator = $translator;
$this->router = $router;
$this->pinbaService = new PinbaService();
}
public function getAccountCode(): string
{
if (null === $this->account) {
throw new \LogicException('Account is not selected');
}
return sprintf('%s-%s', $this->integrationCode, $this->account->getId());
}
public function getAccount(): ?Account
{
return $this->account;
}
public function setAccount(Account $account): ModuleManagerInterface
{
$this->account = $account;
if ($this->account && $this->account->getLanguage() && $this->translator) {
$this->translator->setLocale($this->account->getLanguage());
}
$this->retailCrmClient = $this->retailCrmClientFactory->createRetailCrmClient($this->account);
return $this;
}
public function updateModuleConfiguration(): bool
{
if (null === $this->account) {
throw new \LogicException('Account is not selected');
}
$integrationModule = $this->buildIntegrationModule();
$integrationModule = $this->jmsSerializer
->serialize(
$integrationModule,
'json',
SerializationContext::create()->setGroups(['get', 'request'])->setSerializeNull(true)
);
$client = $this->retailCrmClient;
$response = $this->pinbaService->timerHandler(
[
'api' => 'retailCrm',
'method' => 'integrationModulesEdit',
],
static function () use ($client, $integrationModule) {
return $client->request->integrationModulesEdit(
json_decode($integrationModule, true)
);
}
);
if ($response['success'] ?? false) {
return true;
} else {
if ($this->logger) {
$errorMsg = $response['error_msg'] ?? '';
$this->logger->warning("Failed to update module configuration[account={$this->getAccount()->getCrmUrl()}]:{$errorMsg}");
}
return false;
}
}
protected function buildIntegrationModule(): IntegrationModule
{
$integrationModule = new IntegrationModule();
$integrationModule->code = $this->getAccountCode();
$integrationModule->integrationCode = $this->integrationCode;
$integrationModule->active = $this->account->isActive();
$integrationModule->name = $this->moduleParameters['locales'][$this->translator->getLocale()]['name'];
$integrationModule->logo = $this->moduleParameters['locales'][$this->translator->getLocale()]['logo'];
$integrationModule->clientId = $this->account->getClientId();
$integrationModule->availableCountries = $this->moduleParameters['countries'];
$integrationModule->actions = [
'activity' => 'activity',
];
$integrationModule->baseUrl = $this->router->generate(
'retailcrm_delivery_module_api_base',
[],
UrlGeneratorInterface::ABSOLUTE_URL
);
$integrationModule->accountUrl = $this->getAccountUrl();
$integrationModule->integrations = ['delivery' => $this->doBuildConfiguration()];
return $integrationModule;
}
abstract protected function doBuildConfiguration(): Configuration;
abstract protected function getAccountUrl(): string;
public function calculateDelivery(RequestCalculate $data): array
{
throw new \LogicException('Method should be implemented');
}
public function saveDelivery(RequestSave $data, DeliveryOrder $delivery = null): ResponseSave
{
throw new \LogicException('Method should be implemented');
}
public function getDelivery(string $externalId): ResponseLoadDeliveryData
{
throw new \LogicException('Method should be implemented');
}
public function deleteDelivery(RequestDelete $request, DeliveryOrder $delivery): bool
{
throw new \LogicException('Method should be implemented');
}
/**
* @return \RetailCrm\DeliveryModuleBundle\Model\Terminal[]
*/
public function shipmentPointList(RequestShipmentPointList $request): array
{
throw new \LogicException('Method should be implemented');
}
public function saveShipment(RequestShipmentSave $data): ResponseShipmentSave
{
throw new \LogicException('Method should be implemented');
}
public function deleteShipment(RequestShipmentDelete $request): bool
{
throw new \LogicException('Method should be implemented');
}
public function printDocument(RequestPrint $request)
{
$deliveries = $this->deliveryManager->findBy([
'account' => $this->account,
'externalId' => $request->deliveryIds,
]);
if (empty($deliveries)) {
throw new NotFoundException('Deliveries not found');
}
return $this->doPrint($request->type, $deliveries);
}
protected function doPrint(string $documentType, array $deliveries): array
{
throw new \LogicException('Method should be implemented');
}
public function updateStatuses(): int
{
if (null === $this->account) {
throw new \LogicException('Account is not selected');
}
$deliveryQuery = $this->deliveryManager->createQueryBuilder('delivery')
->select('delivery')
->andWhere('delivery.account = :account')
->andWhere('delivery.id >= :lastId')
->andWhere('delivery.ended = FALSE')
->orderBy('delivery.id ASC')
->createQuery()
->setMaxResults(static::STATUS_UPDATE_LIMIT)
->setAccount($this->account)
;
$count = 0;
$lastId = 0;
while (true) {
$deliveryQuery->setParameter('lastId', $lastId);
$deliveries = $deliveryQuery->getResult();
if (empty($deliveries)) {
break;
}
foreach ($deliveries as $delivery) {
if ($delivery->getId() > $lastId) {
$lastId = $delivery->getId();
}
}
$deliveriesHistory = $this->doUpdateStatuses($deliveries);
if (!empty($deliveriesHistory)) {
$this->updateRetailCrmOrderStatuses($deliveriesHistory);
}
$count += count($deliveriesHistory);
$this->deliveryManager->flush();
}
return $count;
}
public function getRetailCrmClient(): ApiClient
{
if (null === $this->retailCrmClient) {
throw new \LogicException('Account is not selected');
}
return $this->retailCrmClient;
}
/**
* Получение актуальных статусов доставки от службы доставки.
*
* @param \RetailCrm\DeliveryModuleBundle\Entity\Parcel[] $deliveries
*
* @return \RetailCrm\DeliveryModuleBundle\Model\RequestStatusUpdateItem[]
*/
protected function doUpdateStatuses(array $deliveries): array
{
throw new \LogicException('Method should be implemented');
}
/**
* Обновление статусов в CRM.
*
* @param \RetailCrm\DeliveryModuleBundle\Model\RequestStatusUpdateItem[] $deliveriesHistory
*
* @throws \Exception
*/
protected function updateRetailCrmOrderStatuses(array $deliveriesHistory): void
{
if (count($deliveriesHistory) > 100) {
$parts = array_chunk($deliveriesHistory, 100);
} else {
$parts = [$deliveriesHistory];
}
foreach ($parts as $part) {
$request = $this->jmsSerializer
->serialize($part, 'json', SerializationContext::create()->setGroups(['get', 'request']));
$client = $this->retailCrmClient;
$moduleCode = $this->getAccountCode();
$response = $this->pinbaService->timerHandler(
[
'api' => 'retailCrm',
'method' => 'deliveryTracking',
],
static function () use ($client, $moduleCode, $request) {
return $client->request->deliveryTracking(
$moduleCode,
json_decode($request, true)
);
}
);
}
}
}

View File

@ -1,52 +0,0 @@
<?php
namespace RetailCrm\DeliveryModuleBundle\Service;
use RetailCrm\ApiClient;
use RetailCrm\DeliveryModuleBundle\Model\Entity\Account;
use RetailCrm\DeliveryModuleBundle\Model\Entity\DeliveryOrder;
use RetailCrm\DeliveryModuleBundle\Model\RequestCalculate;
use RetailCrm\DeliveryModuleBundle\Model\RequestDelete;
use RetailCrm\DeliveryModuleBundle\Model\RequestPrint;
use RetailCrm\DeliveryModuleBundle\Model\RequestSave;
use RetailCrm\DeliveryModuleBundle\Model\RequestShipmentDelete;
use RetailCrm\DeliveryModuleBundle\Model\RequestShipmentPointList;
use RetailCrm\DeliveryModuleBundle\Model\RequestShipmentSave;
use RetailCrm\DeliveryModuleBundle\Model\ResponseSave;
use RetailCrm\DeliveryModuleBundle\Model\ResponseShipmentSave;
interface ModuleManagerInterface
{
const STATUS_UPDATE_LIMIT = 100;
public function getAccountCode(): string;
public function getAccount(): ?Account;
public function setAccount(Account $account): self;
public function checkAccess(): bool;
public function updateModuleConfiguration(): bool;
public function calculateDelivery(RequestCalculate $data): array;
public function saveDelivery(RequestSave $data, DeliveryOrder $delivery = null): ResponseSave;
public function deleteDelivery(RequestDelete $request, DeliveryOrder $delivery): bool;
/**
* @return \RetailCrm\DeliveryModuleBundle\Model\Terminal[]
*/
public function shipmentPointList(RequestShipmentPointList $request): array;
public function saveShipment(RequestShipmentSave $data): ResponseShipmentSave;
public function deleteShipment(RequestShipmentDelete $request): bool;
public function printDocument(RequestPrint $request);
public function updateStatuses(): int;
public function getRetailCrmClient(): ApiClient;
}

View File

@ -1,22 +0,0 @@
<?php
namespace RetailCrm\DeliveryModuleBundle\Service;
class PinbaService
{
/**
* @return mixed
*/
public function timerHandler(array $tags, \Closure $handler)
{
if (function_exists('pinba_timer_start')) {
$timer = pinba_timer_start($tags);
$response = $handler();
pinba_timer_stop($timer);
} else {
$response = $handler();
}
return $response;
}
}

View File

@ -1,36 +0,0 @@
<?php
namespace RetailCrm\DeliveryModuleBundle\Service;
use Psr\Log\LoggerInterface;
use RetailCrm\ApiClient;
use RetailCrm\DeliveryModuleBundle\Model\Entity\Account;
class RetailCrmClientFactory implements RetailCrmClientFactoryInterface
{
public function createRetailCrmClient(Account $account, ?LoggerInterface $logger = null): ApiClient
{
if (null === $account) {
throw new \LogicException('Account is not selected');
}
if (empty($account->getCrmUrl())) {
throw new \LogicException('Crm url is empty');
}
if (empty($account->getCrmApiKey())) {
throw new \LogicException('Crm apiKey is empty');
}
$retailCrmClient = new ApiClient(
$account->getCrmUrl(),
$account->getCrmApiKey(),
ApiClient::V5
);
if ($logger) {
$retailCrmClient->setLogger($logger);
}
return $retailCrmClient;
}
}

View File

@ -1,12 +0,0 @@
<?php
namespace RetailCrm\DeliveryModuleBundle\Service;
use Psr\Log\LoggerInterface;
use RetailCrm\ApiClient;
use RetailCrm\DeliveryModuleBundle\Model\Entity\Account;
interface RetailCrmClientFactoryInterface
{
public function createRetailCrmClient(Account $account, ?LoggerInterface $logger = null): ApiClient;
}

View File

@ -1,44 +0,0 @@
<?php
namespace RetailCrm\DeliveryModuleBundle\Validator\Constraints;
use RetailCrm\DeliveryModuleBundle\Exception\AbstractModuleException;
use RetailCrm\DeliveryModuleBundle\Exception\ServerUnreachableException;
use RetailCrm\DeliveryModuleBundle\Service\ModuleManagerInterface;
use Symfony\Component\Validator\Constraint;
use Symfony\Component\Validator\ConstraintValidator;
use Symfony\Component\Validator\Exception\UnexpectedTypeException;
class IntegrationModuleAccessValidator extends ConstraintValidator
{
/** @var ModuleManagerInterface */
private $moduleManager;
public function __construct(ModuleManagerInterface $moduleManager)
{
$this->moduleManager = $moduleManager;
}
public function validate($account, Constraint $constraint)
{
if (!($constraint instanceof IntegrationModuleAccess)) {
throw new UnexpectedTypeException($constraint, IntegrationModuleAccess::class);
}
try {
$this->moduleManager->checkAccess();
} catch (ServerUnreachableException $e) {
$this->context
->buildViolation('integration_module_access.server_unreachable_exception')
->atPath($constraint->path)
->addViolation()
;
} catch (AbstractModuleException $e) {
$this->context
->buildViolation('integration_module_access.module_access_exception')
->atPath($constraint->path)
->addViolation()
;
}
}
}

View File

@ -1,23 +0,0 @@
<?php
namespace App\Validator\Constraints;
use Symfony\Component\Validator\Constraint;
/**
* @Annotation
* @Target({"CLASS"})
*/
class RetailCrmAccess extends Constraint
{
/** @var array */
public $requiredApiMethods = [];
/**
* {@inheritdoc}
*/
public function getTargets()
{
return self::CLASS_CONSTRAINT;
}
}

View File

@ -1,80 +0,0 @@
<?php
namespace App\Validator\Constraints;
use RetailCrm\DeliveryModuleBundle\Exception\RetailCrmApiException;
use RetailCrm\DeliveryModuleBundle\Service\ModuleManagerInterface;
use RetailCrm\Exception\CurlException;
use RetailCrm\Exception\InvalidJsonException;
use RetailCrm\Exception\LimitException;
use Symfony\Component\Validator\Constraint;
use Symfony\Component\Validator\ConstraintValidator;
use Symfony\Component\Validator\Exception\UnexpectedTypeException;
class RetailCrmAccessValidator extends ConstraintValidator
{
/** @var ModuleManagerInterface */
private $moduleManager;
public function __construct(ModuleManagerInterface $moduleManager)
{
$this->moduleManager = $moduleManager;
}
public function validate($account, Constraint $constraint)
{
if (!($constraint instanceof RetailCrmAccess)) {
throw new UnexpectedTypeException($constraint, RetailCrmAccess::class);
}
$client = $this->moduleManager->getRetailCrmClient();
try {
$response = $client->request->credentials();
if (!$response->isSuccessful()) {
throw new RetailCrmApiException($response->offsetGet('errorMsg'));
}
$credentials = $response->offsetGet('credentials');
foreach ($constraint->requiredApiMethods as $method) {
if (!in_array($method, $credentials)) {
$this->context
->buildViolation('retailcrm_access.access_denied', ['%method%' => $method])
->atPath('crmApiKey')
->addViolation()
;
}
}
} catch (CurlException $e) {
$this->context
->buildViolation('retailcrm_access.curl_exception')
->atPath('crmUrl')
->addViolation()
;
} catch (LimitException $e) {
$this->context
->buildViolation('retailcrm_access.service_unavailable')
->atPath('crmUrl')
->addViolation()
;
} catch (InvalidJsonException $e) {
$this->context
->buildViolation('retailcrm_access.invalid_json')
->atPath('crmUrl')
->addViolation()
;
} catch (\InvalidArgumentException $e) {
$this->context
->buildViolation('retailcrm_access.requires_https')
->atPath('crmUrl')
->addViolation()
;
} catch (RetailCrmApiException $e) {
$this->context
->buildViolation('retailcrm_access.wrong_api_key')
->atPath('crmUrl')
->addViolation()
;
}
}
}

View File

@ -1,34 +1,49 @@
{
"name": "retailcrm/delivery-module-bundle",
"description": "Delivery module skeleton for RetailCrm",
"license": "MIT",
"type": "symfony-bundle",
"autoload": {
"psr-4": {
"RetailCrm\\DeliveryModuleBundle\\": ""
"description": "Delivery module skeleton for RetailCRM",
"license": "MIT",
"authors": [
{
"name": "RetailCRM",
"email": "support@retailcrm.ru"
}
},
"config": {
"sort-packages": true
},
],
"require": {
"php": "^7.3",
"ext-json": "*",
"ext-zip": "*",
"doctrine/orm": "^2.7",
"jms/serializer": "^3.4",
"jms/serializer-bundle": "^3.5",
"ramsey/uuid": "^3.9",
"ramsey/uuid-doctrine": "^1.5",
"retailcrm/api-client-php": "^5.0.0",
"symfony/framework-bundle": "^3.4|^4.0|^5.1",
"guzzlehttp/guzzle": "^7.0",
"psr/log": "^1.1",
"symfony/framework-bundle": "^5.1",
"symfony/lock": "^5.1",
"symfony/polyfill-uuid": "^1.20",
"symfony/routing": "^5.1",
"symfony/serializer": "^5.1",
"symfony/translation": "^5.1",
"symfony/validator": "^5.1"
},
"require-dev": {
"doctrine/doctrine-fixtures-bundle": "^3.3",
"friendsofphp/php-cs-fixer": "^2.0"
"doctrine/orm": "^2.7",
"friendsofphp/php-cs-fixer": "^2.0",
"phpunit/phpunit": "^9.4",
"vimeo/psalm": "^4.1"
},
"autoload": {
"psr-4": {
"RetailCrm\\DeliveryModuleBundle\\": "src"
}
},
"autoload-dev": {
"psr-4": {
"RetailCrm\\DeliveryModuleBundle\\Tests\\": "tests/"
}
},
"scripts": {
"test": "vendor/bin/phpunit",
"test-ci": "vendor/bin/phpunit --coverage-text --coverage-clover=build/coverage.xml"
},
"config": {
"sort-packages": true
}
}

284
doc/index.md Normal file
View File

@ -0,0 +1,284 @@
Getting started with RetailCrmDeliveryModuleBundle
==================================================
## Prerequisites
This version of the bundle requires Symfony 5.1.
#### Translations
If you wish to use default texts provided in this bundle, you have to make sure you have translator enabled in your config:
``` yaml
# config/packages/translation.yaml
framework:
translator: { fallback: en }
```
For more information about translations, check [Symfony documentation](http://symfony.com/doc/current/book/translation.html).
## Installation
Installation is a 7 steps process:
1. Download RetailCrmDeliveryModuleBundle
2. Enable the Bundle
3. Create your model class
4. Create your integration module factory
5. Create your delivery service
6. Create your tracker
7. Configure the RetailCrmDeliveryModuleBundle
### Step 1: Install RetailCrmDeliveryModuleBundle
The preferred way to install this bundle is to rely on [Composer](http://getcomposer.org).
Just check on [Packagist](http://packagist.org/packages/retailcrm/delivery-module-bundle) the version you want to install (in the following example, we used "dev-master") and add it to your `composer.json`:
``` json
{
"require": {
// ...
"retailcrm/delivery-module-bundle": "dev-master"
}
}
```
### Step 2: Enable the bundle
Finally, enable the bundle in the kernel:
``` php
<?php
// config/bundles.php
return [
// ...
RetailCrm\DeliveryModuleBundle\RetailCrmDeliveryModuleBundle::class => ['all' => true],
];
```
### Step 3: Create model classes
This bundle needs to persist some classes to a database:
- `Account`
- `Delivery`
Your first job, then, is to create these classes for your application.
These classes can look and act however you want: add any properties or methods you find useful.
These classes have just a few requirements:
1. They must extend one of the base classes from the bundle
2. They must have an `id` field
In the following sections, you'll see examples of how your classes should
look, depending on how you're storing your data.
Your classes can live inside any bundle in your application.
**Warning:**
> If you override the __construct() method in your classes, be sure to call parent::__construct(), as the base class depends on this to initialize some fields.
#### Doctrine ORM classes
If you're persisting your data via the Doctrine ORM, then your classes should live in the `Entity` namespace of your bundle and look like this to start:
``` php
<?php
// src/App/Entity/Account.php
namespace App\Entity;
use RetailCrm\DeliveryModuleBundle\Entity\Account as BaseAccount;
use Doctrine\ORM\Mapping as ORM;
/**
* @ORM\Entity
*/
class Account extends BaseAccount
{
/**
* @ORM\Id
* @ORM\Column(type="integer")
* @ORM\GeneratedValue(strategy="AUTO")
*/
protected $id;
public function __construct()
{
parent::__construct();
// your own logic
}
}
```
``` php
<?php
// src/App/Entity/Delivery.php
namespace Acme\ApiBundle\Entity;
use RetailCrm\DeliveryModuleBundle\Entity\Delivery as BaseDelivery;
use Doctrine\ORM\Mapping as ORM;
/**
* @ORM\Entity
*/
class Delivery extends BaseDelivery
{
/**
* @ORM\Id
* @ORM\Column(type="integer")
* @ORM\GeneratedValue(strategy="AUTO")
*/
protected $id;
/**
* @ORM\ManyToOne(targetEntity="Account")
* @ORM\JoinColumn(nullable=false, onDelete="CASCADE")
*/
protected $account;
}
```
__Note__: If you don't have `auto_mapping` activated in your doctrine configuration you need to add `RetailCrmDeliveryModuleBundle` to your mappings in `config/packages/doctrine.yaml`.
### Custom database driver
The bundle provides driver for Doctrine ORM.
Though sometimes you might want to use the bundle with a custom or in-house written storage.
For that, the bundle has support for custom storage.
Once set, setting `manager` options in `retail_crm_delivery_module.service` section becomes mandatory.
### Step 4: Create your integration module factory
The IntegrationModuleFactory class responsibility is to build integration module configuration for RetailCRM.
A custom integration module factory needs to implement `RetailCrn\DeliveryModuleBundle\Integration\Crm\IntegrationModuleFactoryInterface` or extend `RetailCrn\DeliveryModuleBundle\Integration\Crm\AbstractIntegrationModuleFactory`, which makes creating an integration module factory even easier:
``` php
# src/Integration/Crm/CustomIntegrationModuleFactory.php
use RetailCrm\DeliveryModuleBundle\Integration\Crm\AbstractIntegrationModuleFactory;
use RetailCrm\DeliveryModuleBundle\Model\Account;
use Symfony\Component\Routing\Generator\UrlGeneratorInterface;
class CustomIntegrationModuleFactory extends AbstractIntegrationModuleFactory
{
/** @var UrlGeneratorInterface */
private $urlGenerator;
public function __construct(UrlGeneratorInterface $urlGenerator, array $configuration)
{
$this->urlGenerator = $urlGenerator;
parent::__construct($configuration);
}
protected function getBaseUrl(): string
{
return $this->urlGenerator->generate('base_url', [], UrlGeneratorInterface::ABSOLUTE_URL);
}
protected function getAccountUrl(): string
{
return $this->urlGenerator->generate('account_url', [], UrlGeneratorInterface::ABSOLUTE_URL);
}
protected function getDeliveryConfiguration(Account $account): array
{
$configuration = [];
$configuration['description'] = sprintf("Account %s[%s] configuration", $account->getUrl(), $account->getClientId());
$configuration['actions'] = [
'calculate' => 'delivery/calculate',
'save' => 'delivery/save',
'get' => 'delivery/get',
'delete' => 'delivery/delete',
'shipmentPointList' => 'delivery/shipment-point-list',
'shipmentSave' => 'delivery/shipment-save',
'shipmentDelete' => 'delivery/shipment-delete',
'tariffList' => 'delivery/tariff-list',
'print' => 'delivery/print',
];
$configuration['payerType'] = [
'receiver',
'sender',
];
// TODO: add your logic
return $configuration;
}
}
```
### Step 5: Create your delivery service
The DeliveryService class responsibility is to provide a gateway for delivery API.
Custom delivery service must implement:
- `RetailCrm\DeliveryModuleBundle\DeliveryService\ProcessableDeliveryServiceInterface` if delivery provides create/delete processing
- `RetailCrm\DeliveryModuleBundle\DeliveryService\TrackableDeliveryServiceInterface` if delivery provides tracking service
### Step 6: Create your tracker
The Tracker class responsibility is to provide a tracking service.
You can use default tracker `retail_crm_delivery_module.tracker.default` or crete your custom.
Tracker is class must implement the `RetailCrm\DeliveryModuleBundle\Tracking\TrackerInterface`.
This interface defines one method called `tracking` to perform delivery tracking.
### Step 7: Configure RetailCrmDeliveryModuleBundle
Import the routing configuration file in `config/routes.yaml`:
``` yaml
# config/routes.yaml
retail_crm_delivery_module_callback_delivery:
resource: "@RetailCrmDeliveryModuleBundle/Resources/config/routing/delivery_callback.xml"
retail_crm_delivery_module_callback_integration_module:
resource: "@RetailCrmDeliveryModuleBundle/Resources/config/routing/integration_module_callback.xml"
```
Add RetailCrmDeliveryModuleBundle settings in `config/packages/retail_crm_delivery_module.yaml`:
``` yaml
# config/packages/retail_crm_delivery_module.yaml
retail_crm_delivery_module:
db_driver: orm # Drivers available: orm or custom
model:
account_class: App\Entity\Account
delivery_class: App\Entity\Delivery
service:
manager:
account: retail_crm_delivery_module.manager.account.default # Or your custom
delivery: retail_crm_delivery_module.manager.delivery.default # Or your custom
integration_module_factory: App\IntegrationModule\CustomIntegrationModuleFactory
delivery_service: App\DeliveryService\CustomDeliveryService
tracker: retail_crm_delivery_module.tracker.default # Or your custom
```
Update your database schema
Now the bundle is configured, the last thing you need to do is update your database schema because you have added a new entity.
For ORM run the following command.
$ php bin/console doctrine:schema:update --force

36
phpunit.xml Normal file
View File

@ -0,0 +1,36 @@
<?xml version="1.0" encoding="UTF-8"?>
<!-- https://phpunit.de/manual/current/en/appendixes.configuration.html -->
<phpunit xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:noNamespaceSchemaLocation="http://schema.phpunit.de/6.5/phpunit.xsd"
backupGlobals="false"
colors="false"
bootstrap="vendor/autoload.php"
backupStaticAttributes="false"
convertErrorsToExceptions="false"
convertNoticesToExceptions="false"
convertWarningsToExceptions="false"
processIsolation="true"
stopOnError="false"
stopOnFailure="false"
stopOnIncomplete="false"
stopOnSkipped="false"
stopOnRisky="false"
>
<testsuites>
<testsuite name="Project Test Suite">
<directory>tests</directory>
</testsuite>
</testsuites>
<filter>
<whitelist>
<directory>src</directory>
</whitelist>
</filter>
<logging>
<log type="coverage-clover" target="clover.xml"/>
<log type="junit" target="/tmp/logfile.xml"/>
</logging>
</phpunit>

15
psalm.xml Normal file
View File

@ -0,0 +1,15 @@
<?xml version="1.0" encoding="UTF-8"?>
<psalm
errorLevel="8"
resolveFromConfigFile="true"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xmlns="https://getpsalm.org/schema/config"
xsi:schemaLocation="https://getpsalm.org/schema/config vendor/vimeo/psalm/config.xsd"
>
<projectFiles>
<directory name="src" />
<ignoreFiles>
<directory name="vendor" />
</ignoreFiles>
</projectFiles>
</psalm>

View File

@ -0,0 +1,108 @@
<?php
namespace RetailCrm\DeliveryModuleBundle\Command;
use RetailCrm\DeliveryModuleBundle\Model\Account;
use RetailCrm\DeliveryModuleBundle\Model\AccountManagerInterface;
use RetailCrm\DeliveryModuleBundle\Tracking\TrackerInterface;
use Symfony\Component\Console\Command\Command;
use Symfony\Component\Console\Command\LockableTrait;
use Symfony\Component\Console\Input\InputArgument;
use Symfony\Component\Console\Input\InputInterface;
use Symfony\Component\Console\Output\OutputInterface;
class TrackingCommand extends Command
{
use LockableTrait;
protected static $defaultName = 'delivery:tracking';
/** @var AccountManagerInterface */
private $accountManager;
/** @var TrackerInterface|null */
private $tracker;
public function __construct(
AccountManagerInterface $accountManager,
TrackerInterface $tracker,
string $name = null
) {
$this->accountManager = $accountManager;
$this->tracker = $tracker;
parent::__construct($name);
}
/**
* {@inheritdoc}
*/
protected function configure(): void
{
$this
->setDescription('Delivery tracking')
->addArgument('accountId', InputArgument::OPTIONAL, 'Choose account, or make it for all')
;
}
/**
* {@inheritdoc}
*/
protected function execute(InputInterface $input, OutputInterface $output)
{
if (!$this->lock()) {
$output->writeln('The command is already running in another process.');
return 1;
}
$startTime = new \DateTime();
$accountId = $input->hasArgument('accountId')
? (int) $input->getArgument('accountId')
: null
;
$successfulCount = $failureCount = 0;
$accounts = $this->getActiveAccounts($accountId);
/** @var Account $account */
foreach ($accounts as $account) {
try {
$this->tracker->tracking($account);
++$successfulCount;
} catch (\Exception $e) {
$output->writeln("<error>Failed to update statuses for account {$account->getCrmUrl()}[{$account->getClientId()}]</error>");
$output->writeln("<error>Error: {$e->getMessage()}</error>");
++$failureCount;
}
}
$this->release();
$output->writeln(sprintf('<info>Accounts updated successful = %s</info>', $successfulCount));
$output->writeln(sprintf('<info>Accounts failed updates = %s</info>', $failureCount));
$output->writeln(sprintf('<info>Memory = %s</info>', memory_get_peak_usage()));
$output->writeln(sprintf('<info>Time of execution = %s</info>', $startTime->diff(new \DateTime())->format('%I:%S')));
return 0;
}
protected function getActiveAccounts(int $accountId = null): \Generator
{
if (null !== $accountId) {
$account = $this->accountManager->findActiveAccountById($accountId);
if (null !== $account) {
yield $account;
} else {
yield from [];
}
} else {
return $this->accountManager->findActiveAccounts();
}
}
}

Some files were not shown because too many files have changed in this diff Show More