init
This commit is contained in:
commit
edca706fa6
72 changed files with 9744 additions and 0 deletions
2
.gitignore
vendored
Normal file
2
.gitignore
vendored
Normal file
|
@ -0,0 +1,2 @@
|
|||
/*.sublime*
|
||||
/vendor
|
90
Command/StatusesCommand.php
Normal file
90
Command/StatusesCommand.php
Normal file
|
@ -0,0 +1,90 @@
|
|||
<?php
|
||||
|
||||
namespace RetailCrm\DeliveryModuleBundle;
|
||||
|
||||
use Doctrine\ORM\Tools\Pagination\Paginator;
|
||||
use RetailCrm\DeliveryModuleBundle\Entity\Account;
|
||||
use RetailCrm\DeliveryModuleBundle\Service\ModuleManager;
|
||||
use Symfony\Bundle\FrameworkBundle\Command\ContainerAwareCommand;
|
||||
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 ContainerAwareCommand
|
||||
{
|
||||
use LockableTrait;
|
||||
|
||||
private $em;
|
||||
private $moduleManager;
|
||||
|
||||
/**
|
||||
* {@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(EntityManagerInterface $em, ModuleManager $moduleManager)
|
||||
{
|
||||
$this->em = $em;
|
||||
$this->moduleManager = $moduleManager;
|
||||
|
||||
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->em->getRepository($this->getConnectionClass())->find($accountId)];
|
||||
} else {
|
||||
$accountQuery = $this->em->createQuery('
|
||||
SELECT account
|
||||
FROM ' . Account::class . ' account
|
||||
WHERE
|
||||
account.isActive = true
|
||||
AND account.isFreeze != true
|
||||
')
|
||||
->setFirstResult(0)
|
||||
->setMaxResults(100);
|
||||
$paginator = new Paginator($accountQuery);
|
||||
}
|
||||
|
||||
$count = 0;
|
||||
foreach ($paginator as $account) {
|
||||
try {
|
||||
$count += $this->moduleManager
|
||||
->setAccount($account)
|
||||
->updateStatuses()
|
||||
;
|
||||
} catch (\Exception $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();
|
||||
}
|
||||
}
|
91
Command/UpdateModuleConfigurationCommand.php
Normal file
91
Command/UpdateModuleConfigurationCommand.php
Normal file
|
@ -0,0 +1,91 @@
|
|||
<?php
|
||||
|
||||
namespace RetailCrm\DeliveryModuleBundle;
|
||||
|
||||
use Doctrine\ORM\Tools\Pagination\Paginator;
|
||||
use RetailCrm\DeliveryModuleBundle\Entity\Account;
|
||||
use RetailCrm\DeliveryModuleBundle\Service\ModuleManager;
|
||||
use Symfony\Bundle\FrameworkBundle\Command\ContainerAwareCommand;
|
||||
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 UpdateModuleConfigurationCommand extends ContainerAwareCommand
|
||||
{
|
||||
use LockableTrait;
|
||||
|
||||
private $em;
|
||||
private $manager;
|
||||
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*/
|
||||
protected function configure()
|
||||
{
|
||||
$this
|
||||
->setName('configuration:update')
|
||||
->setDescription('Update module configuration')
|
||||
->addArgument('accountId', InputArgument::OPTIONAL, 'Choose account, or make it for all');
|
||||
}
|
||||
|
||||
public function __construct(EntityManagerInterface $em, ModuleManager $manager)
|
||||
{
|
||||
$this->em = $em;
|
||||
$this->manager = $manager;
|
||||
|
||||
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->em->getRepository($this->getConnectionClass())->find($accountId)];
|
||||
} else {
|
||||
$accountQuery = $this->em->createQuery('
|
||||
SELECT account
|
||||
FROM ' . Account::class . ' account
|
||||
WHERE
|
||||
account.isActive = true
|
||||
AND account.isFreeze != true
|
||||
')
|
||||
->setFirstResult(0)
|
||||
->setMaxResults(100);
|
||||
$paginator = new Paginator($accountQuery);
|
||||
}
|
||||
|
||||
$count = 0;
|
||||
foreach ($paginator as $account) {
|
||||
try {
|
||||
$this->manager
|
||||
->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();
|
||||
}
|
||||
}
|
414
Controller/AdminController.php
Normal file
414
Controller/AdminController.php
Normal file
|
@ -0,0 +1,414 @@
|
|||
<?php
|
||||
|
||||
namespace Intaro\DeliveryModuleBundle;
|
||||
|
||||
use Doctrine\Common\Persistence\ObjectManager;
|
||||
use Knp\Component\Pager\PaginatorInterface;
|
||||
use RetailCrm\DeliveryModuleBundle\Entity\Connection;
|
||||
use RetailCrm\DeliveryModuleBundle\Service;
|
||||
use RetailCrm\DeliveryModuleBundle\Service\BaseDelivery;
|
||||
use Symfony\Bundle\FrameworkBundle\Controller\Controller;
|
||||
use Symfony\Component\HttpFoundation\Request;
|
||||
use Symfony\Component\HttpFoundation\Response;
|
||||
use Symfony\Component\HttpFoundation\Session\Flash\FlashBagInterface;
|
||||
|
||||
abstract class AdminController extends Controller
|
||||
{
|
||||
/**
|
||||
* Базовый роут
|
||||
*
|
||||
* @return string
|
||||
*/
|
||||
abstract protected function getRoute();
|
||||
|
||||
/**
|
||||
* Сервис для работы с апи службы доставки
|
||||
*
|
||||
* @return BaseDelivery
|
||||
*/
|
||||
abstract protected function getDeliveryApi();
|
||||
|
||||
/**
|
||||
* @var ObjectManager
|
||||
*/
|
||||
protected $entityManager;
|
||||
|
||||
/**
|
||||
* @var PaginatorInterface
|
||||
*/
|
||||
protected $knpPaginator;
|
||||
|
||||
/**
|
||||
* @var Service\OpenSsl
|
||||
*/
|
||||
protected $openSsl;
|
||||
|
||||
/**
|
||||
* @var FlashBagInterface
|
||||
*/
|
||||
protected $flashBag;
|
||||
|
||||
/**
|
||||
* AdminController constructor.
|
||||
*
|
||||
* @param ObjectManager $entityManager
|
||||
* @param PaginatorInterface $knpPaginator
|
||||
* @param Service\OpenSsl $openSsl
|
||||
* @param FlashBagInterface $flashBag
|
||||
*/
|
||||
public function __construct(
|
||||
ObjectManager $entityManager,
|
||||
PaginatorInterface $knpPaginator,
|
||||
Service\OpenSsl $openSsl,
|
||||
FlashBagInterface $flashBag
|
||||
) {
|
||||
$this->entityManager = $entityManager;
|
||||
$this->knpPaginator = $knpPaginator;
|
||||
$this->openSsl = $openSsl;
|
||||
$this->flashBag = $flashBag;
|
||||
}
|
||||
|
||||
/**
|
||||
* @return string
|
||||
*/
|
||||
private function getShortBundle()
|
||||
{
|
||||
return strtr('Intaro\DeliveryModuleBundle', ['\\' => '']);
|
||||
}
|
||||
|
||||
/**
|
||||
* @return string
|
||||
*/
|
||||
private function getNameService()
|
||||
{
|
||||
$bundle = explode('\\', 'Intaro\DeliveryModuleBundle');
|
||||
|
||||
return strtr(end($bundle), ['Bundle' => '']);
|
||||
}
|
||||
|
||||
/**
|
||||
* @param Request $request
|
||||
*
|
||||
* @return Response
|
||||
*/
|
||||
public function listAction(Request $request)
|
||||
{
|
||||
$clientsQuery = $this->entityManager->createQuery('
|
||||
SELECT connection
|
||||
FROM ' . $this->getConnectionClass() . ' connection
|
||||
');
|
||||
|
||||
$pagination = $this->knpPaginator->paginate(
|
||||
$clientsQuery,
|
||||
$request->query->getInt('page', 1),
|
||||
20
|
||||
);
|
||||
|
||||
return $this->render(
|
||||
$this->getShortBundle() . ':Connection:list.html.twig',
|
||||
['pagination' => $pagination, 'route' => $this->getRoute()]
|
||||
);
|
||||
}
|
||||
|
||||
/**
|
||||
* @param Request $request
|
||||
*
|
||||
* @return Response
|
||||
*/
|
||||
public function newAction(Request $request)
|
||||
{
|
||||
$this->denyAccessUnlessGranted('ROLE_DEVELOPER');
|
||||
|
||||
$connectionClass = $this->getConnectionClass();
|
||||
$connection = new $connectionClass();
|
||||
$connection->setEncoder($this->openSsl);
|
||||
$connectionTypeClass = 'Intaro\DeliveryModuleBundle\Form\ConnectionType';
|
||||
$form = $this->createForm($connectionTypeClass, $connection, [
|
||||
'container' => $this->container,
|
||||
'is_admin' => true,
|
||||
]);
|
||||
$form->handleRequest($request);
|
||||
|
||||
if ($form->isSubmitted() && $form->isValid()) {
|
||||
$connection->generateClientId();
|
||||
$this->actualizeWebhooks($connection);
|
||||
$this->entityManager->persist($connection);
|
||||
$this->entityManager->flush();
|
||||
|
||||
return $this->redirectToRoute($this->getRoute() . '_admin_edit', [
|
||||
'connectionId' => $connection->getId(),
|
||||
]);
|
||||
}
|
||||
|
||||
return $this->render(
|
||||
$this->getShortBundle() . ':Connection:edit.html.twig',
|
||||
['route' => $this->getRoute(), 'form' => $form->createView()]
|
||||
);
|
||||
}
|
||||
|
||||
/**
|
||||
* @param Request $request
|
||||
* @param string $connectionId
|
||||
*
|
||||
* @return Response
|
||||
*/
|
||||
public function editAction(Request $request, $connectionId)
|
||||
{
|
||||
$connection = $this->entityManager
|
||||
->getRepository($this->getConnectionClass())
|
||||
->find($connectionId);
|
||||
if (null === $connection) {
|
||||
throw $this->createNotFoundException();
|
||||
}
|
||||
|
||||
$connectionTypeClass = 'Intaro\DeliveryModuleBundle\Form\ConnectionType';
|
||||
$form = $this->createForm($connectionTypeClass, $connection, [
|
||||
'container' => $this->container,
|
||||
'is_admin' => true,
|
||||
]);
|
||||
$form->handleRequest($request);
|
||||
|
||||
if ($form->isSubmitted() && $form->isValid()) {
|
||||
$this->actualizeWebhooks($connection);
|
||||
$this->entityManager->flush();
|
||||
|
||||
return $this->redirectToRoute($this->getRoute() . '_admin_edit', [
|
||||
'connectionId' => $connection->getId(),
|
||||
]);
|
||||
}
|
||||
|
||||
return $this->render(
|
||||
$this->getShortBundle() . ':Connection:edit.html.twig',
|
||||
[
|
||||
'route' => $this->getRoute(),
|
||||
'connection' => $connection,
|
||||
'form' => $form->createView(),
|
||||
]
|
||||
);
|
||||
}
|
||||
|
||||
/**
|
||||
* @param Request $request
|
||||
* @param string $connectionId
|
||||
*
|
||||
* @return Response
|
||||
*
|
||||
* @throws \Exception
|
||||
*/
|
||||
public function updateConfigurationAction(Request $request, $connectionId)
|
||||
{
|
||||
$this->denyAccessUnlessGranted('ROLE_DEVELOPER');
|
||||
|
||||
$api = $this->getDeliveryApi();
|
||||
|
||||
$connection = $this->entityManager
|
||||
->getRepository($this->getConnectionClass())
|
||||
->find($connectionId);
|
||||
|
||||
$api->setConnection($connection);
|
||||
$result = $api->updateConfiguration();
|
||||
|
||||
if (isset($result['success']) && $result['success']) {
|
||||
$this->flashBag->add('notice', 'ChangesWereSaved');
|
||||
} else {
|
||||
$this->flashBag->add('error', 'ChangesWereNotSaved');
|
||||
}
|
||||
|
||||
return $this->redirectToRoute($this->getRoute() . '_admin_edit', [
|
||||
'connectionId' => $connection->getId(),
|
||||
]);
|
||||
}
|
||||
|
||||
/**
|
||||
* @param Request $request
|
||||
*
|
||||
* @return Response
|
||||
*/
|
||||
public function parcelListAction(Request $request)
|
||||
{
|
||||
$parcelsQuery = $this->entityManager->createQuery('
|
||||
SELECT parcel
|
||||
FROM ' . $this->getParcelClass() . ' parcel
|
||||
');
|
||||
|
||||
$pagination = $this->knpPaginator->paginate(
|
||||
$parcelsQuery,
|
||||
$request->query->getInt('page', 1),
|
||||
20
|
||||
);
|
||||
|
||||
return $this->render(
|
||||
$this->getShortBundle() . ':Parcel:list.html.twig',
|
||||
['route' => $this->getRoute(), 'pagination' => $pagination]
|
||||
);
|
||||
}
|
||||
|
||||
/**
|
||||
* @param Request $request
|
||||
*
|
||||
* @return Response
|
||||
*/
|
||||
public function parcelNewAction(Request $request)
|
||||
{
|
||||
$this->denyAccessUnlessGranted('ROLE_DEVELOPER');
|
||||
|
||||
$parcelClass = $this->getParcelClass();
|
||||
$parcel = new $parcelClass();
|
||||
$parcelTypeClass = 'Intaro\DeliveryModuleBundle\Form\ParcelType';
|
||||
$form = $this->createForm($parcelTypeClass, $parcel, [
|
||||
'connection_class' => $this->getConnectionClass(),
|
||||
]);
|
||||
|
||||
$form->handleRequest($request);
|
||||
|
||||
if ($form->isSubmitted() && $form->isValid()) {
|
||||
$this->entityManager->persist($parcel);
|
||||
$this->entityManager->flush();
|
||||
|
||||
return $this->redirectToRoute($this->getRoute() . '_admin_parcel_list');
|
||||
}
|
||||
|
||||
return $this->render(
|
||||
$this->getShortBundle() . ':Parcel:edit.html.twig',
|
||||
['form' => $form->createView(), 'parcel' => $parcel]
|
||||
);
|
||||
}
|
||||
|
||||
/**
|
||||
* @param Request $request
|
||||
* @param string $parcelId
|
||||
*
|
||||
* @return Response
|
||||
*/
|
||||
public function parcelEditAction(Request $request, $parcelId)
|
||||
{
|
||||
$parcel = $this->entityManager
|
||||
->getRepository($this->getParcelClass())
|
||||
->find(['id' => $parcelId]);
|
||||
|
||||
$parcelTypeClass = 'Intaro\DeliveryModuleBundle\Form\ParcelType';
|
||||
$form = $this->createForm($parcelTypeClass, $parcel, [
|
||||
'connection_class' => $this->getConnectionClass(),
|
||||
]);
|
||||
|
||||
$form->handleRequest($request);
|
||||
|
||||
if ($form->isSubmitted() && $form->isValid()) {
|
||||
$this->entityManager->flush();
|
||||
|
||||
return $this->redirectToRoute($this->getRoute() . '_admin_parcel_list');
|
||||
}
|
||||
|
||||
return $this->render(
|
||||
$this->getShortBundle() . ':Parcel:edit.html.twig',
|
||||
['form' => $form->createView(), 'parcel' => $parcel]
|
||||
);
|
||||
}
|
||||
|
||||
/**
|
||||
* @param Request $request
|
||||
*
|
||||
* @return Response
|
||||
*
|
||||
* @throws \Exception
|
||||
*/
|
||||
public function connectAction(Request $request)
|
||||
{
|
||||
$api = $this->getDeliveryApi();
|
||||
|
||||
$referer = $request->headers->get('referer');
|
||||
$account = $request->query->get('account');
|
||||
$accountUrl = null;
|
||||
if (!empty($account)) {
|
||||
$accountUrl = null === parse_url($account, PHP_URL_HOST)
|
||||
? null : 'https://' . parse_url($account, PHP_URL_HOST);
|
||||
}
|
||||
|
||||
if (
|
||||
!empty($request->request->get('clientId'))
|
||||
|| !empty($request->attributes->get('clientId'))
|
||||
) {
|
||||
if (!empty($request->request->get('clientId'))) {
|
||||
$clientId = $request->request->get('clientId');
|
||||
} else {
|
||||
$clientId = $request->attributes->get('clientId');
|
||||
}
|
||||
|
||||
$connection = $this->entityManager
|
||||
->getRepository($this->getConnectionClass())
|
||||
->findOneBy([
|
||||
'clientId' => $clientId,
|
||||
]);
|
||||
$accountUrl = $connection->getCrmUrl();
|
||||
} else {
|
||||
$class = $this->getConnectionClass();
|
||||
$connection = new $class();
|
||||
$connection
|
||||
->setLanguage($request->getLocale())
|
||||
->setEncoder($this->openSsl);
|
||||
}
|
||||
|
||||
$connectionTypeClass = 'Intaro\DeliveryModuleBundle\Form\ConnectionType';
|
||||
$form = $this->createForm($connectionTypeClass, $connection, [
|
||||
'container' => $this->container,
|
||||
'is_admin' => false,
|
||||
]);
|
||||
$form->handleRequest($request);
|
||||
|
||||
if ($form->isSubmitted() && $form->isValid()) {
|
||||
$connectionIsCreated = true;
|
||||
if (empty($connection->getClientId())) {
|
||||
$connection->generateClientId();
|
||||
$connectionIsCreated = false;
|
||||
}
|
||||
|
||||
$api->setConnection($connection);
|
||||
$this->actualizeWebhooks($connection);
|
||||
$result = $api->updateConfiguration();
|
||||
if (isset($result['success']) && $result['success']) {
|
||||
if (!$connectionIsCreated) {
|
||||
$this->entityManager->persist($connection);
|
||||
}
|
||||
$this->entityManager->flush();
|
||||
|
||||
return $this->redirect($connection->getCrmUrl() . '/admin/integration/list');
|
||||
} else {
|
||||
$srcLogo = $request->getUriForPath(
|
||||
'/bundles/delivery'
|
||||
. strtolower($this->getNameService())
|
||||
. '/images/'
|
||||
. strtolower($this->getNameService())
|
||||
. '.svg'
|
||||
);
|
||||
|
||||
return $this->render(
|
||||
'DeliveryCoreBundle:Connection:configure_error.html.twig',
|
||||
[
|
||||
'referer' => $referer,
|
||||
'errors' => $result,
|
||||
'title_delivery' => $this->getNameService(),
|
||||
'src_logo_delivery' => $srcLogo,
|
||||
]
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
return $this->render(
|
||||
$this->getShortBundle() . ':Connection:configure.html.twig',
|
||||
[
|
||||
'route' => $this->getRoute(),
|
||||
'form' => $form->createView(),
|
||||
'account' => $accountUrl,
|
||||
]
|
||||
);
|
||||
}
|
||||
|
||||
/**
|
||||
* Actualize webhooks
|
||||
*
|
||||
* @param Connection $connection
|
||||
*/
|
||||
protected function actualizeWebhooks(Connection $connection)
|
||||
{
|
||||
}
|
||||
}
|
458
Controller/ApiController.php
Normal file
458
Controller/ApiController.php
Normal file
|
@ -0,0 +1,458 @@
|
|||
<?php
|
||||
|
||||
namespace RetailCrm\DeliveryModuleBundle\Controller;
|
||||
|
||||
use Doctrine\Common\Persistence\ObjectManager;
|
||||
use JMS\Serializer\DeserializationContext;
|
||||
use JMS\Serializer\Exception\Exception as JmsException;
|
||||
use JMS\Serializer\SerializationContext;
|
||||
use JMS\Serializer\SerializerInterface;
|
||||
use RetailCrm\DeliveryModuleBundle\Entity\Account;
|
||||
use RetailCrm\DeliveryModuleBundle\Entity\DeliveryOrder;
|
||||
use RetailCrm\DeliveryModuleBundle\Exception;
|
||||
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\RequestShipmentSave;
|
||||
use RetailCrm\DeliveryModuleBundle\Model\ResponseCalculate;
|
||||
use RetailCrm\DeliveryModuleBundle\Model\ResponseCalculateSuccessful;
|
||||
use RetailCrm\DeliveryModuleBundle\Model\ResponseLoadDeliveryData;
|
||||
use RetailCrm\DeliveryModuleBundle\Model\ResponseSave;
|
||||
use RetailCrm\DeliveryModuleBundle\Model\ResponseShipmentSave;
|
||||
use RetailCrm\DeliveryModuleBundle\Model\ResponseSuccessful;
|
||||
use RetailCrm\DeliveryModuleBundle\ModuleManager;
|
||||
use Symfony\Bundle\FrameworkBundle\Controller\Controller;
|
||||
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;
|
||||
|
||||
abstract class ApiController extends Controller
|
||||
{
|
||||
/**
|
||||
* @var ObjectManager
|
||||
*/
|
||||
protected $entityManager;
|
||||
|
||||
/**
|
||||
* @var SerializerInterface
|
||||
*/
|
||||
protected $jmsSerializer;
|
||||
|
||||
/**
|
||||
* @var ModuleManager
|
||||
*/
|
||||
protected $moduleManager;
|
||||
|
||||
public function __construct(
|
||||
ObjectManager $entityManager,
|
||||
SerializerInterface $jmsSerializer,
|
||||
ModuleManager $moduleManager,
|
||||
DeliveryOrderManager $deliveryOrderManager,
|
||||
RequestStack $requestStack
|
||||
) {
|
||||
$this->entityManager = $entityManager;
|
||||
$this->jmsSerializer = $jmsSerializer;
|
||||
$this->moduleManager = $moduleManager;
|
||||
$this->deliveryOrderManager = $deliveryOrderManager;
|
||||
|
||||
$request = $requestStack->getCurrentRequest();
|
||||
if ($request->isMethod('post')) {
|
||||
$clientId = $request->request->get('clientId');
|
||||
} else {
|
||||
$clientId = $request->query->get('clientId');
|
||||
}
|
||||
|
||||
$account = $entityManager->getRepository(Account::class)
|
||||
->findOneBy(['id' => $clientId]);
|
||||
if (null === $account) {
|
||||
return $this->getInvalidResponse('ClientId not found', 404);
|
||||
}
|
||||
|
||||
$this->moduleManager->setAccount($account);
|
||||
}
|
||||
|
||||
public function activityAction(Request $request): JsonResponse
|
||||
{
|
||||
$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->account->setActive($requestModel->active);
|
||||
$this->account->setFreeze($requestModel->freeze);
|
||||
|
||||
$systemUrl = $request->request->get('systemUrl');
|
||||
$this->account->setCrmUrl($systemUrl);
|
||||
|
||||
$this->entityManager->flush();
|
||||
|
||||
return $this->getSucessfullResponse();
|
||||
}
|
||||
|
||||
public function calculateAction(Request $request): JsonResponse
|
||||
{
|
||||
if (
|
||||
false === $this->moduleManager->getAccount()->getIsActive()
|
||||
|| false !== $this->moduleManager->getAccount()->getIsFreeze()
|
||||
) {
|
||||
return $this->getInvalidResponse('Account is not active', 403);
|
||||
}
|
||||
|
||||
$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\ValidationException $e) {
|
||||
return $this->getInvalidResponse($e->getMessage(), 400);
|
||||
} catch (Exception\ApiException $e) {
|
||||
return $this->getInvalidResponse($e->getMessage(), 400);
|
||||
}
|
||||
|
||||
return $this->getSucessfullResponse($responseModel);
|
||||
}
|
||||
|
||||
public function saveAction(Request $request): JsonResponse
|
||||
{
|
||||
if (
|
||||
false === $this->moduleManager->getAccount()->getIsActive()
|
||||
|| false !== $this->moduleManager->getAccount()->getIsFreeze()
|
||||
) {
|
||||
return $this->getInvalidResponse('Account is not active', 403);
|
||||
}
|
||||
|
||||
$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);
|
||||
}
|
||||
|
||||
$delivery = $this->deliveryOrderManager->findOneBy([
|
||||
'account' => $this->account,
|
||||
'orderId' => $requestModel->order,
|
||||
]);
|
||||
|
||||
// ищем доставки, созданные без заказа в запросе get
|
||||
if (null === $delivery) {
|
||||
$parcel = $this->deliveryOrderManager
|
||||
->findOneBy(['account' => $this->account, 'trackId' => $requestModel->deliveryId]);
|
||||
}
|
||||
|
||||
try {
|
||||
$responseModel = $this->doSave($requestModel, $delivery);
|
||||
} catch (Exception\ValidationException $e) {
|
||||
return $this->getInvalidResponse($e->getMessage(), 400);
|
||||
} catch (Exception\ApiException $e) {
|
||||
return $this->getInvalidResponse($e->getMessage(), 400);
|
||||
} catch (\InvalidArgumentException $e) {
|
||||
return $this->getInvalidResponse($e->getMessage(), 400);
|
||||
}
|
||||
|
||||
if (null === $delivery) {
|
||||
$deliveryClass = $this->deliveryOrderManager->create();
|
||||
$delivery = new $deliveryClass();
|
||||
}
|
||||
|
||||
$delivery
|
||||
->setAccount($this->moduleManager->getAccount())
|
||||
->setOrderId($requestModel->order)
|
||||
->setExternalId($responseModel->deliveryId)
|
||||
->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->entityManager->persist($delivery);
|
||||
}
|
||||
$this->entityManager->flush();
|
||||
|
||||
return $this->getSucessfullResponse($responseModel);
|
||||
}
|
||||
|
||||
public function getAction(Request $request): JsonResponse
|
||||
{
|
||||
if (
|
||||
false === $this->moduleManager->getAccount()->getIsActive()
|
||||
|| false !== $this->moduleManager->getAccount()->getIsFreeze()
|
||||
) {
|
||||
return $this->getInvalidResponse('Account is not active', 403);
|
||||
}
|
||||
|
||||
$externalId = $request->query->get('deliveryId');
|
||||
if (null === $externalId || empty($externalId)) {
|
||||
return $this->getInvalidResponse('DeliveryId is required', 400);
|
||||
}
|
||||
|
||||
try {
|
||||
$responseModel = $this->doGet($externalId);
|
||||
} catch (Exception\ValidationException $e) {
|
||||
return $this->getInvalidResponse($e->getMessage(), 400);
|
||||
} catch (Exception\ApiException $e) {
|
||||
return $this->getInvalidResponse($e->getMessage(), 400);
|
||||
}
|
||||
|
||||
return $this->getSucessfullResponse($responseModel);
|
||||
}
|
||||
|
||||
public function deleteAction(Request $request): JsonResponse
|
||||
{
|
||||
if (
|
||||
false === $this->moduleManager->getAccount()->getIsActive()
|
||||
|| false !== $this->moduleManager->getAccount()->getIsFreeze()
|
||||
) {
|
||||
return $this->getInvalidResponse('Account is not active', 403);
|
||||
}
|
||||
|
||||
$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->account,
|
||||
'externalId' => $requestModel->deliveryId,
|
||||
]);
|
||||
|
||||
if (null === $delivery) {
|
||||
return $this->getInvalidResponse("Delivery {$requestModel->deliveryId} not found", 404);
|
||||
}
|
||||
|
||||
try {
|
||||
$this->doDelete($requestModel, $delivery);
|
||||
} catch (Exception\ValidationException $e) {
|
||||
return $this->getInvalidResponse($e->getMessage(), 400);
|
||||
} catch (Exception\ApiException $e) {
|
||||
return $this->getInvalidResponse($e->getMessage(), 400);
|
||||
}
|
||||
|
||||
$this->entityManager->remove($delivery);
|
||||
$this->entityManager->flush();
|
||||
|
||||
return $this->getSucessfullResponse();
|
||||
}
|
||||
|
||||
public function printAction(Request $request): Response
|
||||
{
|
||||
if (
|
||||
false === $this->moduleManager->getAccount()->getIsActive()
|
||||
|| false !== $this->moduleManager->getAccount()->getIsFreeze()
|
||||
) {
|
||||
return $this->getInvalidResponse('Account is not active', 403);
|
||||
}
|
||||
|
||||
$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\ValidationException $e) {
|
||||
return $this->getInvalidResponse($e->getMessage(), 400);
|
||||
} catch (Exception\ApiException $e) {
|
||||
return $this->getInvalidResponse($e->getMessage(), 500);
|
||||
}
|
||||
|
||||
if (is_array($plateData)) {
|
||||
$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($plateData);
|
||||
$response->headers->set('Content-Type', 'application/pdf');
|
||||
}
|
||||
|
||||
return $response;
|
||||
}
|
||||
|
||||
public function shipmentSaveAction(Request $request): JsonResponse
|
||||
{
|
||||
if (
|
||||
false === $this->moduleManager->getAccount()->getIsActive()
|
||||
|| false !== $this->moduleManager->getAccount()->getIsFreeze()
|
||||
) {
|
||||
return $this->getInvalidResponse('Account is not active', 403);
|
||||
}
|
||||
|
||||
$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\ValidationException $e) {
|
||||
return $this->getInvalidResponse($e->getMessage(), 400);
|
||||
} catch (Exception\ApiException $e) {
|
||||
return $this->getInvalidResponse($e->getMessage(), 400);
|
||||
} catch (\InvalidArgumentException $e) {
|
||||
return $this->getInvalidResponse($e->getMessage(), 400);
|
||||
}
|
||||
|
||||
return $this->getSucessfullResponse($responseModel);
|
||||
}
|
||||
|
||||
public function shipmentDeleteAction(Request $request): JsonResponse
|
||||
{
|
||||
if (
|
||||
false === $this->moduleManager->getAccount()->getIsActive()
|
||||
|| false !== $this->moduleManager->getAccount()->getIsFreeze()
|
||||
) {
|
||||
return $this->getInvalidResponse('Account is not active', 403);
|
||||
}
|
||||
|
||||
$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\ValidationException $e) {
|
||||
return $this->getInvalidResponse($e->getMessage(), 400);
|
||||
} catch (Exception\ApiException $e) {
|
||||
return $this->getInvalidResponse($e->getMessage(), 400);
|
||||
}
|
||||
|
||||
return $this->getSucessfullResponse();
|
||||
}
|
||||
|
||||
protected function getSucessfullResponse($responseResult = null): JsonResponse
|
||||
{
|
||||
if (is_array($responseResult)) {
|
||||
$response = new ResponseCalculateSuccessful();
|
||||
} else {
|
||||
$response = new ResponseSuccessful();
|
||||
}
|
||||
$response->result = $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): ResponseCalculate
|
||||
{
|
||||
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 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);
|
||||
}
|
||||
}
|
55
DependencyInjection/Configuration.php
Normal file
55
DependencyInjection/Configuration.php
Normal file
|
@ -0,0 +1,55 @@
|
|||
<?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();
|
||||
$rootNode = $treeBuilder->root('retailcrm_delivery_module');
|
||||
|
||||
$rootNode
|
||||
->arrayNode('module')
|
||||
->scalarNode('integration_code')
|
||||
->isRequired()
|
||||
->end()
|
||||
->arrayNode('locales')
|
||||
->requiresAtLeastOneElement()
|
||||
->useAttributeAsKey('locale')
|
||||
|
||||
->prototype('array')
|
||||
->children()
|
||||
->scalarNode('name')
|
||||
->isRequired()
|
||||
->end()
|
||||
->scalarNode('logo')
|
||||
->isRequired()
|
||||
->end()
|
||||
->end()
|
||||
->end()
|
||||
->scalarNode('countries')
|
||||
->cannotBeEmpty()
|
||||
->defaultValue(['ru'])
|
||||
->end()
|
||||
->cannotBeEmpty()
|
||||
->end()
|
||||
->scalarNode('module_manager_class')
|
||||
->isRequired()
|
||||
->end()
|
||||
->scalarNode('delivery_order_class')
|
||||
->isRequired()
|
||||
->end()
|
||||
;
|
||||
|
||||
return $treeBuilder;
|
||||
}
|
||||
}
|
44
DependencyInjection/DeliveryCoreExtension.php
Normal file
44
DependencyInjection/DeliveryCoreExtension.php
Normal file
|
@ -0,0 +1,44 @@
|
|||
<?php
|
||||
|
||||
namespace RetailCrm\DeliveryModuleBundle\DependencyInjection;
|
||||
|
||||
use Symfony\Component\Config\FileLocator;
|
||||
use Symfony\Component\DependencyInjection\ContainerBuilder;
|
||||
use Symfony\Component\DependencyInjection\Loader;
|
||||
use Symfony\Component\HttpKernel\DependencyInjection\Extension;
|
||||
|
||||
/**
|
||||
* 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 DeliveryCoreExtension extends Extension
|
||||
{
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*/
|
||||
public function load(array $configs, ContainerBuilder $container)
|
||||
{
|
||||
$loader = new Loader\YamlFileLoader(
|
||||
$container,
|
||||
new FileLocator(dirname(__DIR__) . '/Resources/config')
|
||||
);
|
||||
$loader->load('services.xml');
|
||||
|
||||
$configuration = new Configuration();
|
||||
$config = $this->processConfiguration($configuration, $configs);
|
||||
|
||||
$container->setParameter(
|
||||
'retailcrm.delivery_module.module_configuration',
|
||||
$config['module']
|
||||
);
|
||||
$container->setParameter(
|
||||
'retailcrm.delivery_module.module_manager.class',
|
||||
$config['module_manager_class']
|
||||
);
|
||||
$container->setParameter(
|
||||
'retailcrm.delivery_module.delivery_order.class',
|
||||
$config['delivery_order_class']
|
||||
);
|
||||
}
|
||||
}
|
174
Entity/Account.php
Normal file
174
Entity/Account.php
Normal file
|
@ -0,0 +1,174 @@
|
|||
<?php
|
||||
|
||||
namespace RetailCrm\DeliveryModuleBundle\Entity;
|
||||
|
||||
use Doctrine\ORM\Mapping as ORM;
|
||||
use JMS\Serializer\Annotation as Serializer;
|
||||
use Ramsey\Uuid\Uuid;
|
||||
use Ramsey\Uuid\UuidInterface;
|
||||
|
||||
/**
|
||||
* @ORM\Entity
|
||||
* @ORM\Table(
|
||||
* name="account",
|
||||
* uniqueConstraints={
|
||||
* @ORM\UniqueConstraint(name="account_crm_url_api_key_idx", columns={"crm_url", "crm_api_key"})
|
||||
* }
|
||||
* )
|
||||
*/
|
||||
class Account
|
||||
{
|
||||
/**
|
||||
* @var UuidInterface
|
||||
*
|
||||
* @ORM\Id
|
||||
* @ORM\Column(type="uuid")
|
||||
* @Serializer\Groups({"get"})
|
||||
* @Serializer\Type("string")
|
||||
*/
|
||||
protected $id;
|
||||
|
||||
/**
|
||||
* @var \DateTime
|
||||
*
|
||||
* @ORM\Column(name="created_at", type="datetime", nullable=false, options={"default"="now()"})
|
||||
* @Serializer\Groups({"get"})
|
||||
* @Serializer\Type("DateTime<'Y-m-d H:i:s'>")
|
||||
*/
|
||||
protected $createdAt;
|
||||
|
||||
/**
|
||||
* @var string
|
||||
*
|
||||
* @ORM\Column(name="crm_url", type="string", length=255, nullable=false)
|
||||
* @Serializer\Groups({"get", "connect"})
|
||||
* @Serializer\Type("string")
|
||||
*/
|
||||
protected $crmUrl;
|
||||
|
||||
/**
|
||||
* @var string
|
||||
*
|
||||
* @ORM\Column(name="crm_api_key", type="string", length=255, nullable=false)
|
||||
* @Serializer\Groups({"get", "connect"})
|
||||
* @Serializer\Type("string")
|
||||
*/
|
||||
protected $crmApiKey;
|
||||
|
||||
/**
|
||||
* @var bool
|
||||
*
|
||||
* @ORM\Column(name="active", type="boolean", options={"default"=true})
|
||||
*/
|
||||
protected $active;
|
||||
|
||||
/**
|
||||
* @var bool
|
||||
*
|
||||
* @ORM\Column(name="freezed", type="boolean", options={"default"=false})
|
||||
*/
|
||||
protected $freeze;
|
||||
|
||||
/**
|
||||
* @var string
|
||||
*
|
||||
* @ORM\Column(name="language", type="string", length=255, nullable=true)
|
||||
*/
|
||||
protected $language;
|
||||
|
||||
public function __construct()
|
||||
{
|
||||
$this->id = Uuid::uuid4();
|
||||
$this->createdAt = new \DateTime();
|
||||
$this->active = false;
|
||||
$this->freeze = false;
|
||||
}
|
||||
|
||||
public function getId(): UuidInterface
|
||||
{
|
||||
return $this->id;
|
||||
}
|
||||
|
||||
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;
|
||||
}
|
||||
}
|
117
Entity/DeliveryOrder.php
Normal file
117
Entity/DeliveryOrder.php
Normal file
|
@ -0,0 +1,117 @@
|
|||
<?php
|
||||
|
||||
namespace RetailCrm\DeliveryModuleBundle\Entity;
|
||||
|
||||
use Doctrine\ORM\Mapping as ORM;
|
||||
|
||||
abstract class DeliveryOrder
|
||||
{
|
||||
/**
|
||||
* @var int
|
||||
*
|
||||
* @ORM\Column(name="id", type="integer")
|
||||
* @ORM\Id
|
||||
* @ORM\GeneratedValue(strategy="AUTO")
|
||||
*/
|
||||
protected $id;
|
||||
|
||||
/**
|
||||
* @var Account
|
||||
*
|
||||
* @ORM\ManyToOne(targetEntity="Account")
|
||||
* @ORM\JoinColumn(name="account_id", referencedColumnName="id", onDelete="CASCADE")
|
||||
*/
|
||||
protected $account;
|
||||
|
||||
/**
|
||||
* @var int
|
||||
*
|
||||
* @ORM\Column(name="order_id", type="integer", nullable=false)
|
||||
*/
|
||||
protected $orderId;
|
||||
|
||||
/**
|
||||
* @var string
|
||||
*
|
||||
* @ORM\Column(name="external_id", type="string", length=255, nullable=false)
|
||||
*/
|
||||
protected $externalId;
|
||||
|
||||
/**
|
||||
* @var bool
|
||||
*
|
||||
* @ORM\Column(name="ended", type="boolean")
|
||||
*/
|
||||
protected $ended;
|
||||
|
||||
public function __construct()
|
||||
{
|
||||
$this->ended = false;
|
||||
}
|
||||
|
||||
/**
|
||||
* @return int
|
||||
*/
|
||||
public function getId()
|
||||
{
|
||||
return $this->id;
|
||||
}
|
||||
|
||||
public function setAccount(Account $account): self
|
||||
{
|
||||
$this->account = $account;
|
||||
|
||||
return $this;
|
||||
}
|
||||
|
||||
public function getAccount(): ?Account
|
||||
{
|
||||
return $this->account;
|
||||
}
|
||||
|
||||
public function setOrderId(int $orderId): self
|
||||
{
|
||||
$this->orderId = $orderId;
|
||||
|
||||
return $this;
|
||||
}
|
||||
|
||||
public function getOrderId(): int
|
||||
{
|
||||
return $this->orderId;
|
||||
}
|
||||
|
||||
public function setExternalId(string $externalId): self
|
||||
{
|
||||
$this->externalId = $externalId;
|
||||
|
||||
return $this;
|
||||
}
|
||||
|
||||
public function getExternalId(): string
|
||||
{
|
||||
return $this->externalId;
|
||||
}
|
||||
|
||||
public function setEnded(bool $ended): self
|
||||
{
|
||||
$this->ended = $ended;
|
||||
|
||||
return $this;
|
||||
}
|
||||
|
||||
public function getTrackNumber(): string
|
||||
{
|
||||
return $this->externalId;
|
||||
}
|
||||
|
||||
public function setTrackNumber(string $trackNumber): self
|
||||
{
|
||||
return $this;
|
||||
}
|
||||
|
||||
public function getEnded(): bool
|
||||
{
|
||||
return $this->ended;
|
||||
}
|
||||
}
|
30
EventListener/SerializeListener.php
Normal file
30
EventListener/SerializeListener.php
Normal file
|
@ -0,0 +1,30 @@
|
|||
<?php
|
||||
|
||||
namespace RetailCrm\DeliveryModuleBundle;
|
||||
|
||||
use Symfony\Component\DependencyInjection\ContainerAwareTrait;
|
||||
use JMS\Serializer\EventDispatcher\Events;
|
||||
use JMS\Serializer\EventDispatcher\PreSerializeEvent;
|
||||
use JMS\Serializer\EventDispatcher\EventSubscriberInterface;
|
||||
|
||||
|
||||
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');
|
||||
}
|
||||
}
|
||||
}
|
7
Exception/AbstractException.php
Normal file
7
Exception/AbstractException.php
Normal file
|
@ -0,0 +1,7 @@
|
|||
<?php
|
||||
|
||||
namespace RetailCrm\DeliveryModuleBundle\Exception;
|
||||
|
||||
abstract class AbstractException extends \Exception
|
||||
{
|
||||
}
|
7
Exception/ApiException.php
Normal file
7
Exception/ApiException.php
Normal file
|
@ -0,0 +1,7 @@
|
|||
<?php
|
||||
|
||||
namespace RetailCrm\DeliveryModuleBundle\Exception;
|
||||
|
||||
class ApiException extends AbstractException
|
||||
{
|
||||
}
|
7
Exception/ValidationException.php
Normal file
7
Exception/ValidationException.php
Normal file
|
@ -0,0 +1,7 @@
|
|||
<?php
|
||||
|
||||
namespace RetailCrm\DeliveryModuleBundle\Exception;
|
||||
|
||||
class ValidationException extends AbstractException
|
||||
{
|
||||
}
|
36
Form/ConfigureEditType.php
Normal file
36
Form/ConfigureEditType.php
Normal file
|
@ -0,0 +1,36 @@
|
|||
<?php
|
||||
|
||||
namespace RetailCrm\DeliveryModuleBundle\Form;
|
||||
|
||||
use Symfony\Component\Form\AbstractType;
|
||||
use Symfony\Component\Form\Extension\Core\Type\CheckboxType;
|
||||
use Symfony\Component\Form\FormBuilderInterface;
|
||||
use Symfony\Component\OptionsResolver\OptionsResolver;
|
||||
|
||||
class ConfigureEditType extends AbstractType
|
||||
{
|
||||
/**
|
||||
* @param FormBuilderInterface $builder
|
||||
* @param array $options
|
||||
*
|
||||
* @return void
|
||||
*/
|
||||
public function buildForm(FormBuilderInterface $builder, array $options)
|
||||
{
|
||||
$builder
|
||||
->add('connectionId', null, [
|
||||
'label' => 'label.connectionId',
|
||||
'required' => true,
|
||||
'attr' => [
|
||||
'placeholder' => 'label.connectionId'
|
||||
]
|
||||
])
|
||||
->add('crmKey', null, [
|
||||
'label' => 'label.crmKey',
|
||||
'required' => true,
|
||||
'attr' => [
|
||||
'placeholder' => 'label.crmKey'
|
||||
]
|
||||
]);
|
||||
}
|
||||
}
|
78
Form/ConnectionType.php
Normal file
78
Form/ConnectionType.php
Normal file
|
@ -0,0 +1,78 @@
|
|||
<?php
|
||||
|
||||
namespace RetailCrm\DeliveryModuleBundle\Form;
|
||||
|
||||
use Symfony\Component\Form\AbstractType;
|
||||
use Symfony\Component\Form\Extension\Core\Type\CheckboxType;
|
||||
use Symfony\Component\Form\Extension\Core\Type\TextType;
|
||||
use Symfony\Component\Form\Extension\Core\Type\ChoiceType;
|
||||
use Symfony\Component\Form\Extension\Core\Type\UrlType;
|
||||
use Symfony\Component\Form\FormBuilderInterface;
|
||||
use Symfony\Component\Form\FormEvents;
|
||||
use Symfony\Component\Form\FormEvent;
|
||||
use Symfony\Component\OptionsResolver\OptionsResolver;
|
||||
|
||||
class ConnectionType extends AbstractType
|
||||
{
|
||||
/**
|
||||
* @param FormBuilderInterface $builder
|
||||
* @param array $options
|
||||
*
|
||||
* @return void
|
||||
*/
|
||||
public function buildForm(FormBuilderInterface $builder, array $options)
|
||||
{
|
||||
$builder
|
||||
->add('crmUrl', TextType::class, [
|
||||
'label' => 'label.crmUrl',
|
||||
'required' => true,
|
||||
'attr' => [
|
||||
'placeholder' => 'label.crmUrl',
|
||||
'pattern' => '^(https?:\/\/)?([\da-z0-9\.-]+)\.([a-z\.]{2,6})([\/\w \.-]*)*\/?$',
|
||||
],
|
||||
'translation_domain' => 'messages'
|
||||
])
|
||||
->add('crmKey', TextType::class, [
|
||||
'label' => 'label.crmKey',
|
||||
'required' => true,
|
||||
'attr' => [
|
||||
'placeholder' => 'label.crmKey'
|
||||
],
|
||||
'translation_domain' => 'messages'
|
||||
])
|
||||
->add('isActive', CheckboxType::class, [
|
||||
'label' => 'label.isActive',
|
||||
'required' => false,
|
||||
'translation_domain' => 'messages'
|
||||
])
|
||||
->add('language', ChoiceType::class, [
|
||||
'label' => 'label.language',
|
||||
'choices' => [
|
||||
'RU' => 'ru',
|
||||
'EN' => 'en',
|
||||
'ES' => 'es'
|
||||
],
|
||||
'required' => true,
|
||||
'translation_domain' => 'messages'
|
||||
])
|
||||
->add('isFreeze', CheckboxType::class, [
|
||||
'label' => 'label.isFreeze',
|
||||
'required' => false,
|
||||
'translation_domain' => 'messages'
|
||||
]);
|
||||
|
||||
if ($options['is_admin']) {
|
||||
$builder
|
||||
->add('debug', CheckboxType::class, [
|
||||
'label' => 'label.debug',
|
||||
'required' => false,
|
||||
'translation_domain' => 'messages'
|
||||
]);
|
||||
}
|
||||
}
|
||||
|
||||
public function configureOptions(OptionsResolver $resolver)
|
||||
{
|
||||
$resolver->setRequired(['container', 'is_admin']);
|
||||
}
|
||||
}
|
63
Form/ParcelType.php
Normal file
63
Form/ParcelType.php
Normal file
|
@ -0,0 +1,63 @@
|
|||
<?php
|
||||
|
||||
namespace RetailCrm\DeliveryModuleBundle\Form;
|
||||
|
||||
use Symfony\Bridge\Doctrine\Form\Type\EntityType;
|
||||
use Symfony\Component\Form\AbstractType;
|
||||
use Symfony\Component\Form\Extension\Core\Type\CheckboxType;
|
||||
use Symfony\Component\Form\Extension\Core\Type\TextType;
|
||||
use Symfony\Component\Form\FormBuilderInterface;
|
||||
use Symfony\Component\OptionsResolver\OptionsResolver;
|
||||
|
||||
abstract class ParcelType extends AbstractType
|
||||
{
|
||||
/**
|
||||
* {@inheritDoc}
|
||||
*/
|
||||
public function buildForm(FormBuilderInterface $builder, array $options)
|
||||
{
|
||||
$builder
|
||||
->add(
|
||||
'connection',
|
||||
EntityType::class,
|
||||
[
|
||||
'class' => $options['connection_class'],
|
||||
'label' => 'label.connection',
|
||||
'translation_domain' => 'messages'
|
||||
]
|
||||
)
|
||||
->add(
|
||||
'orderId',
|
||||
TextType::class,
|
||||
[
|
||||
'label' => 'label.orderId',
|
||||
'translation_domain' => 'messages'
|
||||
]
|
||||
)
|
||||
->add(
|
||||
'trackId',
|
||||
TextType::class,
|
||||
[
|
||||
'label' => 'label.trackId',
|
||||
'translation_domain' => 'messages'
|
||||
]
|
||||
)
|
||||
->add(
|
||||
'isClosed',
|
||||
CheckboxType::class,
|
||||
[
|
||||
'required' => false,
|
||||
'label' => 'label.isClosed',
|
||||
'translation_domain' => 'messages'
|
||||
]
|
||||
);
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritDoc}
|
||||
*/
|
||||
public function configureOptions(OptionsResolver $resolver)
|
||||
{
|
||||
$resolver->setRequired(['connection_class']);
|
||||
}
|
||||
}
|
9
IntaroRetailCRMDeliveryModuleBundle.php
Normal file
9
IntaroRetailCRMDeliveryModuleBundle.php
Normal file
|
@ -0,0 +1,9 @@
|
|||
<?php
|
||||
|
||||
namespace RetailCrm\DeliveryModuleBundle;
|
||||
|
||||
use Symfony\Component\HttpKernel\Bundle\Bundle;
|
||||
|
||||
class RetailCrmDeliveryModuleBundle extends Bundle
|
||||
{
|
||||
}
|
165
Model/Configuration.php
Normal file
165
Model/Configuration.php
Normal file
|
@ -0,0 +1,165 @@
|
|||
<?php
|
||||
|
||||
namespace RetailCrm\DeliveryModuleBundle\Model;
|
||||
|
||||
use JMS\Serializer\Annotation as Serializer;
|
||||
|
||||
use RetailCrm\DeliveryModuleBundle\Model\Status;
|
||||
use RetailCrm\DeliveryModuleBundle\Model\Plate;
|
||||
use RetailCrm\DeliveryModuleBundle\Model\DeliveryDataField;
|
||||
|
||||
class Configuration
|
||||
{
|
||||
const PAYER_TYPE_RECEIVER = 'receiver';
|
||||
const PAYER_TYPE_SENDER = 'sender';
|
||||
|
||||
/**
|
||||
* Описание подключения
|
||||
* @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 integer
|
||||
*
|
||||
* @Serializer\Groups({"set", "get"})
|
||||
* @Serializer\SerializedName("platePrintLimit")
|
||||
* @Serializer\Type("integer")
|
||||
*/
|
||||
public $platePrintLimit = 100;
|
||||
|
||||
/**
|
||||
* В методе calculate расчитывается стоимость доставки
|
||||
* @var boolean
|
||||
*
|
||||
* @Serializer\Groups({"set", "get"})
|
||||
* @Serializer\SerializedName("rateDeliveryCost")
|
||||
* @Serializer\Type("boolean")
|
||||
*/
|
||||
public $rateDeliveryCost = true;
|
||||
|
||||
/**
|
||||
* Разрешить использование упаковок
|
||||
* @var boolean
|
||||
*
|
||||
* @Serializer\Groups({"set", "get"})
|
||||
* @Serializer\SerializedName("allowPackages")
|
||||
* @Serializer\Type("boolean")
|
||||
*/
|
||||
public $allowPackages = false;
|
||||
|
||||
/**
|
||||
* Доставка наложенным платежом доступна/не доступна
|
||||
* @var boolean
|
||||
*
|
||||
* @Serializer\Groups({"set", "get"})
|
||||
* @Serializer\SerializedName("codAvailable")
|
||||
* @Serializer\Type("boolean")
|
||||
*/
|
||||
public $codAvailable = false;
|
||||
|
||||
/**
|
||||
* Возможен самопривоз на терминал.
|
||||
* @var boolean
|
||||
*
|
||||
* @Serializer\Groups({"set", "get"})
|
||||
* @Serializer\SerializedName("selfShipmentAvailable")
|
||||
* @Serializer\Type("boolean")
|
||||
*/
|
||||
public $selfShipmentAvailable = false;
|
||||
|
||||
/**
|
||||
* Разрешить отдельно передавать трек номер
|
||||
* @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;
|
||||
}
|
28
Model/Coordinates.php
Normal file
28
Model/Coordinates.php
Normal file
|
@ -0,0 +1,28 @@
|
|||
<?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;
|
||||
}
|
68
Model/Customer.php
Normal file
68
Model/Customer.php
Normal file
|
@ -0,0 +1,68 @@
|
|||
<?php
|
||||
|
||||
namespace RetailCrm\DeliveryModuleBundle\Model;
|
||||
|
||||
use JMS\Serializer\Annotation as Serializer;
|
||||
|
||||
class Customer
|
||||
{
|
||||
/**
|
||||
* Идентификатор покупателя
|
||||
* @var integer
|
||||
*
|
||||
* @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;
|
||||
}
|
249
Model/DeliveryAddress.php
Normal file
249
Model/DeliveryAddress.php
Normal file
|
@ -0,0 +1,249 @@
|
|||
<?php
|
||||
|
||||
namespace RetailCrm\DeliveryModuleBundle\Model;
|
||||
|
||||
use Symfony\Component\Validator\Mapping\ClassMetadata;
|
||||
use Symfony\Component\Validator\Constraints as Assert;
|
||||
use JMS\Serializer\Annotation as Serializer;
|
||||
|
||||
class DeliveryAddress
|
||||
{
|
||||
/**
|
||||
* Почтовый индекс
|
||||
*
|
||||
* @var string $index
|
||||
*
|
||||
* @Serializer\Groups({"get", "set", "response"})
|
||||
* @Serializer\SerializedName("index")
|
||||
* @Serializer\Type("string")
|
||||
*
|
||||
*/
|
||||
public $index;
|
||||
|
||||
/**
|
||||
* ISO код страны (ISO 3166-1 alpha-2)
|
||||
*
|
||||
* @var string $country
|
||||
*
|
||||
* @Serializer\Groups({"get", "set", "response"})
|
||||
* @Serializer\SerializedName("countryIso")
|
||||
* @Serializer\Type("string")
|
||||
*
|
||||
*/
|
||||
public $country;
|
||||
|
||||
/**
|
||||
* Область/край
|
||||
*
|
||||
* @var string $region
|
||||
*
|
||||
* @Serializer\Groups({"get", "set", "response"})
|
||||
* @Serializer\SerializedName("region")
|
||||
* @Serializer\Type("string")
|
||||
*
|
||||
*/
|
||||
public $region;
|
||||
|
||||
/**
|
||||
* Идентификатор региона в Geohelper
|
||||
* @var integer $regionId
|
||||
*
|
||||
* @Serializer\Groups({"get", "set", "response"})
|
||||
* @Serializer\SerializedName("regionId")
|
||||
* @Serializer\Type("integer")
|
||||
*/
|
||||
public $regionId;
|
||||
|
||||
/**
|
||||
* Город
|
||||
*
|
||||
* @var string $city
|
||||
*
|
||||
* @Serializer\Groups({"get", "set", "response"})
|
||||
* @Serializer\SerializedName("city")
|
||||
* @Serializer\Type("string")
|
||||
*
|
||||
*/
|
||||
public $city;
|
||||
|
||||
/**
|
||||
* Идентификатор города в Geohelper
|
||||
*
|
||||
* @var integer $cityId
|
||||
*
|
||||
* @Serializer\Groups({"get", "set", "response"})
|
||||
* @Serializer\SerializedName("cityId")
|
||||
* @Serializer\Type("integer")
|
||||
*/
|
||||
public $cityId;
|
||||
|
||||
/**
|
||||
* Тип населенного пункта
|
||||
* @var string $cityType
|
||||
*
|
||||
* @Serializer\Groups({"get", "set", "response"})
|
||||
* @Serializer\SerializedName("cityType")
|
||||
* @Serializer\Type("string")
|
||||
*/
|
||||
public $cityType;
|
||||
|
||||
/**
|
||||
* Название улицы, шоссе, проспекта, проезда
|
||||
*
|
||||
* @var string $street
|
||||
*
|
||||
* @Serializer\Groups({"get", "set", "response"})
|
||||
* @Serializer\SerializedName("street")
|
||||
* @Serializer\Type("string")
|
||||
*
|
||||
*/
|
||||
public $street;
|
||||
|
||||
/**
|
||||
* Идентификатор улицы в Geohelper
|
||||
*
|
||||
* @var integer $streetId
|
||||
*
|
||||
* @Serializer\Groups({"get", "set", "response"})
|
||||
* @Serializer\SerializedName("streetId")
|
||||
* @Serializer\Type("integer")
|
||||
*/
|
||||
public $streetId;
|
||||
|
||||
/**
|
||||
* Тип улицы
|
||||
* @var string $streetType
|
||||
*
|
||||
* @Serializer\Groups({"get", "set", "response"})
|
||||
* @Serializer\SerializedName("streetType")
|
||||
* @Serializer\Type("string")
|
||||
*/
|
||||
public $streetType;
|
||||
|
||||
/**
|
||||
* Дом
|
||||
*
|
||||
* @var string $building
|
||||
*
|
||||
* @Serializer\Groups({"get", "set", "response"})
|
||||
* @Serializer\SerializedName("building")
|
||||
* @Serializer\Type("string")
|
||||
*
|
||||
*/
|
||||
public $building;
|
||||
|
||||
/**
|
||||
* Номер квартиры или офиса
|
||||
*
|
||||
* @var string $flat
|
||||
*
|
||||
* @Serializer\Groups({"get", "set", "response"})
|
||||
* @Serializer\SerializedName("flat")
|
||||
* @Serializer\Type("string")
|
||||
*
|
||||
*/
|
||||
public $flat;
|
||||
|
||||
/**
|
||||
* Код домофона
|
||||
*
|
||||
* @var string $intercomCode
|
||||
*
|
||||
* @Serializer\Groups({"get", "set", "response"})
|
||||
* @Serializer\SerializedName("intercomCode")
|
||||
* @Serializer\Type("string")
|
||||
*
|
||||
*/
|
||||
public $intercomCode;
|
||||
|
||||
/**
|
||||
* Этаж
|
||||
*
|
||||
* @var integer $floor
|
||||
*
|
||||
* @Serializer\Groups({"get", "set", "response"})
|
||||
* @Serializer\SerializedName("floor")
|
||||
* @Serializer\Type("integer")
|
||||
*
|
||||
*/
|
||||
public $floor;
|
||||
|
||||
/**
|
||||
* Подъезд
|
||||
*
|
||||
* @var integer $block
|
||||
*
|
||||
* @Serializer\Groups({"get", "set", "response"})
|
||||
* @Serializer\SerializedName("block")
|
||||
* @Serializer\Type("integer")
|
||||
*
|
||||
*/
|
||||
public $block;
|
||||
|
||||
/**
|
||||
* Строение/Корпус
|
||||
*
|
||||
* @var string $house
|
||||
*
|
||||
* @Serializer\Groups({"get", "set", "response"})
|
||||
* @Serializer\SerializedName("house")
|
||||
* @Serializer\Type("string")
|
||||
*
|
||||
*/
|
||||
public $house;
|
||||
|
||||
/**
|
||||
* Метро
|
||||
*
|
||||
* @var string $metro
|
||||
*
|
||||
* @Serializer\Groups({"get", "set", "response"})
|
||||
* @Serializer\SerializedName("metro")
|
||||
* @Serializer\Type("string")
|
||||
*
|
||||
*/
|
||||
public $metro;
|
||||
|
||||
/**
|
||||
* Дополнительные заметки
|
||||
*
|
||||
* @var string $notes
|
||||
*
|
||||
* @Serializer\Groups({"get", "set", "response"})
|
||||
* @Serializer\SerializedName("notes")
|
||||
* @Serializer\Type("string")
|
||||
*
|
||||
*/
|
||||
public $notes;
|
||||
|
||||
/**
|
||||
* Адрес в виде строки
|
||||
*
|
||||
* @var string $text
|
||||
*
|
||||
* @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;
|
||||
}
|
124
Model/DeliveryDataField.php
Normal file
124
Model/DeliveryDataField.php
Normal file
|
@ -0,0 +1,124 @@
|
|||
<?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 boolean
|
||||
*
|
||||
* @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;
|
||||
|
||||
/**
|
||||
* Поле обязательно для заполнения
|
||||
* @var boolean
|
||||
*
|
||||
* @Serializer\Groups({"get", "set"})
|
||||
* @Serializer\SerializedName("required")
|
||||
* @Serializer\Type("boolean")
|
||||
*/
|
||||
public $isRequired = false;
|
||||
|
||||
/**
|
||||
* Поле влияет на стоимость доставки. Если true - значение поля используется в методе calculate
|
||||
* @var boolean
|
||||
*
|
||||
* @Serializer\Groups({"get", "set"})
|
||||
* @Serializer\SerializedName("affectsCost")
|
||||
* @Serializer\Type("boolean")
|
||||
*/
|
||||
public $isAffectsCost = false;
|
||||
|
||||
/**
|
||||
* Разрешено ли редактировать поле.
|
||||
* Если false - поле информационное - заполняется только данными,
|
||||
* полученными напрямую от службы доставки (
|
||||
* например стоимость страховки - может заполняться после оформления доставки или при расчете стоимости)
|
||||
* @var boolean
|
||||
*
|
||||
* @Serializer\Groups({"get", "set"})
|
||||
* @Serializer\SerializedName("editable")
|
||||
* @Serializer\Type("boolean")
|
||||
*/
|
||||
public $isEditable = true;
|
||||
}
|
340
Model/DeliveryTime.php
Normal file
340
Model/DeliveryTime.php
Normal file
|
@ -0,0 +1,340 @@
|
|||
<?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 null|string|\DateTime $from
|
||||
* @param null|string|\DateTime $to
|
||||
* @param null|string $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);
|
||||
}
|
||||
|
||||
/**
|
||||
* Проверяет, соответствует ли время доставки диапазону из настроек
|
||||
*
|
||||
* @param array $range
|
||||
* @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'] ||
|
||||
$range['from'] === '00:00' ||
|
||||
$range['from'] === '00:00:00'
|
||||
) {
|
||||
$fromEquals = true;
|
||||
}
|
||||
}
|
||||
|
||||
if ($to) {
|
||||
if (isset($range['to'])) {
|
||||
$toEquals = $to->format('H:i') === $range['to'];
|
||||
}
|
||||
} else {
|
||||
if (!isset($range['to']) ||
|
||||
!$range['to'] ||
|
||||
$range['from'] === '23:59' ||
|
||||
$range['from'] === '23:59:59'
|
||||
) {
|
||||
$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 ($from === null && $to !== null) {
|
||||
$this->from = new \DateTime('1970-01-01T00:00:00');
|
||||
} elseif ($to === null && $from !== null) {
|
||||
$this->to = new \DateTime('1970-01-01T23:59:59');
|
||||
} elseif ($to === null && $from === null) {
|
||||
$this->to = null;
|
||||
$this->from = null;
|
||||
}
|
||||
}
|
||||
}
|
128
Model/IntegrationConfiguration.php
Normal file
128
Model/IntegrationConfiguration.php
Normal file
|
@ -0,0 +1,128 @@
|
|||
<?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 boolean
|
||||
*
|
||||
* @Serializer\Groups({"set", "get", "activity"})
|
||||
* @Serializer\SerializedName("active")
|
||||
* @Serializer\Type("boolean")
|
||||
*/
|
||||
public $active;
|
||||
|
||||
/**
|
||||
* Работа модуля заморожена
|
||||
* @var boolean
|
||||
*
|
||||
* @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;
|
||||
}
|
68
Model/Manager.php
Normal file
68
Model/Manager.php
Normal file
|
@ -0,0 +1,68 @@
|
|||
<?php
|
||||
|
||||
namespace RetailCrm\DeliveryModuleBundle\Model;
|
||||
|
||||
use JMS\Serializer\Annotation as Serializer;
|
||||
|
||||
class Manager
|
||||
{
|
||||
/**
|
||||
* Идентификатор менеджера
|
||||
* @var integer
|
||||
*
|
||||
* @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;
|
||||
}
|
96
Model/Package.php
Normal file
96
Model/Package.php
Normal file
|
@ -0,0 +1,96 @@
|
|||
<?php
|
||||
|
||||
namespace RetailCrm\DeliveryModuleBundle\Model;
|
||||
|
||||
use Symfony\Component\Validator\Mapping\ClassMetadata;
|
||||
use Symfony\Component\Validator\Constraints as Assert;
|
||||
use JMS\Serializer\Annotation as Serializer;
|
||||
|
||||
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 integer
|
||||
*
|
||||
* @Serializer\Groups({"request", "calculate"})
|
||||
* @Serializer\SerializedName("width")
|
||||
* @Serializer\Type("integer")
|
||||
*/
|
||||
public $width;
|
||||
|
||||
/**
|
||||
* Длина мм.
|
||||
* @var integer
|
||||
*
|
||||
* @Serializer\Groups({"request", "calculate"})
|
||||
* @Serializer\SerializedName("length")
|
||||
* @Serializer\Type("integer")
|
||||
*/
|
||||
public $length;
|
||||
|
||||
/**
|
||||
* Высота мм.
|
||||
* @var integer
|
||||
*
|
||||
* @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 (!is_null($this->length)
|
||||
&& !is_null($this->width)
|
||||
&& !is_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());
|
||||
}
|
||||
}
|
72
Model/PackageItem.php
Normal file
72
Model/PackageItem.php
Normal file
|
@ -0,0 +1,72 @@
|
|||
<?php
|
||||
|
||||
namespace RetailCrm\DeliveryModuleBundle\Model;
|
||||
|
||||
use Symfony\Component\Validator\Mapping\ClassMetadata;
|
||||
use Symfony\Component\Validator\Constraints as Assert;
|
||||
use JMS\Serializer\Annotation as Serializer;
|
||||
|
||||
use Intaro\CRMDeliveryBundle\Delivery\Generic\Generic;
|
||||
|
||||
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 string
|
||||
*
|
||||
* @Serializer\Groups({"get"})
|
||||
* @Serializer\SerializedName("quantity")
|
||||
* @Serializer\Type("float")
|
||||
*/
|
||||
public $quantity;
|
||||
|
||||
/**
|
||||
* Свойства товара
|
||||
* @var string
|
||||
*
|
||||
* @Serializer\Groups({"get"})
|
||||
* @Serializer\SerializedName("properties")
|
||||
* @Serializer\Type("array<string, array>")
|
||||
*/
|
||||
public $properties;
|
||||
}
|
34
Model/Plate.php
Normal file
34
Model/Plate.php
Normal file
|
@ -0,0 +1,34 @@
|
|||
<?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;
|
||||
}
|
||||
}
|
117
Model/RequestCalculate.php
Normal file
117
Model/RequestCalculate.php
Normal file
|
@ -0,0 +1,117 @@
|
|||
<?php
|
||||
|
||||
namespace RetailCrm\DeliveryModuleBundle\Model;
|
||||
|
||||
use Symfony\Component\Validator\Mapping\ClassMetadata;
|
||||
use Symfony\Component\Validator\Constraints as Assert;
|
||||
use JMS\Serializer\Annotation as Serializer;
|
||||
|
||||
use Intaro\CRMApiBundle\Validator\Constraints\DocSubEntity;
|
||||
use Intaro\CRMBundle\Entity\Model\DeliveryTime;
|
||||
use Intaro\CRMDeliveryBundle\Delivery\Generic\Generic;
|
||||
use RetailCrm\DeliveryModuleBundle\Model\Package;
|
||||
|
||||
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 $deliveryDate
|
||||
*
|
||||
* @Serializer\Groups({"request", "calculate"})
|
||||
* @Serializer\SerializedName("deliveryDate")
|
||||
* @Serializer\Type("DateTime<'Y-m-d'>")
|
||||
*/
|
||||
public $deliveryDate;
|
||||
|
||||
/**
|
||||
* Время доставки
|
||||
* @var DeliveryTime $deliveryTime
|
||||
*
|
||||
* @Serializer\Groups({"request", "calculate"})
|
||||
* @Serializer\SerializedName("deliveryTime")
|
||||
* @Serializer\Type("RetailCrm\DeliveryModuleBundle\Model\DeliveryTime")
|
||||
*/
|
||||
public $deliveryTime;
|
||||
|
||||
/**
|
||||
* Валюта
|
||||
* @var string $currency
|
||||
*
|
||||
* @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;
|
||||
}
|
17
Model/RequestDelete.php
Normal file
17
Model/RequestDelete.php
Normal file
|
@ -0,0 +1,17 @@
|
|||
<?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;
|
||||
}
|
26
Model/RequestPrint.php
Normal file
26
Model/RequestPrint.php
Normal file
|
@ -0,0 +1,26 @@
|
|||
<?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;
|
||||
}
|
144
Model/RequestSave.php
Normal file
144
Model/RequestSave.php
Normal file
|
@ -0,0 +1,144 @@
|
|||
<?php
|
||||
|
||||
namespace RetailCrm\DeliveryModuleBundle\Model;
|
||||
|
||||
use Symfony\Component\Validator\Mapping\ClassMetadata;
|
||||
use Symfony\Component\Validator\Constraints as Assert;
|
||||
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 $currency
|
||||
*
|
||||
* @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;
|
||||
}
|
||||
}
|
28
Model/RequestShipmentDelete.php
Normal file
28
Model/RequestShipmentDelete.php
Normal file
|
@ -0,0 +1,28 @@
|
|||
<?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;
|
||||
}
|
89
Model/RequestShipmentSave.php
Normal file
89
Model/RequestShipmentSave.php
Normal file
|
@ -0,0 +1,89 @@
|
|||
<?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;
|
||||
}
|
53
Model/RequestStatusUpdateItem.php
Normal file
53
Model/RequestStatusUpdateItem.php
Normal file
|
@ -0,0 +1,53 @@
|
|||
<?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 = [];
|
||||
}
|
||||
}
|
42
Model/ResponseAutocompleteItem.php
Normal file
42
Model/ResponseAutocompleteItem.php
Normal file
|
@ -0,0 +1,42 @@
|
|||
<?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;
|
||||
}
|
||||
}
|
26
Model/ResponseAutocompleteSuccessful.php
Normal file
26
Model/ResponseAutocompleteSuccessful.php
Normal file
|
@ -0,0 +1,26 @@
|
|||
<?php
|
||||
|
||||
namespace RetailCrm\DeliveryModuleBundle\Model;
|
||||
|
||||
use JMS\Serializer\Annotation as Serializer;
|
||||
|
||||
class ResponseAutocompleteSuccessful
|
||||
{
|
||||
/**
|
||||
* @var boolean
|
||||
*
|
||||
* @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;
|
||||
}
|
126
Model/ResponseCalculate.php
Normal file
126
Model/ResponseCalculate.php
Normal file
|
@ -0,0 +1,126 @@
|
|||
<?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 integer
|
||||
*
|
||||
* @Serializer\Groups({"response"})
|
||||
* @Serializer\SerializedName("minTerm")
|
||||
* @Serializer\Type("integer")
|
||||
*/
|
||||
public $minTerm;
|
||||
|
||||
/**
|
||||
* Максимальный срок доставки
|
||||
* @var integer
|
||||
*
|
||||
* @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 = [];
|
||||
}
|
||||
}
|
26
Model/ResponseCalculateSuccessful.php
Normal file
26
Model/ResponseCalculateSuccessful.php
Normal file
|
@ -0,0 +1,26 @@
|
|||
<?php
|
||||
|
||||
namespace RetailCrm\DeliveryModuleBundle\Model;
|
||||
|
||||
use JMS\Serializer\Annotation as Serializer;
|
||||
|
||||
class ResponseCalculateSuccessful
|
||||
{
|
||||
/**
|
||||
* @var boolean
|
||||
*
|
||||
* @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;
|
||||
}
|
138
Model/ResponseLoadDeliveryData.php
Normal file
138
Model/ResponseLoadDeliveryData.php
Normal file
|
@ -0,0 +1,138 @@
|
|||
<?php
|
||||
|
||||
namespace RetailCrm\DeliveryModuleBundle\Model;
|
||||
|
||||
use Symfony\Component\Validator\Mapping\ClassMetadata;
|
||||
use Symfony\Component\Validator\Constraints as Assert;
|
||||
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 = [];
|
||||
}
|
||||
}
|
7
Model/ResponseResult.php
Normal file
7
Model/ResponseResult.php
Normal file
|
@ -0,0 +1,7 @@
|
|||
<?php
|
||||
|
||||
namespace RetailCrm\DeliveryModuleBundle\Model;
|
||||
|
||||
class ResponseResult
|
||||
{
|
||||
}
|
70
Model/ResponseSave.php
Normal file
70
Model/ResponseSave.php
Normal file
|
@ -0,0 +1,70 @@
|
|||
<?php
|
||||
|
||||
namespace RetailCrm\DeliveryModuleBundle\Model;
|
||||
|
||||
use Symfony\Component\Validator\Mapping\ClassMetadata;
|
||||
use Symfony\Component\Validator\Constraints as Assert;
|
||||
use JMS\Serializer\Annotation as Serializer;
|
||||
|
||||
use Intaro\CRMDeliveryBundle\Delivery\Generic\Generic;
|
||||
|
||||
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 = [];
|
||||
}
|
||||
}
|
36
Model/ResponseShipmentSave.php
Normal file
36
Model/ResponseShipmentSave.php
Normal file
|
@ -0,0 +1,36 @@
|
|||
<?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());
|
||||
}
|
||||
}
|
26
Model/ResponseSuccessful.php
Normal file
26
Model/ResponseSuccessful.php
Normal file
|
@ -0,0 +1,26 @@
|
|||
<?php
|
||||
|
||||
namespace RetailCrm\DeliveryModuleBundle\Model;
|
||||
|
||||
use JMS\Serializer\Annotation as Serializer;
|
||||
|
||||
class ResponseSuccessful
|
||||
{
|
||||
/**
|
||||
* @var boolean
|
||||
*
|
||||
* @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;
|
||||
}
|
122
Model/SaveDeliveryData.php
Normal file
122
Model/SaveDeliveryData.php
Normal file
|
@ -0,0 +1,122 @@
|
|||
<?php
|
||||
|
||||
namespace RetailCrm\DeliveryModuleBundle\Model;
|
||||
|
||||
use Symfony\Component\Validator\Mapping\ClassMetadata;
|
||||
use Symfony\Component\Validator\Constraints as Assert;
|
||||
use JMS\Serializer\Annotation as Serializer;
|
||||
|
||||
class SaveDeliveryData
|
||||
{
|
||||
use Traits\ExtraDataTrait;
|
||||
|
||||
/**
|
||||
* Адрес отгрузки
|
||||
* @var DeliveryAddress
|
||||
*
|
||||
* @Serializer\Groups({"get"})
|
||||
* @Serializer\SerializedName("shipmentAddress")
|
||||
* @Serializer\Type("RetailCrm\DeliveryModuleBundle\Model\DeliveryAddress")
|
||||
*/
|
||||
public $shipmentAddress;
|
||||
|
||||
/**
|
||||
* Адрес доставки
|
||||
* @var DeliveryAddress
|
||||
*
|
||||
* @Serializer\Groups({"get"})
|
||||
* @Serializer\SerializedName("deliveryAddress")
|
||||
* @Serializer\Type("RetailCrm\DeliveryModuleBundle\Model\DeliveryAddress")
|
||||
*/
|
||||
public $deliveryAddress;
|
||||
|
||||
/**
|
||||
* Доставка наложенным платежом
|
||||
* @var boolean
|
||||
*
|
||||
* @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 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 Intaro\CRMBundle\Entity\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;
|
||||
}
|
29
Model/ShipmentOrder.php
Normal file
29
Model/ShipmentOrder.php
Normal file
|
@ -0,0 +1,29 @@
|
|||
<?php
|
||||
|
||||
namespace RetailCrm\DeliveryModuleBundle\Model;
|
||||
|
||||
use Intaro\CRMDeliveryBundle\Entity\GenericData;
|
||||
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;
|
||||
}
|
45
Model/Status.php
Normal file
45
Model/Status.php
Normal file
|
@ -0,0 +1,45 @@
|
|||
<?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;
|
||||
}
|
||||
}
|
38
Model/StatusInfo.php
Normal file
38
Model/StatusInfo.php
Normal file
|
@ -0,0 +1,38 @@
|
|||
<?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;
|
||||
}
|
78
Model/Terminal.php
Normal file
78
Model/Terminal.php
Normal file
|
@ -0,0 +1,78 @@
|
|||
<?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({"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;
|
||||
}
|
15
Model/Traits/ExtraDataTrait.php
Normal file
15
Model/Traits/ExtraDataTrait.php
Normal file
|
@ -0,0 +1,15 @@
|
|||
<?php
|
||||
|
||||
namespace RetailCrm\DeliveryModuleBundle\Model\Traits;
|
||||
|
||||
trait ExtraDataTrait
|
||||
{
|
||||
public function getExtraData($fieldCode)
|
||||
{
|
||||
if (!isset($this->extraData[$fieldCode])) {
|
||||
return null;
|
||||
} else {
|
||||
return $this->extraData[$fieldCode];
|
||||
}
|
||||
}
|
||||
}
|
0
README.md
Normal file
0
README.md
Normal file
80
Resources/config/routing.yml
Normal file
80
Resources/config/routing.yml
Normal file
|
@ -0,0 +1,80 @@
|
|||
retailcrm_delivery_module_connect:
|
||||
path: /{_locale}/connect
|
||||
defaults: { _controller: :Admin:connect }
|
||||
requirements:
|
||||
_locale: en|ru
|
||||
|
||||
retailcrm_delivery_module_connect_edit:
|
||||
path: /{_locale}/connect/{clientId}/edit
|
||||
defaults: { _controller: :Admin:connect }
|
||||
requirements:
|
||||
_locale: en|ru
|
||||
|
||||
############
|
||||
# Admin
|
||||
############
|
||||
retailcrm_delivery_module_admin_list:
|
||||
path: /omega
|
||||
defaults: { _controller: :Admin:list }
|
||||
|
||||
retailcrm_delivery_module_admin_new:
|
||||
path: /omega/new
|
||||
defaults: { _controller: :Admin:new }
|
||||
|
||||
retailcrm_delivery_module_admin_edit:
|
||||
path: /omega/{connectionId}/edit
|
||||
defaults: { _controller: :Admin:edit }
|
||||
requirements:
|
||||
connectionId: \d+
|
||||
|
||||
retailcrm_delivery_module_admin_update_configuration:
|
||||
path: /omega/{connectionId}/update-configuration
|
||||
defaults: { _controller: :Admin:updateConfiguration }
|
||||
requirements:
|
||||
connectionId: \d+
|
||||
|
||||
retailcrm_delivery_module_admin_parcel_list:
|
||||
path: /omega/parcels
|
||||
defaults: { _controller: :Admin:parcelList }
|
||||
|
||||
retailcrm_delivery_module_admin_parcel_new:
|
||||
path: /omega/parcels/new
|
||||
defaults: { _controller: :Admin:parcelNew }
|
||||
|
||||
retailcrm_delivery_module_admin_parcel_edit:
|
||||
path: /omega/parcels/{parcelId}/edit
|
||||
defaults: { _controller: :Admin:parcelEdit }
|
||||
requirements:
|
||||
parcelId: \d+
|
||||
|
||||
|
||||
#############
|
||||
# Exchange
|
||||
############
|
||||
retailcrm_delivery_module_exchange_base:
|
||||
path: /api
|
||||
defaults: { _controller: DeliveryModuleBundle/Controller/Api:index }
|
||||
|
||||
retailcrm_delivery_module_exchange_activity:
|
||||
path: /api/activity
|
||||
defaults: { _controller: DeliveryModuleBundle/Controller/Api:activity }
|
||||
|
||||
retailcrm_delivery_module_exchange_calculate:
|
||||
path: /api/calculate
|
||||
defaults: { _controller: DeliveryModuleBundle/Controller/Api:calculate }
|
||||
|
||||
retailcrm_delivery_module_exchange_save:
|
||||
path: /api/save
|
||||
defaults: { _controller: DeliveryModuleBundle/Controller/Api:save }
|
||||
|
||||
retailcrm_delivery_module_exchange_print:
|
||||
path: /api/print
|
||||
defaults: { _controller: DeliveryModuleBundle/Controller/Api:print }
|
||||
|
||||
retailcrm_delivery_module_exchange_shipment_save:
|
||||
path: /api/shipment-save
|
||||
defaults: { _controller: DeliveryModuleBundle/Controller/Api:shipmentSave }
|
||||
|
||||
retailcrm_delivery_module_exchange_shipment_delete:
|
||||
path: /api/shipment-delete
|
||||
defaults: { _controller: DeliveryModuleBundle/Controller/Api:shipmentDelete }
|
40
Resources/config/services.yml
Normal file
40
Resources/config/services.yml
Normal file
|
@ -0,0 +1,40 @@
|
|||
|
||||
services:
|
||||
RetailCrm\DeliveryModuleBundle\Service\ModuleManager:
|
||||
public: true
|
||||
class: "%retailcrm.delivery_module.module_manager.class%"
|
||||
arguments:
|
||||
- "%retailcrm.delivery_module.module_configuration%"
|
||||
- "@RetailCrm\DeliveryModuleBundle\Service\DeliveryOrderManager"
|
||||
- "@jms_serializer"
|
||||
- "@translator"
|
||||
- "@router"
|
||||
|
||||
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
|
||||
arguments:
|
||||
- "@doctrine.orm.entity_manager"
|
||||
- "RetailCrm\DeliveryModuleBundle\Service\ModuleManager"
|
||||
tags: ['console.command']
|
||||
|
||||
RetailCrm\DeliveryModuleBundle\Command\UpdateModuleConfigurationCommand:
|
||||
class: RetailCrm\DeliveryModuleBundle\Command\UpdateModuleConfigurationCommand
|
||||
arguments:
|
||||
- "@doctrine.orm.entity_manager"
|
||||
- "RetailCrm\DeliveryModuleBundle\Service\ModuleManager"
|
||||
tags: ['console.command']
|
||||
|
||||
RetailCrm\DeliveryModuleBundle\Controller\:
|
||||
resource: '../../Controller'
|
||||
public: true
|
||||
tags: ['controller.service_arguments']
|
||||
|
||||
RetailCrm\DeliveryModuleBundle\EventListener\SerializeListener:
|
||||
tags:
|
||||
- { name: jms_serializer.event_subscriber }
|
67
Resources/translations/messages.en.yml
Normal file
67
Resources/translations/messages.en.yml
Normal file
|
@ -0,0 +1,67 @@
|
|||
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
|
67
Resources/translations/messages.es.yml
Normal file
67
Resources/translations/messages.es.yml
Normal file
|
@ -0,0 +1,67 @@
|
|||
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
|
67
Resources/translations/messages.ru.yml
Normal file
67
Resources/translations/messages.ru.yml
Normal file
|
@ -0,0 +1,67 @@
|
|||
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: элементов
|
68
Resources/views/Connection/configure.html.twig
Normal file
68
Resources/views/Connection/configure.html.twig
Normal file
|
@ -0,0 +1,68 @@
|
|||
{% form_theme form 'DeliveryCoreBundle:Form:configure.html.twig' %}
|
||||
|
||||
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
|
||||
<html xmlns="http://www.w3.org/1999/xhtml">
|
||||
<head>
|
||||
<meta http-equiv="Content-Type" content="text/html; charset=utf-8" />
|
||||
<title>
|
||||
{% block title %}{% endblock %}
|
||||
</title>
|
||||
<link rel="stylesheet" href="{{ asset('bundles/coreautomate/css/connect.css') }}" />
|
||||
<link rel="shortcut icon" href="{{ asset('favicon.ico') }}" type="image/x-icon">
|
||||
</head>
|
||||
|
||||
<body>
|
||||
<div class="wrapper" style="width:100%;">
|
||||
<div class="top">
|
||||
<div class="header">
|
||||
<div>
|
||||
{% block logo %}{% endblock %}
|
||||
</div>
|
||||
</div>
|
||||
<div class="blue_line"></div>
|
||||
</div>
|
||||
<div class="content">
|
||||
<div class="form-style-5">
|
||||
{% block form %}
|
||||
<div style="text-align: justify; margin-bottom: 10px;">
|
||||
{{ form_errors(form) }}
|
||||
</div>
|
||||
|
||||
<form name="connection" method="post" {{ form.vars.data.clientId is not empty ? ('action="' ~ path(route ~ '_configure_edit', {'clientId': form.vars.data.clientId}) ~ '"')|raw }} >
|
||||
{{ form_start(form) }}
|
||||
|
||||
{% block form_delivery %}
|
||||
{% endblock %}
|
||||
|
||||
<fieldset>
|
||||
<legend class="header_form_text">{{ 'header.configureConnection'|trans }}</legend>
|
||||
{{ form_widget(form.crmUrl, {'attr': {'value': account}}) }}
|
||||
{{ form_errors(form.crmUrl) }}
|
||||
|
||||
{{ form_widget(form.crmKey) }}
|
||||
{{ form_errors(form.crmKey) }}
|
||||
|
||||
{{ form_widget(form.language) }}
|
||||
{{ form_errors(form.language) }}
|
||||
</fieldset>
|
||||
|
||||
{% block form_delivery_after %}
|
||||
{% endblock %}
|
||||
|
||||
<div style="display: none">
|
||||
{{ form_rest(form) }}
|
||||
</div>
|
||||
<input type="submit" value="{{ (form.vars.data.clientId is not empty ? 'button.save' : 'button.activate')|trans }}" />
|
||||
|
||||
{{ form_end(form) }}
|
||||
{% endblock %}
|
||||
|
||||
</div>
|
||||
</div>
|
||||
<div class="footer">
|
||||
|
||||
</div>
|
||||
</div>
|
||||
</body>
|
||||
</html>
|
||||
|
13
Resources/views/Connection/configure_error.html.twig
Normal file
13
Resources/views/Connection/configure_error.html.twig
Normal file
|
@ -0,0 +1,13 @@
|
|||
{% extends 'CoreAutomateBundle:Layout:connect.html.twig' %}
|
||||
|
||||
{% block title %}
|
||||
{{ 'header.serviceConnect'|trans({'%delivery%': title_delivery})|raw }}
|
||||
{% endblock %}
|
||||
|
||||
{% block logo %}
|
||||
<img style="height: 60px" src="{{ src_logo_delivery }}" alt="{{ title_delivery }}">
|
||||
{% endblock %}
|
||||
|
||||
{% block form %}
|
||||
{{ 'error.connect.failed'|trans({'%delivery%': title_delivery, '%href%': referer})|raw }}
|
||||
{% endblock %}
|
60
Resources/views/Connection/edit.html.twig
Normal file
60
Resources/views/Connection/edit.html.twig
Normal file
|
@ -0,0 +1,60 @@
|
|||
{% extends 'CoreOmegaBundle:Layout:base.html.twig' %}
|
||||
{% form_theme form 'DeliveryCoreBundle:Form:admin.html.twig' %}
|
||||
|
||||
{% block content %}
|
||||
<div class="header-main">
|
||||
<h1 style="margin: 10px 0 10px 0;">
|
||||
{% if connection is defined %}
|
||||
{{ 'header.adminConnectionEdit'|trans({'%uid%': '<a target="_blank" href="'~connection.crmUrl~'">'~connection.crmUrl~'</a>'})|raw }}
|
||||
{% else %}
|
||||
{{ 'header.adminConnectionCreate'|trans()|raw }}
|
||||
{% endif %}
|
||||
</h1>
|
||||
</div>
|
||||
|
||||
<div class="main">
|
||||
<div class="m-box mn-or-info">
|
||||
{{ form_start(form) }}
|
||||
{{ form_errors(form) }}
|
||||
|
||||
<div class="field-for-group cleared">
|
||||
{{ form_row(form.crmUrl) }}
|
||||
{{ form_row(form.crmKey) }}
|
||||
|
||||
{{ form_row(form.isActive) }}
|
||||
|
||||
{% if form.language is defined %}
|
||||
{{ form_row(form.language) }}
|
||||
{% endif %}
|
||||
|
||||
{{ form_row(form.isFreeze) }}
|
||||
</div>
|
||||
|
||||
{% block form_appendix %}
|
||||
{% endblock %}
|
||||
|
||||
<div class="field-for-group cleared">
|
||||
{{ form_row(form.debug) }}
|
||||
</div>
|
||||
|
||||
<div class="field-for-group cleared">
|
||||
<div class="input-group cleared">
|
||||
<input type="submit" name="submit" value="{{ 'button.save'|trans()|raw }}" class="btn small btn-save"/>
|
||||
</div>
|
||||
{% if is_granted('ROLE_DEVELOPER') %}
|
||||
{% if connection is defined %}
|
||||
<div class="input-group cleared">
|
||||
<a href="{{ path(route ~ '_admin_update_configuration', {'connectionId': connection.id}) }}" class="btn small btn-save">
|
||||
{{ 'button.updateConfiguration'|trans()|raw }}
|
||||
</a>
|
||||
</div>
|
||||
{% endif %}
|
||||
{% endif %}
|
||||
</div>
|
||||
|
||||
{{ form_end(form) }}
|
||||
</div>
|
||||
|
||||
<div id="push"></div>
|
||||
</div>
|
||||
{% endblock %}
|
61
Resources/views/Connection/list.html.twig
Normal file
61
Resources/views/Connection/list.html.twig
Normal file
|
@ -0,0 +1,61 @@
|
|||
{% extends 'CoreOmegaBundle:Layout:base.html.twig' %}
|
||||
|
||||
{% block content %}
|
||||
<div class="header-main">
|
||||
<h1 style="margin: 10px 0 10px 0;">{{ 'header.listConnection'|trans()|raw }}</h1>
|
||||
</div>
|
||||
|
||||
<div class="main">
|
||||
<div style="margin: 5px 0 15px 0;">
|
||||
{% if is_granted('ROLE_DEVELOPER') %}
|
||||
<a href="{{ path(route ~ '_admin_new') }}" class="btn small btn-save">
|
||||
{{ 'button.add'|trans()|raw }}
|
||||
</a>
|
||||
{% endif %}
|
||||
<a href="{{ path(route ~ '_admin_parcel_list') }}" class="btn small btn-save">
|
||||
{{ 'button.listTracking'|trans()|raw }}
|
||||
</a>
|
||||
</div>
|
||||
|
||||
<table class="modern-table">
|
||||
<tr>
|
||||
<th style="text-align: left">{{ 'label.id'|trans()|raw }}</th>
|
||||
<th>{{ 'label.crmUrl'|trans()|raw }}</th>
|
||||
<th style="text-align: center">{{ 'label.isActive'|trans()|raw }}</th>
|
||||
</tr>
|
||||
{% for client in pagination %}
|
||||
<tr>
|
||||
<td style="text-align: left">
|
||||
<a href="{{ path(route ~ '_admin_edit', {'connectionId': client.id}) }}">{{ client.clientId }}</a>
|
||||
</td>
|
||||
<td>
|
||||
{% if client.crmUrl is not empty %}
|
||||
<a target="_blank" href="{{ client.crmUrl }}">
|
||||
{{ client.crmUrl }}
|
||||
</a>
|
||||
{% endif %}
|
||||
</td>
|
||||
<td style="text-align: center">
|
||||
{% if client.isActive %}
|
||||
<img src="{{ asset('bundles/coreomega/images/mark-yes.svg') }}" style="width: 20px; height: 20px;"/>
|
||||
{% else %}
|
||||
<img src="{{ asset('bundles/coreomega/images/mark-no.svg') }}" style="width: 20px; height: 20px;" />
|
||||
{% endif %}
|
||||
</td>
|
||||
</tr>
|
||||
{% endfor %}
|
||||
</table>
|
||||
|
||||
<div class="list-bottom">
|
||||
<div class="list-total-stripe">
|
||||
<span id="list-total-count">
|
||||
{{ pagination.getTotalItemCount }} <span>{{ 'pagination.items.name'|trans()|raw }}</span>
|
||||
</span>
|
||||
</div>
|
||||
<div class="paginator">
|
||||
{{ knp_pagination_render(pagination) }}
|
||||
</div>
|
||||
</div>
|
||||
<div id="push"></div>
|
||||
</div>
|
||||
{% endblock %}
|
18
Resources/views/Form/admin.html.twig
Normal file
18
Resources/views/Form/admin.html.twig
Normal file
|
@ -0,0 +1,18 @@
|
|||
{% extends "form_div_layout.html.twig" %}
|
||||
|
||||
{% block form_row %}
|
||||
{% spaceless %}
|
||||
<div class="input-group cleared">
|
||||
{{ form_label(form, null, {'label_attr' : {'class': 'label-common'}}) }}
|
||||
{{ form_errors(form) }}
|
||||
|
||||
{% if not attr or not attr.class|default(null) %}
|
||||
{% set attr = attr|default({})|merge({
|
||||
'class': 'input-field',
|
||||
'style': 'max-width: 320px;'
|
||||
}) %}
|
||||
{% endif %}
|
||||
{{ form_widget(form, { 'attr': attr }) }}
|
||||
</div>
|
||||
{% endspaceless %}
|
||||
{% endblock form_row %}
|
13
Resources/views/Form/configure.html.twig
Normal file
13
Resources/views/Form/configure.html.twig
Normal file
|
@ -0,0 +1,13 @@
|
|||
{% extends "form_div_layout.html.twig" %}
|
||||
|
||||
{% block form_errors %}
|
||||
{% spaceless %}
|
||||
{% if errors|length > 0 %}
|
||||
{% for error in errors %}
|
||||
<div class="form_error_message">
|
||||
<span style="color: #ff0000;">{{ error.message }}</span>
|
||||
</div>
|
||||
{% endfor %}
|
||||
{% endif %}
|
||||
{% endspaceless %}
|
||||
{% endblock form_errors %}
|
61
Resources/views/Parcel/edit.html.twig
Normal file
61
Resources/views/Parcel/edit.html.twig
Normal file
|
@ -0,0 +1,61 @@
|
|||
{% extends 'CoreOmegaBundle:Layout:base.html.twig' %}
|
||||
|
||||
{% block content %}
|
||||
<div class="header-main">
|
||||
<h1 style="margin: 10px 0 10px 0;">
|
||||
{% if parcel.id is not empty %}
|
||||
{{ 'header.adminParcelEdit' |trans({'%trackId%': parcel.trackId})|raw }}
|
||||
{% else %}
|
||||
{{ 'header.adminParcelCreate' |trans()|raw }}
|
||||
{% endif %}
|
||||
</h1>
|
||||
</div>
|
||||
|
||||
<div class="main">
|
||||
<div class="m-box mn-or-info">
|
||||
{{ form_start(form) }}
|
||||
{{ form_errors(form) }}
|
||||
|
||||
<div class="field-for-group cleared">
|
||||
<div class="input-group cleared">
|
||||
{{ form_label(form.connection, null, {'label_attr' : {'class': 'label-common'}}) }}
|
||||
{{ form_errors(form.connection) }}
|
||||
{{ form_widget(form.connection, {'attr': {'class': 'input-field', 'style': 'width: 320px;'}}) }}
|
||||
</div>
|
||||
|
||||
<div class="input-group cleared">
|
||||
{{ form_label(form.orderId, null, {'label_attr' : {'class': 'label-common'}}) }}
|
||||
{{ form_errors(form.orderId) }}
|
||||
{{ form_widget(form.orderId, {'attr': {'class': 'input-field', 'style': 'width: 320px;'}}) }}
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="field-for-group cleared">
|
||||
<div class="input-group cleared">
|
||||
{{ form_label(form.trackId, null, {'label_attr' : {'class': 'label-common'}}) }}
|
||||
{{ form_errors(form.trackId) }}
|
||||
{{ form_widget(form.trackId, {'attr': {'class': 'input-field', 'style': 'width: 320px;'}}) }}
|
||||
</div>
|
||||
|
||||
<div class="input-group cleared">
|
||||
{{ form_label(form.isClosed, null, {'label_attr' : {'class': 'label-common'}}) }}
|
||||
{{ form_errors(form.isClosed) }}
|
||||
{{ form_widget(form.isClosed) }}
|
||||
</div>
|
||||
</div>
|
||||
|
||||
{% block form_appendix %}
|
||||
{% endblock %}
|
||||
|
||||
<div class="field-for-group cleared">
|
||||
<div class="input-group cleared">
|
||||
<input type="submit" name="submit" value="{{ 'button.save' |trans()|raw }}" class="btn small btn-save"/>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
{{ form_end(form) }}
|
||||
</div>
|
||||
|
||||
<div id="push"></div>
|
||||
</div>
|
||||
{% endblock%}
|
60
Resources/views/Parcel/list.html.twig
Normal file
60
Resources/views/Parcel/list.html.twig
Normal file
|
@ -0,0 +1,60 @@
|
|||
{% extends 'CoreOmegaBundle:Layout:base.html.twig' %}
|
||||
|
||||
{% block content %}
|
||||
<div class="header-main">
|
||||
<h1 style="margin: 10px 0 10px 0;">{{ 'header.listConnection'|trans()|raw }}</h1>
|
||||
</div>
|
||||
|
||||
<div class="main">
|
||||
<div style="margin: 5px 0 15px 0;">
|
||||
<a href="{{ path(route ~ '_admin_list') }}" class="btn small btn-save">
|
||||
{{ 'button.listConnection'|trans()|raw }}
|
||||
</a>
|
||||
{% if is_granted('ROLE_DEVELOPER') %}
|
||||
<a href="{{ path(route ~ '_admin_parcel_new') }}" class="btn small btn-save">
|
||||
{{ 'button.addTracking'|trans()|raw }}
|
||||
</a>
|
||||
{% endif %}
|
||||
</div>
|
||||
<table class="modern-table">
|
||||
<tr>
|
||||
<th style="text-align: left">{{ 'label.trackId'|trans()|raw }}</th>
|
||||
<th style="text-align: left">{{ 'label.orderId'|trans()|raw }}</th>
|
||||
<th style="text-align: left">{{ 'label.connection'|trans()|raw }}</th>
|
||||
<th style="text-align: center">{{ 'label.isClosed'|trans()|raw }}</th>
|
||||
</tr>
|
||||
{% for track in pagination %}
|
||||
<tr>
|
||||
<td style="text-align: left">
|
||||
<a href="{{ path(route ~ '_admin_parcel_edit', {'parcelId': track.id}) }}">{{ track.trackId}}</a>
|
||||
</td>
|
||||
<td style="text-align: left">
|
||||
{{ track.orderId}}
|
||||
</td>
|
||||
<td style="text-align: left">
|
||||
<a href="{{ path(route ~ '_admin_edit', {'connectionId': track.connection.id}) }}">{{ track.clientId}}</a>
|
||||
</td>
|
||||
<td style="text-align: center">
|
||||
{% if track.isClosed %}
|
||||
<img src="{{ asset('bundles/coreomega/images/mark-yes.svg') }}" style="width: 20px; height: 20px;"/>
|
||||
{% else %}
|
||||
<img src="{{ asset('bundles/coreomega/images/mark-no.svg') }}" style="width: 20px; height: 20px;" />
|
||||
{% endif %}
|
||||
</td>
|
||||
</tr>
|
||||
{% endfor %}
|
||||
</table>
|
||||
|
||||
<div class="list-bottom">
|
||||
<div class="list-total-stripe">
|
||||
<span id="list-total-count">
|
||||
{{ pagination.getTotalItemCount }} <span>{{ 'pagination.items.name'|trans()|raw }}</span>
|
||||
</span>
|
||||
</div>
|
||||
<div class="paginator">
|
||||
{{ knp_pagination_render(pagination) }}
|
||||
</div>
|
||||
</div>
|
||||
<div id="push"></div>
|
||||
</div>
|
||||
{% endblock%}
|
50
Service/DeliveryOrderManager.php
Normal file
50
Service/DeliveryOrderManager.php
Normal file
|
@ -0,0 +1,50 @@
|
|||
<?php
|
||||
|
||||
namespace RetailCrm\DeliveryModuleBundle\Service;
|
||||
|
||||
use Doctrine\Persistence\ObjectManager;
|
||||
use Doctrine\Persistence\ObjectRepository;
|
||||
use RetailCrm\DeliveryModuleBundle\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->getRepository()->getClassName();
|
||||
}
|
||||
|
||||
public function create(): DeliveryOrder
|
||||
{
|
||||
$class = $this->getClass();
|
||||
|
||||
return new $class();
|
||||
}
|
||||
|
||||
public function findBy(array $criteria): array
|
||||
{
|
||||
return $this->getRepository()->findBy($criteria);
|
||||
}
|
||||
|
||||
public function findOneBy(array $criteria): ?DeliveryOrder
|
||||
{
|
||||
return $this->getRepository()->findOneBy($criteria);
|
||||
}
|
||||
|
||||
public function flush(): void
|
||||
{
|
||||
$this->entityManager->flush();
|
||||
}
|
||||
|
||||
public function getRepository(): ObjectRepository
|
||||
{
|
||||
return $this->entityManager->getRepository($this->class);
|
||||
}
|
||||
}
|
348
Service/ModuleManager.php
Normal file
348
Service/ModuleManager.php
Normal file
|
@ -0,0 +1,348 @@
|
|||
<?php
|
||||
|
||||
namespace RetailCrm\DeliveryModuleBundle\Service;
|
||||
|
||||
use JMS\Serializer\SerializationContext;
|
||||
use JMS\Serializer\SerializerInterface;
|
||||
use Psr\Log\LoggerInterface;
|
||||
use RetailCrm\ApiClient;
|
||||
use RetailCrm\DeliveryModuleBundle\Entity\Account;
|
||||
use RetailCrm\DeliveryModuleBundle\Entity\DeliveryOrder;
|
||||
use RetailCrm\DeliveryModuleBundle\Model\Configuration;
|
||||
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\RequestShipmentSave;
|
||||
use RetailCrm\DeliveryModuleBundle\Model\ResponseCalculate;
|
||||
use RetailCrm\DeliveryModuleBundle\Model\ResponseSave;
|
||||
use RetailCrm\DeliveryModuleBundle\Model\ResponseShipmentSave;
|
||||
use Symfony\Component\Routing\Generator\UrlGeneratorInterface;
|
||||
use Symfony\Component\Translation\TranslatorInterface;
|
||||
|
||||
abstract class ModuleManager
|
||||
{
|
||||
const STATUS_UPDATE_LIMIT = 100;
|
||||
|
||||
/**
|
||||
* @var string
|
||||
*/
|
||||
protected $integrationCode;
|
||||
|
||||
/**
|
||||
* @var array
|
||||
*/
|
||||
private $config;
|
||||
|
||||
/**
|
||||
* @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 $moduleConfig,
|
||||
DeliveryOrderManager $deliveryManager,
|
||||
SerializerInterface $jmsSerializer,
|
||||
TranslatorInterface $translator,
|
||||
UrlGeneratorInterface $router,
|
||||
PinbaService $pinbaService
|
||||
) {
|
||||
$this->integrationCode = $moduleConfig['integrationCode'];
|
||||
$this->config = $moduleConfig;
|
||||
$this->deliveryManager = $deliveryManager;
|
||||
$this->jmsSerializer = $jmsSerializer;
|
||||
$this->translator = $translator;
|
||||
$this->router = $router;
|
||||
$this->pinbaService = $pinbaService;
|
||||
}
|
||||
|
||||
public function getModuleCode(): string
|
||||
{
|
||||
if (null === $this->account) {
|
||||
throw new \LogicException('Account is not selected');
|
||||
}
|
||||
|
||||
return sprintf('%s-%s', $this->integrationCode, $this->account->getId());
|
||||
}
|
||||
|
||||
public function setLogger(?LoggerInterface $logger): self
|
||||
{
|
||||
$this->logger = $logger;
|
||||
|
||||
return $this;
|
||||
}
|
||||
|
||||
public function getAccount(): ?Account
|
||||
{
|
||||
return $this->account;
|
||||
}
|
||||
|
||||
public function setAccount(Account $account): self
|
||||
{
|
||||
$this->account = $account;
|
||||
|
||||
if ($this->account && $this->account->getLanguage() && $this->translator) {
|
||||
$this->translator->setLocale($this->account->getLanguage());
|
||||
}
|
||||
|
||||
$this->createRetailCrmClient();
|
||||
|
||||
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']));
|
||||
|
||||
$response = $this->pinbaService->timerHandler(
|
||||
[
|
||||
'api' => 'retailCrm',
|
||||
'method' => 'integrationModulesEdit',
|
||||
],
|
||||
static function () use ($integrationModule) {
|
||||
return $this->retailCrmClient->request->integrationModulesEdit(
|
||||
json_decode($integrationModule, true)
|
||||
);
|
||||
}
|
||||
);
|
||||
|
||||
if ($result['success'] ?? false) {
|
||||
return true;
|
||||
} else {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
protected function buildIntegrationModule(): IntegrationModule
|
||||
{
|
||||
$integrationModule = new IntegrationModule();
|
||||
|
||||
$integrationModule->code = $this->getModuleCode();
|
||||
$integrationModule->integrationCode = $this->integrationCode;
|
||||
$integrationModule->active = $this->account->isActive();
|
||||
$integrationModule->name = $this->config['locales'][$this->translator->getLocale()]['name'];
|
||||
$integrationModule->logo = $this->config['locales'][$this->translator->getLocale()]['logo'];
|
||||
$integrationModule->clientId = $this->account->getId();
|
||||
$integrationModule->availableCountries = $this->config['countries'];
|
||||
$integrationModule->actions = [
|
||||
'activity' => 'activity',
|
||||
];
|
||||
|
||||
$integrationModule->baseUrl = $this->router->generate(
|
||||
'retailcrm_delivery_module_exchange_base',
|
||||
[],
|
||||
UrlGeneratorInterface::ABSOLUTE_URL
|
||||
);
|
||||
$integrationModule->accountUrl = $this->router->generate(
|
||||
'retailcrm_delivery_module_connect',
|
||||
['_locale' => $this->connection->getLanguage()],
|
||||
UrlGeneratorInterface::ABSOLUTE_URL
|
||||
);
|
||||
|
||||
$integrationModule->integrations['delivery'] = $this->doBuildDeliveryConfiguration();
|
||||
|
||||
return $integrationModule;
|
||||
}
|
||||
|
||||
abstract protected function doBuildConfiguration(): Configuration;
|
||||
|
||||
public function calculateDelivery(RequestCalculate $data): ResponseCalculate
|
||||
{
|
||||
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 deleteDelivery(RequestDelete $request, DeliveryOrder $delivery): bool
|
||||
{
|
||||
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 Exception\ApiException('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;
|
||||
}
|
||||
|
||||
/**
|
||||
* Получение актуальных статусов доставки от службы доставки
|
||||
*
|
||||
* @param \RetailCrm\DeliveryModuleBundle\Entity\Parcel[] $parces
|
||||
*
|
||||
* @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']));
|
||||
|
||||
$response = $this->pinbaService->timerHandler(
|
||||
[
|
||||
'api' => 'retailCrm',
|
||||
'method' => 'deliveryTracking',
|
||||
],
|
||||
static function () use ($request) {
|
||||
return $this->retailCrmClient->request->deliveryTracking(
|
||||
$this->getModuleCode(),
|
||||
json_decode($request, true)
|
||||
);
|
||||
}
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
private function createRetailCrmClient(): void
|
||||
{
|
||||
if (null === $this->account) {
|
||||
throw new \LogicException('Account is not selected');
|
||||
}
|
||||
|
||||
if (empty($this->account->getCrmUrl())) {
|
||||
throw new \LogicException('Crm url is empty');
|
||||
}
|
||||
|
||||
if (empty($this->account->getCrmApiKey())) {
|
||||
throw new \LogicException('Crm apiKey is empty');
|
||||
}
|
||||
|
||||
$this->retailCrmClient = new ApiClient(
|
||||
$this->account->getCrmUrl(),
|
||||
$this->account->getCrmApiKey(),
|
||||
ApiClient::V5
|
||||
);
|
||||
if ($this->logger) {
|
||||
$this->retailCrmClient->setLogger($this->logger);
|
||||
}
|
||||
}
|
||||
}
|
25
Service/PinbaService.php
Normal file
25
Service/PinbaService.php
Normal file
|
@ -0,0 +1,25 @@
|
|||
<?php
|
||||
|
||||
namespace RetailCrm\DeliveryModuleBundle\Service;
|
||||
|
||||
class PinbaService
|
||||
{
|
||||
/**
|
||||
* @param array $tags
|
||||
* @param \Closure $handler
|
||||
*
|
||||
* @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;
|
||||
}
|
||||
}
|
30
composer.json
Normal file
30
composer.json
Normal file
|
@ -0,0 +1,30 @@
|
|||
{
|
||||
"name": "retailcrm/delivery-module-bundle",
|
||||
"description": "Delivery module skeleton for RetailCrm",
|
||||
"license": "MIT",
|
||||
"type": "symfony-bundle",
|
||||
"autoload": {
|
||||
"psr-4": {
|
||||
"RetailCrm\\DeliveryModuleBundle\\": ""
|
||||
}
|
||||
},
|
||||
"require": {
|
||||
"php": "^7.3",
|
||||
"ramsey/uuid": "^3.9",
|
||||
"ramsey/uuid-doctrine": "^1.5",
|
||||
"symfony/framework-bundle": "^3.4|^4.0|^5.0",
|
||||
"jms/serializer": "^3.4",
|
||||
"jms/serializer-bundle": "^3.5",
|
||||
"doctrine/orm": "^2.7",
|
||||
"symfony/lock": "^5.0",
|
||||
"retailcrm/api-client-php": "dev-add-logger@dev",
|
||||
"symfony/translation": "^5.0",
|
||||
"symfony/routing": "^5.0"
|
||||
},
|
||||
"repositories": [
|
||||
{
|
||||
"type": "vcs",
|
||||
"url": "https://github.com/raulleo/api-client-php.git"
|
||||
}
|
||||
]
|
||||
}
|
4088
composer.lock
generated
Normal file
4088
composer.lock
generated
Normal file
File diff suppressed because it is too large
Load diff
28
docker-compose-test.yml
Normal file
28
docker-compose-test.yml
Normal file
|
@ -0,0 +1,28 @@
|
|||
version: '2.1'
|
||||
services:
|
||||
automate_app:
|
||||
image: "gwinn/php:7.1"
|
||||
working_dir: /automate
|
||||
user: ${UID:-1000}:${GID:-1000}
|
||||
volumes:
|
||||
- ./:/automate
|
||||
links:
|
||||
- "automate_db:automate_db"
|
||||
- "automate_cache:automate_cache"
|
||||
- "automate_queue:automate_queue"
|
||||
automate_db:
|
||||
image: "postgres:9.5"
|
||||
ports:
|
||||
- ${POSTGRES_ADDRESS:-127.0.0.1:5432}:5432
|
||||
environment:
|
||||
- POSTGRES_PASSWORD=automate
|
||||
- POSTGRES_USER=automate
|
||||
- POSTGRES_DB=automate
|
||||
automate_cache:
|
||||
image: "redis:alpine"
|
||||
ports:
|
||||
- "6379:6379"
|
||||
automate_queue:
|
||||
image: "schickling/beanstalkd:latest"
|
||||
ports:
|
||||
- "11300:11300"
|
46
docker-compose.yml
Normal file
46
docker-compose.yml
Normal file
|
@ -0,0 +1,46 @@
|
|||
version: '2.1'
|
||||
services:
|
||||
automate_app:
|
||||
image: "gwinn/php:7.1"
|
||||
ports:
|
||||
- "80:8080"
|
||||
working_dir: /automate
|
||||
user: ${UID:-1000}:${GID:-1000}
|
||||
volumes:
|
||||
- ./:/automate
|
||||
depends_on:
|
||||
- automate_db
|
||||
- automate_db_test
|
||||
- automate_cache
|
||||
- automate_queue
|
||||
links:
|
||||
- "automate_db:automate_db"
|
||||
- "automate_db_test:automate_db_test"
|
||||
- "automate_cache:automate_cache"
|
||||
- "automate_queue:automate_queue"
|
||||
command: make run
|
||||
automate_db:
|
||||
image: "postgres:9.5"
|
||||
ports:
|
||||
- ${POSTGRES_ADDRESS:-127.0.0.1:5432}:5432
|
||||
environment:
|
||||
- POSTGRES_PASSWORD=automate
|
||||
- POSTGRES_USER=automate
|
||||
- POSTGRES_DB=automate
|
||||
automate_db_test:
|
||||
image: "postgres:9.5"
|
||||
ports:
|
||||
- ${POSTGRES_ADDRESS:-127.0.0.1:5434}:5434
|
||||
environment:
|
||||
- PGPORT=5434
|
||||
- POSTGRES_PASSWORD=automate
|
||||
- POSTGRES_USER=automate
|
||||
- POSTGRES_DB=automate
|
||||
automate_cache:
|
||||
image: "redis:alpine"
|
||||
ports:
|
||||
- "6379:6379"
|
||||
automate_queue:
|
||||
image: "schickling/beanstalkd:latest"
|
||||
ports:
|
||||
- "11300:11300"
|
102
tests/Controller/AbstractExchangeControllerTest.php
Normal file
102
tests/Controller/AbstractExchangeControllerTest.php
Normal file
|
@ -0,0 +1,102 @@
|
|||
<?php
|
||||
|
||||
namespace RetailCrm\DeliveryModuleBundle\Tests\Controller;
|
||||
|
||||
use Core\AutomateBundle\Services\Proxy;
|
||||
use Doctrine\Common\Persistence\ObjectManager;
|
||||
use Symfony\Component\HttpFoundation\JsonResponse;
|
||||
use Symfony\Component\HttpFoundation\ParameterBag;
|
||||
use Symfony\Component\HttpFoundation\Request;
|
||||
use Symfony\Component\HttpFoundation\RequestStack;
|
||||
use Symfony\Bundle\FrameworkBundle\Test\WebTestCase;
|
||||
|
||||
abstract class AbstractExchangeControllerTest extends WebTestCase
|
||||
{
|
||||
public function setUp()
|
||||
{
|
||||
self::bootKernel();
|
||||
parent::setUp();
|
||||
}
|
||||
|
||||
/**
|
||||
* @return string
|
||||
*/
|
||||
abstract protected function getExchangeControllerClassName();
|
||||
|
||||
/**
|
||||
* @return \PHPUnit\Framework\MockObject\MockObject
|
||||
*/
|
||||
abstract protected function getServiceMock();
|
||||
|
||||
/**
|
||||
* @return array
|
||||
*/
|
||||
abstract protected function dataProviderMethods();
|
||||
|
||||
/**
|
||||
* @param string $method
|
||||
* @param string $type
|
||||
* @param string $dataKey
|
||||
* @param string $data
|
||||
* @param callable $assertions
|
||||
*
|
||||
* @dataProvider dataProviderMethods
|
||||
*/
|
||||
public function testExchangeControllerMethods(
|
||||
string $method,
|
||||
string $type,
|
||||
string $dataKey,
|
||||
string $data,
|
||||
callable $assertions
|
||||
) {
|
||||
self::bootKernel();
|
||||
$container = self::$kernel->getContainer();
|
||||
|
||||
$req = $this->createMock(Request::class);
|
||||
$req->$type = new ParameterBag([
|
||||
'clientId' => 'clientId',
|
||||
$dataKey => $data
|
||||
]);
|
||||
$req->expects($this->any())
|
||||
->method('isMethod')
|
||||
->with('post')
|
||||
->willReturn($type == 'request');
|
||||
|
||||
$reqStack = $this->createMock(RequestStack::class);
|
||||
$reqStack->expects($this->any())
|
||||
->method('getCurrentRequest')
|
||||
->willReturn($req);
|
||||
|
||||
$res = $this->getExchangeControllerMock($reqStack)->{$method.'Action'}($req);
|
||||
$content = json_decode($res->getContent(), true);
|
||||
|
||||
$assertions($res, $content);
|
||||
}
|
||||
|
||||
/**
|
||||
* @return \PHPUnit\Framework\MockObject\MockObject
|
||||
*/
|
||||
protected function getExchangeControllerMock($reqStack)
|
||||
{
|
||||
$container = self::$kernel->getContainer();
|
||||
$serviceMock = $this->getServiceMock();
|
||||
|
||||
$exchangeControllerClassName = $this->getExchangeControllerClassName();
|
||||
$exchangeControllerMock = $this->getMockBuilder($exchangeControllerClassName)
|
||||
->setMethods(['getDeliveryApi'])
|
||||
->setConstructorArgs([
|
||||
$container->get('doctrine.orm.entity_manager'),
|
||||
$container->get('jms_serializer'),
|
||||
$reqStack,
|
||||
])
|
||||
->getMock();
|
||||
|
||||
$exchangeControllerMock->expects($this->any())
|
||||
->method('getDeliveryApi')
|
||||
->willReturn($serviceMock);
|
||||
|
||||
$exchangeControllerMock->setContainer($container);
|
||||
|
||||
return $exchangeControllerMock;
|
||||
}
|
||||
}
|
Loading…
Add table
Reference in a new issue