Initial Commit

This commit is contained in:
2019-11-21 12:25:31 +01:00
commit f4aabcb9b1
13959 changed files with 787761 additions and 0 deletions

View File

@@ -0,0 +1,168 @@
<script>
var nb_products = 0;
//Automatic product add during order creation
$('#add-cart-item').click(function(ev) {
$.get("{url path='/admin/module/OrderCreation/add-item'}/"+nb_products, function(data){
nb_products += 1;
$('#body-order-cart').append(data);
},'html');
});
$('#body-order-cart').on('change', '.category-list', function(clickEvent){
var target_id = $(this).data('target');
var target_destination_id = $(this).data('destination');
$.ajax({
url : '{url path="/admin/module/OrderCreation/0/list-products/"}' + $(this).val() + '.xml',
type : 'get',
dataType : 'json',
success : function(json) {
$('#'+target_id).empty();
var have_content = false;
var oldValue = null;
var isOptGroupOpen = false;
var listOfOptions = "";
$.each(json, function(idx, value) {
if (oldValue == null) {
oldValue = value;
} else {
if (oldValue.product_id == value.product_id) {
if (isOptGroupOpen == false) {
listOfOptions +=
'<optgroup label="' + oldValue.title + '">' +
'<option value="' + oldValue.id + '">' + oldValue.ref + '(' + oldValue.quantity + ')' + '</option>'
;
isOptGroupOpen = true;
} else {
listOfOptions +=
'<option value="' + oldValue.id + '">' + oldValue.ref + '(' + oldValue.quantity + ')' + '</option>'
;
}
} else {
if (isOptGroupOpen == true) {
listOfOptions +=
'</optgroup>'
;
}
listOfOptions +=
'<option value="' + oldValue.id + '">' + oldValue.title + '(' + oldValue.quantity + ')' + '</option>'
;
}
oldValue = value;
}
//$('#'+target_id).append($('<option>').text(value.title+" ("+value.quantity+")").attr('value', value.id));
have_content = true;
});
if (isOptGroupOpen == true) {
listOfOptions +=
'<option value="' + oldValue.id + '">' + oldValue.ref + '(' + oldValue.quantity + ')' + '</option>' +
'</optgroup>'
;
} else {
listOfOptions +=
'<option value="' + oldValue.id + '">' + oldValue.title + '(' + oldValue.quantity + ')' + '</option>'
;
}
$('#'+target_id).append(listOfOptions);
if (have_content) {
$('#'+target_destination_id).removeClass('hide');
}
else {
$('#'+target_destination_id).addClass('hide');
}
}
});
});
$('#body-order-cart').on('click', '.item-ajax-delete', function(clickEvent){
$('#'+$(this).data('target')).remove();
});
$('#type_order_form').change(function(ev) {
if($(this).val() == 2){
$('#type_order_info').removeClass('hide');
}else{
$('#type_order_info').addClass('hide');
}
});
$('#delivery_address_id_form').on('change', function(){
if ($(this).val() > 0) {
$('#list-delivery').addClass('loading');
//update the country in the request
$.ajax({
type: "POST",
url: "/admin/module/OrderCreation/update/country/request",
data: {
address_id: $(this).val()
}
})
.done(function(response){
$.ajax({
type: "GET",
url: "/order/deliveryModuleList"
})
.done(function(response){
$('#list-delivery').removeClass('loading');
$('#list-delivery').html(response);
$('#list-delivery input.delivery-method').each(function(){
if ($(this).is(':checked')) {
$('#delivery_module_id').val($(this).val());
}
});
//clear both between all radio button
$('#list-delivery .radio').each(function(){
$(this).css('clear', 'both');
});
})
.error(function(error){
$('#list-delivery').removeClass('loading');
if (typeof(error.statusTexddt) != 'undefined') {
$('#list-delivery').html('<div class="alert alert-danger">' + error.statusText + '</div>');
}
});
})
.error(function(error){
$('#list-delivery').removeClass('loading');
if (typeof(error.statusTexddt) != 'undefined') {
$('#list-delivery').html('<div class="alert alert-danger">' + error.statusText + '</div>');
}
});
} else {
$('#delivery_module_id').val(0);
$('#list-delivery').removeClass('loading');
$('#list-delivery').html(
'<div class="alert alert-danger">' +
"{intl l='Choose a delivery address first' d='ordercreation'}" +
'</div>'
);
}
});
$('#list-delivery').on('change', '.delivery-method', function(){
$('#delivery_module_id').val($(this).val());
})
</script>

View File

@@ -0,0 +1,29 @@
<div class="row">
<div class="col-md-12 general-block-decorator">
<div class="row">
{if $order_creation_error}
<div class="col-md-12">
<div class="alert alert-danger">{$order_creation_error}</div>
</div>
{/if}
{if $order_creation_success}
<div class="col-md-12">
<div class="alert alert-success">{$order_creation_success}</div>
</div>
{/if}
<div class="col-md-12 title title-without-tabs">
{intl l="Create an order for this customer" d='ordercreation'}
</div>
<div class="col-md-12">
{loop type="auth" name="can_create" role="ADMIN" resource="admin.ordercreation" access="CREATE"}
<a class="btn btn-default btn-primary action-btn" title="{intl l='Generate a new order' d='ordercreation'}" href="#order_create_dialog" data-toggle="modal">
<span>{intl l="Generate a new order" d="ordercreation"}</span>
</a>
{/loop}
</div>
</div>
</div>
</div>
{* -- Create a new order -------------------- *}
{include file="forms/create-order-form.html"}

View File

@@ -0,0 +1,9 @@
<style type="text/css">
.label-credit{
background-color: #000000;
}
.label-credit-payed{
background-color: hotpink;
}
</style>

View File

@@ -0,0 +1,6 @@
<th class="object-title text-center">
{intl l="Invoice" d="ordercreation"}
</th>
<th class="object-title text-center">
{intl l="Invoice date" d="ordercreation"}
</th>

View File

@@ -0,0 +1,6 @@
<td class="text-center">
{$INVOICE_REF}
</td>
<td class="text-center">
{format_date date=$INVOICE_DATE output="date"}
</td>

View File

@@ -0,0 +1,41 @@
<?xml version="1.0" encoding="UTF-8" ?>
<config xmlns="http://thelia.net/schema/dic/config"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://thelia.net/schema/dic/config http://thelia.net/schema/dic/config/thelia-1.0.xsd">
<loops>
<!-- sample definition
<loop name="MySuperLoop" class="MyModule\Loop\MySuperLoop" />
-->
</loops>
<forms>
<form name="admin.order.creation.create.form" class="OrderCreation\Form\OrderCreationCreateForm" />
</forms>
<commands>
<!--
<command class="MyModule\Command\MySuperCommand" />
-->
</commands>
<services>
<service id="order.creation.action" class="OrderCreation\EventListeners\OrderCreationListener" scope="request">
<argument type="service" id="request"/>
<tag name="kernel.event_subscriber"/>
</service>
</services>
<!--
<exports>
</exports>
-->
<!--
<imports>
</imports>
-->
</config>

View File

@@ -0,0 +1,18 @@
<?xml version="1.0" encoding="UTF-8"?>
<module>
<fullnamespace>OrderCreation\OrderCreation</fullnamespace>
<descriptive locale="en_US">
<title>Order creation in BackOffice</title>
</descriptive>
<descriptive locale="fr_FR">
<title>Creation de commande dans le BackOffice</title>
</descriptive>
<version>1.4</version>
<author>
<name>gbarral</name>
<email>gbarral@openstudio.fr</email>
</author>
<type>classic</type>
<thelia>2.1.1</thelia>
<stability>other</stability>
</module>

View File

@@ -0,0 +1,25 @@
<?xml version="1.0" encoding="UTF-8" ?>
<routes xmlns="http://symfony.com/schema/routing"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://symfony.com/schema/routing http://symfony.com/schema/routing/routing-1.0.xsd">
<route id="admin.order.creation.create" path="/admin/module/OrderCreation/order/create" methods="post">
<default key="_controller">OrderCreation\Controller\Admin\OrderCreationAdminController::createOrderAction</default>
</route>
<route id="admin.order.creation.add.item" path="/admin/module/OrderCreation/add-item/{position}" methods="get">
<default key="_controller">OrderCreation\Controller\Admin\OrderCreationAdminController::addItemAction</default>
<requirement key="position">\d+</requirement>
</route>
<route id="admin.order.creation.list-products" path="/admin/module/OrderCreation/{productId}/list-products/{categoryId}.{_format}" methods="GET">
<default key="_controller">OrderCreation\Controller\Admin\OrderCreationAdminController::getAvailableProductAction</default>
<requirement key="_format">xml|json</requirement>
</route>
<route id="admin.order.creation.country.request" path="/admin/module/OrderCreation/update/country/request" methods="POST">
<default key="_controller">OrderCreation\Controller\Admin\OrderCreationAdminController::updateCountryInRequest</default>
</route>
</routes>

View File

@@ -0,0 +1,7 @@
<?xml version="1.0" encoding="UTF-8"?>
<database defaultIdMethod="native" name="thelia" namespace="OrderCreation\Model">
<!--
See propel documentation on http://propelorm.org for all information about schema file
-->
<external-schema filename="local/config/schema.xml" referenceOnly="true" />
</database>

View File

@@ -0,0 +1,239 @@
<?php
/**
* Created by PhpStorm.
* User: gbarral
* Date: 28/08/2014
* Time: 10:58
*/
namespace OrderCreation\Controller\Admin;
use OrderCreation\Event\OrderCreationEvent;
use OrderCreation\EventListeners\OrderCreationListener;
use OrderCreation\Form\OrderCreationCreateForm;
use Propel\Runtime\ActiveQuery\Criteria;
use Propel\Runtime\ActiveQuery\Join;
use Propel\Runtime\Propel;
use Symfony\Component\HttpFoundation\RedirectResponse;
use Thelia\Controller\Admin\BaseAdminController;
use Thelia\Core\Security\AccessManager;
use Thelia\Core\Security\Resource\AdminResources;
use Thelia\Form\CustomerUpdateForm;
use Thelia\Model\AddressQuery;
use Thelia\Model\Base\CustomerQuery;
use Thelia\Model\Base\ProductSaleElementsQuery;
use Thelia\Model\Customer;
use Thelia\Model\Map\OrderTableMap;
use Thelia\Model\Map\ProductCategoryTableMap;
use Thelia\Model\Map\ProductI18nTableMap;
use Thelia\Model\Map\ProductSaleElementsTableMap;
use Thelia\Model\Map\ProductTableMap;
use Thelia\Model\Order;
use Thelia\Tools\URL;
class OrderCreationAdminController extends BaseAdminController
{
public function addItemAction($position)
{
return $this->render(
"ajax/add-cart-item",
array("position" => $position)
);
}
public function createOrderAction()
{
$response = $this->checkAuth(array(AdminResources::MODULE), array('OrderCreation'), AccessManager::CREATE);
if (null !== $response) {
return $response;
}
$con = Propel::getConnection(OrderTableMap::DATABASE_NAME);
$con->beginTransaction();
$form = new OrderCreationCreateForm($this->getRequest());
try {
$formValidate = $this->validateForm($form);
$event = new OrderCreationEvent();
$event
->setContainer($this->getContainer())
->setCustomerId($formValidate->get('customer_id')->getData())
->setDeliveryAddressId($formValidate->get('delivery_address_id')->getData())
->setDeliveryModuleId($formValidate->get('delivery_module_id')->getData())
->setInvoiceAddressId($formValidate->get('invoice_address_id')->getData())
->setPaymentModuleId($formValidate->get('payment_module_id')->getData())
->setProductSaleElementIds($formValidate->get('product_sale_element_id')->getData())
->setQuantities($formValidate->get('quantity')->getData())
;
$this->dispatch(OrderCreationListener::ADMIN_ORDER_CREATE, $event);
if (null != $event->getResponse()) {
$con->commit();
return $event->getResponse();
}
//Don't forget to fill the Customer form
if (null != $customer = CustomerQuery::create()->findPk($formValidate->get('customer_id')->getData())) {
$customerForm = $this->hydrateCustomerForm($customer);
$this->getParserContext()->addForm($customerForm);
}
$con->commit();
return RedirectResponse::create(
URL::getInstance()->absoluteUrl(
'/admin/customer/update?customer_id='.$formValidate->get('customer_id')->getData()
)
);
} catch (\Exception $e) {
$con->rollBack();
$form->setErrorMessage($e->getMessage());
$this->getParserContext()
->addForm($form)
->setGeneralError($e->getMessage())
;
//Don't forget to fill the Customer form
if (null != $customer = CustomerQuery::create()
->findPk($this->getRequest()->request->get('admin_order_create')['customer_id'])) {
$customerForm = $this->hydrateCustomerForm($customer);
$this->getParserContext()->addForm($customerForm);
}
return $this->render('customer-edit', array(
'customer_id' => $this->getRequest()->request->get('admin_order_create')['customer_id'],
"order_creation_error" => $e->getMessage()
));
}
}
protected function hydrateCustomerForm(Customer $customer)
{
// Get default adress of the customer
$address = $customer->getDefaultAddress();
// Prepare the data that will hydrate the form
$data = array(
'id' => $customer->getId(),
'firstname' => $customer->getFirstname(),
'lastname' => $customer->getLastname(),
'email' => $customer->getEmail(),
'title' => $customer->getTitleId(),
'discount' => $customer->getDiscount(),
'reseller' => $customer->getReseller(),
);
if ($address !== null) {
$data['company'] = $address->getCompany();
$data['address1'] = $address->getAddress1();
$data['address2'] = $address->getAddress2();
$data['address3'] = $address->getAddress3();
$data['phone'] = $address->getPhone();
$data['cellphone'] = $address->getCellphone();
$data['zipcode'] = $address->getZipcode();
$data['city'] = $address->getCity();
$data['country'] = $address->getCountryId();
}
// A loop is used in the template
return new CustomerUpdateForm($this->getRequest(), 'form', $data);
}
public function getAvailableProductAction($categoryId = null)
{
$result = array();
if ($categoryId !== null) {
$pseQuery = ProductSaleElementsQuery::create();
$productJoin = new Join(ProductSaleElementsTableMap::PRODUCT_ID, ProductTableMap::ID, Criteria::INNER_JOIN);
$pseQuery->addJoinObject($productJoin);
$productI18nJoin = new Join(ProductTableMap::ID, ProductI18nTableMap::ID, Criteria::INNER_JOIN);
$pseQuery->addJoinObject($productI18nJoin, 'productI18n_JOIN');
$pseQuery->addJoinCondition(
"productI18n_JOIN",
"product_i18n.locale = '".$this->getCurrentEditionLocale()."'",
null,
null,
\PDO::PARAM_STR
);
$productCategoryJoin = new Join(
ProductTableMap::ID,
ProductCategoryTableMap::PRODUCT_ID,
Criteria::INNER_JOIN
);
$pseQuery->addJoinObject($productCategoryJoin, "productCategory_JOIN");
$pseQuery->addJoinCondition(
"productCategory_JOIN",
"product_category.default_category = ?",
1,
null,
\PDO::PARAM_INT
);
$pseQuery->addJoinCondition(
"productCategory_JOIN",
"product_category.category_id = ?",
$categoryId,
null,
\PDO::PARAM_INT
);
$pseQuery->addAscendingOrderByColumn('product_i18n.TITLE');
$pseQuery->withColumn("product_i18n.title", "PRODUCT_TITLE");
$pseQuery->withColumn("product.id", "PRODUCT_ID");
$pses = $pseQuery->find();
/** @var \Thelia\Model\ProductSaleElements $pse */
foreach ($pses as $pse) {
$result[] = array(
'id' => $pse->getId(),
'product_id' => $pse->getVirtualColumns()["PRODUCT_ID"],
'ref' => $pse->getRef(),
'title' => $pse->getVirtualColumns()["PRODUCT_TITLE"],
'quantity' => $pse->getQuantity()
);
}
}
return $this->jsonResponse(json_encode($result));
}
public function updateCountryInRequest()
{
if (null != $addressId = $this->getRequest()->request->get('address_id')) {
if (null != $address = AddressQuery::create()->findPk($addressId)) {
$order = new Order();
$order
->setCustomer()
->setChoosenDeliveryAddress($addressId);
$this->getRequest()->getSession()->set(
"thelia.order",
$order
);
$this->getRequest()->getSession()->set(
"thelia.customer_user",
$address->getCustomer()
);
}
}
return null;
}
}

View File

@@ -0,0 +1,273 @@
<?php
/**
* Created by PhpStorm.
* User: gbarral
* Date: 28/08/2014
* Time: 17:13
*/
namespace OrderCreation\Event;
use Thelia\Core\Event\ActionEvent;
class OrderCreationEvent extends ActionEvent
{
/** @var \Symfony\Component\DependencyInjection\ContainerInterface */
protected $container;
/** @var int $customerId */
protected $customerId;
/** @var int $deliveryAddressId */
protected $deliveryAddressId;
/** @var int $invoiceAddressId */
protected $invoiceAddressId;
/** @var int $deliveryModuleId */
protected $deliveryModuleId;
/** @var int $paymentModuleId */
protected $paymentModuleId;
/** @var array $productSaleElementIds */
protected $productSaleElementIds;
/** @var array $quantities */
protected $quantities;
/** @var \Thelia\Model\CartItem $cartItem */
protected $cartItem;
/** @var \Thelia\Model\Order $customerId */
protected $placedOrder;
protected $response;
public function __construct()
{
//
}
/**
* @param \Symfony\Component\DependencyInjection\ContainerInterface $container
*
* @return OrderCreationEvent
*/
public function setContainer($container)
{
$this->container = $container;
return $this;
}
/**
* @return \Symfony\Component\DependencyInjection\ContainerInterface
*/
public function getContainer()
{
return $this->container;
}
/**
* @param \Thelia\Model\CartItem $cartItem
*
* @return OrderCreationEvent
*/
public function setCartItem($cartItem)
{
$this->cartItem = $cartItem;
return $this;
}
/**
* @return \Thelia\Model\CartItem
*/
public function getCartItem()
{
return $this->cartItem;
}
/**
* @param int $customerId
*
* @return OrderCreationEvent
*/
public function setCustomerId($customerId)
{
$this->customerId = $customerId;
return $this;
}
/**
* @return int
*/
public function getCustomerId()
{
return $this->customerId;
}
/**
* @param int $deliveryAddressId
*
* @return OrderCreationEvent
*/
public function setDeliveryAddressId($deliveryAddressId)
{
$this->deliveryAddressId = $deliveryAddressId;
return $this;
}
/**
* @return int
*/
public function getDeliveryAddressId()
{
return $this->deliveryAddressId;
}
/**
* @param int $deliveryModuleId
*
* @return OrderCreationEvent
*/
public function setDeliveryModuleId($deliveryModuleId)
{
$this->deliveryModuleId = $deliveryModuleId;
return $this;
}
/**
* @return int
*/
public function getDeliveryModuleId()
{
return $this->deliveryModuleId;
}
/**
* @param int $invoiceAddressId
*
* @return OrderCreationEvent
*/
public function setInvoiceAddressId($invoiceAddressId)
{
$this->invoiceAddressId = $invoiceAddressId;
return $this;
}
/**
* @return int
*/
public function getInvoiceAddressId()
{
return $this->invoiceAddressId;
}
/**
* @param int $paymentModuleId
*
* @return OrderCreationEvent
*/
public function setPaymentModuleId($paymentModuleId)
{
$this->paymentModuleId = $paymentModuleId;
return $this;
}
/**
* @return int
*/
public function getPaymentModuleId()
{
return $this->paymentModuleId;
}
/**
* @param \Thelia\Model\Order $placedOrder
*
* @return OrderCreationEvent
*/
public function setPlacedOrder($placedOrder)
{
$this->placedOrder = $placedOrder;
return $this;
}
/**
* @return \Thelia\Model\Order
*/
public function getPlacedOrder()
{
return $this->placedOrder;
}
/**
* @param array $productSaleElementIds
*
* @return OrderCreationEvent
*/
public function setProductSaleElementIds($productSaleElementIds)
{
$this->productSaleElementIds = $productSaleElementIds;
return $this;
}
/**
* @return array
*/
public function getProductSaleElementIds()
{
return $this->productSaleElementIds;
}
/**
* @param array $quantities
*
* @return OrderCreationEvent
*/
public function setQuantities($quantities)
{
$this->quantities = $quantities;
return $this;
}
/**
* @return array
*/
public function getQuantities()
{
return $this->quantities;
}
/**
* @param mixed $response
*
* @return OrderCreationEvent
*/
public function setResponse($response)
{
$this->response = $response;
return $this;
}
/**
* @return mixed
*/
public function getResponse()
{
return $this->response;
}
}

View File

@@ -0,0 +1,229 @@
<?php
/**
* Created by PhpStorm.
* User: gbarral
* Date: 28/08/2014
* Time: 17:19
*/
namespace OrderCreation\EventListeners;
use OrderCreation\Event\OrderCreationEvent;
use Symfony\Component\EventDispatcher\EventSubscriberInterface;
use Thelia\Core\Event\Order\OrderEvent;
use Thelia\Core\Event\Order\OrderManualEvent;
use Thelia\Core\Event\Order\OrderPaymentEvent;
use Thelia\Core\Event\TheliaEvents;
use Thelia\Core\HttpFoundation\Request;
use Thelia\Core\HttpFoundation\Session\Session;
use Thelia\Model\Base\AddressQuery;
use Thelia\Model\Base\CustomerQuery;
use Thelia\Model\Base\ProductSaleElementsQuery;
use Thelia\Model\Cart;
use Thelia\Model\CartItem;
use Thelia\Model\Currency;
use Thelia\Model\Lang;
use Thelia\Model\ModuleQuery;
use Thelia\Model\Order;
use Thelia\Model\OrderPostage;
use Thelia\Model\OrderStatusQuery;
use Thelia\Model\ProductPriceQuery;
class OrderCreationListener implements EventSubscriberInterface
{
const ADMIN_ORDER_CREATE = "action.admin.order.create";
const ADMIN_ORDER_BEFORE_ADD_CART = "action.admin.order.before.add.cart";
const ADMIN_ORDER_AFTER_CREATE_MANUAL = "action.admin.order.after.create.manual";
protected $request;
public function __construct(Request $request)
{
$this->request = $request;
}
/**
* Returns an array of event names this subscriber wants to listen to.
*
* The array keys are event names and the value can be:
*
* * The method name to call (priority defaults to 0)
* * An array composed of the method name to call and the priority
* * An array of arrays composed of the method names to call and respective
* priorities, or 0 if unset
*
* For instance:
*
* * array('eventName' => 'methodName')
* * array('eventName' => array('methodName', $priority))
* * array('eventName' => array(array('methodName1', $priority), array('methodName2'))
*
* @return array The event names to listen to
*
* @api
*/
public static function getSubscribedEvents()
{
return array(
self::ADMIN_ORDER_CREATE => array('adminOrderCreate', 128)
);
}
public function adminOrderCreate(OrderCreationEvent $event)
{
$pseIds = $event->getProductSaleElementIds();
$quantities = $event->getQuantities();
/** @var \Thelia\Model\Address $deliveryAddress */
$deliveryAddress = AddressQuery::create()->findPk($event->getDeliveryAddressId());
/** @var \Thelia\Model\Address $invoiceAddress */
$invoiceAddress = AddressQuery::create()->findPk($event->getInvoiceAddressId());
/** @var \Thelia\Model\Module $deliveryModule */
$deliveryModule = ModuleQuery::create()->findPk($event->getDeliveryModuleId());
/** @var \Thelia\Model\Module $paymentModule */
$paymentModule = ModuleQuery::create()->findPk($event->getPaymentModuleId());
/** @var \Thelia\Model\Currency $currency */
$currency = Currency::getDefaultCurrency();
$lang = new Lang();
/** @var \Thelia\Model\Customer $customer */
$customer = CustomerQuery::create()->findPk($event->getCustomerId());
$order = new Order();
$order
->setCustomerId($customer->getId())
->setCurrencyId($currency->getId())
->setCurrencyRate($currency->getRate())
->setStatusId(OrderStatusQuery::getNotPaidStatus()->getId())
->setLangId($lang->getDefaultLanguage()->getId())
->setChoosenDeliveryAddress($deliveryAddress)
->setChoosenInvoiceAddress($invoiceAddress)
;
$cart = new Cart();
$cart->setToken(uniqid("createorder", true))
->setCustomer($customer)
->setCurrency($currency->getDefaultCurrency())
->save()
;
foreach ($pseIds as $key => $pseId) {
/** @var \Thelia\Model\ProductSaleElements $productSaleElements */
if (null != $productSaleElements = ProductSaleElementsQuery::create()->findOneById($pseId)) {
/** @var \Thelia\Model\ProductPrice $productPrice */
if (null != $productPrice = ProductPriceQuery::create()
->filterByProductSaleElementsId($productSaleElements->getId())
->filterByCurrencyId($currency->getDefaultCurrency()->getId())
->findOne()) {
$cartItem = new CartItem();
$cartItem
->setCart($cart)
->setProduct($productSaleElements->getProduct())
->setProductSaleElements($productSaleElements)
->setQuantity($quantities[$key])
->setPrice($productPrice->getPrice())
->setPromoPrice($productPrice->getPromoPrice())
->setPromo($productSaleElements->getPromo())
->setPriceEndOfLife(time() + 60*60*24*30);
$event->setCartItem($cartItem);
$event->getDispatcher()->dispatch(self::ADMIN_ORDER_BEFORE_ADD_CART, $event);
$cartItem->save();
}
}
}
//If someone is connected in FRONT, stock it
$oldCustomer = $this->request->getSession()->getCustomerUser();
//Do the same for his cart
$oldCart = $this->request->getSession()->getSessionCart($event->getDispatcher());
$this->request->getSession()->setCustomerUser($customer);
$this->request->getSession()->set("thelia.cart_id", $cart->getId());
$orderEvent = new OrderEvent($order);
$orderEvent->setDeliveryAddress($deliveryAddress->getId());
$orderEvent->setInvoiceAddress($invoiceAddress->getId());
$moduleInstance = $deliveryModule->getModuleInstance($event->getContainer());
$postage = OrderPostage::loadFromPostage(
$moduleInstance->getPostage($deliveryAddress->getCountry())
);
$orderEvent->setPostage($postage->getAmount());
$orderEvent->setPostageTax($postage->getAmountTax());
$orderEvent->setPostageTaxRuleTitle($postage->getTaxRuleTitle());
$orderEvent->setDeliveryModule($deliveryModule->getId());
$orderEvent->setPaymentModule($paymentModule->getId());
$event->getDispatcher()->dispatch(TheliaEvents::ORDER_SET_DELIVERY_ADDRESS, $orderEvent);
$event->getDispatcher()->dispatch(TheliaEvents::ORDER_SET_INVOICE_ADDRESS, $orderEvent);
$event->getDispatcher()->dispatch(TheliaEvents::ORDER_SET_POSTAGE, $orderEvent);
$event->getDispatcher()->dispatch(TheliaEvents::ORDER_SET_DELIVERY_MODULE, $orderEvent);
$event->getDispatcher()->dispatch(TheliaEvents::ORDER_SET_PAYMENT_MODULE, $orderEvent);
//DO NOT FORGET THAT THE DISCOUNT ORDER HAS TO BE PLACED IN CART
if ($this->request->getSession()->getSessionCart($event->getDispatcher()) != null) {
$cart->setCartItems($this->request->getSession()->getSessionCart($event->getDispatcher())->getCartItems());
$cart->setDiscount($this->request->getSession()->getSessionCart($event->getDispatcher())->getDiscount());
}
$cart->save();
$orderManualEvent = new OrderManualEvent(
$orderEvent->getOrder(),
$orderEvent->getOrder()->getCurrency(),
$orderEvent->getOrder()->getLang(),
$cart,
$customer
);
$this->request->getSession()->set("thelia.cart_id", $cart->getId());
$event->getDispatcher()->dispatch(TheliaEvents::ORDER_CREATE_MANUAL, $orderManualEvent);
$event->getDispatcher()->dispatch(
TheliaEvents::ORDER_BEFORE_PAYMENT,
new OrderEvent($orderManualEvent->getPlacedOrder())
);
/* but memorize placed order */
$orderEvent->setOrder(new Order());
$orderEvent->setPlacedOrder($orderManualEvent->getPlacedOrder());
/* call pay method */
$payEvent = new OrderPaymentEvent($orderManualEvent->getPlacedOrder());
$event->getDispatcher()->dispatch(TheliaEvents::MODULE_PAY, $payEvent);
if ($payEvent->hasResponse()) {
$event->setResponse($payEvent->getResponse());
}
$event->setPlacedOrder($orderManualEvent->getPlacedOrder());
$event->getDispatcher()->dispatch(self::ADMIN_ORDER_AFTER_CREATE_MANUAL, $event);
//Reconnect the front user
if ($oldCustomer != null) {
$this->request->getSession()->setCustomerUser($oldCustomer);
//And fill his cart
if ($oldCart != null) {
$this->request->getSession()->set("thelia.cart_id", $oldCart->getId());
}
} else {
$this->request->getSession()->clearCustomerUser();
}
}
}

View File

@@ -0,0 +1,122 @@
<?php
/**
* Created by PhpStorm.
* User: gbarral
* Date: 28/08/2014
* Time: 11:02
*/
namespace OrderCreation\Form;
use OrderCreation\OrderCreation;
use Symfony\Component\Validator\Constraints\GreaterThan;
use Symfony\Component\Validator\Constraints\NotBlank;
use Thelia\Core\Translation\Translator;
use Thelia\Form\BaseForm;
class OrderCreationCreateForm extends BaseForm
{
/**
*
* in this function you add all the fields you need for your Form.
* Form this you have to call add method on $this->formBuilder attribute :
*
* $this->formBuilder->add("name", "text")
* ->add("email", "email", array(
* "attr" => array(
* "class" => "field"
* ),
* "label" => "email",
* "constraints" => array(
* new \Symfony\Component\Validator\Constraints\NotBlank()
* )
* )
* )
* ->add('age', 'integer');
*
* @return null
*/
protected function buildForm()
{
$this->formBuilder
->add('customer_id', 'integer', array(
'constraints' => array(
new NotBlank()
),
'label' => 'customer_id',
'label_attr' => array(
'for' => 'customer_id_form'
)
))
->add('delivery_address_id', 'integer', array(
'constraints' => array(
new NotBlank()
),
'label' => Translator::getInstance()->trans("Delivery address", array(), OrderCreation::MESSAGE_DOMAIN),
'label_attr' => array(
'for' => 'delivery_address_id_form'
)
))
->add('invoice_address_id', 'integer', array(
'constraints' => array(
new NotBlank()
),
'label' => Translator::getInstance()->trans("Invoice address", array(), OrderCreation::MESSAGE_DOMAIN),
'label_attr' => array(
'for' => 'invoice_address_id_form'
)
))
->add('delivery_module_id', 'integer', array(
'constraints' => array(
new NotBlank()
),
'label' => Translator::getInstance()->trans("Transport solution", array(), OrderCreation::MESSAGE_DOMAIN),
'label_attr' => array(
'for' => 'delivery_module_id_form'
)
))
->add('payment_module_id', 'integer', array(
'constraints' => array(
new NotBlank()
),
'label' => Translator::getInstance()->trans("Payment solution", array(), OrderCreation::MESSAGE_DOMAIN),
'label_attr' => array(
'for' => 'payment_module_id_form'
)
))
->add('product_sale_element_id', 'collection', array(
'type' => 'number',
'label' => Translator::getInstance()->trans('Product', array(), OrderCreation::MESSAGE_DOMAIN),
'label_attr' => array('for' => 'product_sale_element_id_form'),
'allow_add' => true,
'allow_delete' => true,
))
->add('quantity', 'collection', array(
'type' => 'number',
'label' => Translator::getInstance()->trans('Quantity', array(), OrderCreation::MESSAGE_DOMAIN),
'label_attr' => array('for' => 'quantity_form'),
'allow_add' => true,
'allow_delete' => true,
'options' => array(
'constraints' => array(
new NotBlank(),
new GreaterThan(
array('value' => 0)
)
)
)
))
;
}
/**
* @return string the name of you form. This name must be unique
*/
public function getName()
{
return "admin_order_create";
}
}

View File

@@ -0,0 +1,37 @@
<?php
return array(
//A
"Add product" => "Add product",
//B
"Be Carefull! This action will increase your product's stock" => "Be Carefull! This action will increase your product's stock",
//C
"Choose" => "Choose",
"Create an order for this customer" => "Create an order for this customer",
//D
"Delivery address" => "Delivery address",
//I
"Invoice" => "Invoice",
"Invoice date" => "Invoice date",
"Invoice address" => "Invoice address",
//P
"Payment" => "Payment",
"Payment solution" => "Payment solution",
//R
"Reimbursement" => "Reimbursement",
//G
"Generate a new order" => "Generate a new order",
//T
"Transport solution" => "Transport solution",
"Type of order" => "Type of order",
//Y
"You can't choose negative quantity for CREDIT order" => "You can't choose negative quantity for CREDIT order",
);

View File

@@ -0,0 +1,38 @@
<?php
return array(
//A
"Add product" => "Ajouter produit",
//B
"Be Carefull! This action will increase your product's stock" => "Attention! Cette action va augmenter vos stocks !",
//C
"Choose" => "Choisir",
"Choose a delivery address first" => "Veuillez choisir une adresse de livraison",
"Create an order for this customer" => "Créer une commande pour ce client",
//D
"Delivery address" => "Adresse de livraison",
//I
"Invoice" => "Facture",
"Invoice date" => "Date facture",
"Invoice address" => "Adresse de facturation",
//P
"Payment" => "Paiement",
"Payment solution" => "Moyen de paiement",
//R
"Reimbursement" => "Remboursement",
//G
"Generate a new order" => "Générer une nouvelle commande",
//T
"Transport solution" => "Moyen de transport",
"Type of order" => "Type de commande",
//Y
"You can't choose negative quantity for CREDIT order" => "Vous ne pouvez pas choisir de quantités négatives pour un AVOIR.",
);

View File

@@ -0,0 +1,20 @@
<?php
/*************************************************************************************/
/* This file is part of the Thelia package. */
/* */
/* Copyright (c) OpenStudio */
/* email : dev@thelia.net */
/* web : http://www.thelia.net */
/* */
/* For the full copyright and license information, please view the LICENSE.txt */
/* file that was distributed with this source code. */
/*************************************************************************************/
namespace OrderCreation;
use Thelia\Module\BaseModule;
class OrderCreation extends BaseModule
{
const MESSAGE_DOMAIN = "ordercreation";
}

View File

@@ -0,0 +1,26 @@
# Order Creation
Create order from admin of Thelia2 (2.1.1+)
## Installation
### Manually
* Copy the module into ```<thelia_root>/local/modules/``` directory and be sure that the name of the module is OrderCreation.
* Activate it in your thelia administration panel
### Composer
Add it in your main thelia composer.json file
```
composer require thelia/order-creation-module:~1.0
```
## Usage
Be sure that you have :
- an active payment module
- an active delivery module
Then, go to the customer edit page and click on the button "Create an order for this customer"

View File

@@ -0,0 +1,11 @@
{
"name": "thelia/order-creation-module",
"license": "LGPL-3.0+",
"type": "thelia-module",
"require": {
"thelia/installer": "~1.1"
},
"extra": {
"installer-name": "OrderCreation"
}
}

View File

@@ -0,0 +1,45 @@
{form name="admin.order.creation.create.form"}
<tr id="tr-{$position}" class="title-without-tabs">
<td colspan="2">
<table class="table table-striped table-condensed">
<caption>
<div class="col-md-11"></div>
<div class="col-md-1">
<a class="btn btn-default btn-xs item-ajax-delete" data-toggle="modal" title="{intl l='Remove' d='ordercreation'}" data-target="tr-{$position}" href="#">
<i class="glyphicon glyphicon-trash"></i>
</a>
</div>
</caption>
<tbody>
<tr>
<td>
<label for="category{$position}" class="control-label">{intl l="Category" d="ordercreation"}</label>
<select id="category{$position}" required="required" class="form-control category-list" data-target="item{$position}" data-destination="tr-item{$position}">
<option>{intl l="Choose"}</option>
{loop name="cat-parent" type="category-tree" category="0" visible="*" product="0"}
<option value="{$ID}" style="padding-left: {3 + $LEVEL * 20}px">{$TITLE}</option>
{/loop}
</select>
</td>
<td></td>
</tr>
<tr id="tr-item{$position}" class="hide">
<td>
{form_field form=$form field='product_sale_element_id' value_key=$position}
<label for="item{$position}" class="control-label">{$label}</label>
<select id="item{$position}" class="form-control" name="{$name}"></select>
{/form_field}
</td>
<td>
{form_field form=$form field='quantity' value_key=$position}
<label for="quantity{$position}" class="control-label">{$label}</label>
<input type="text" class="form-control" name="{$name}" value="1">
{/form_field}
</td>
</tr>
</tbody>
</table>
</td>
<td></td>
</tr>
{/form}

View File

@@ -0,0 +1,107 @@
{form name="admin.order.creation.create.form"}
{* Capture the dialog body, to pass it to the generic dialog *}
{capture "order_create_dialog"}
{form_hidden_fields form=$form}
{form_field form=$form field='customer_id'}
<input type="hidden" name="{$name}" value="{$ID}">
{/form_field}
<table class="table">
<thead>
<tr>
<td>
{form_field form=$form field='delivery_address_id'}
<div class="form-group {if $error}has-error{/if}">
<label for="{$label_attr.for}" class="control-label">{$label} * : </label>
<select name="{$name}" id="{$label_attr.for}" class="form-control" required="required">
<option value="0">{intl l="Choose" d="ordercreation"}</option>
{loop type="address" name="address-delivery" customer=$ID}
<option value="{$ID}">{$LABEL}</option>
{/loop}
</select>
</div>
{/form_field}
</td>
<td>
{form_field form=$form field='invoice_address_id'}
<div class="form-group {if $error}has-error{/if}">
<label for="{$label_attr.for}" class="control-label">{$label} : </label>
<select name="{$name}" id="{$label_attr.for}" class="form-control">
{loop type="address" name="address-invoice" customer=$ID}
<option value="{$ID}">{$LABEL}</option>
{/loop}
</select>
</div>
{/form_field}
</td>
</tr>
</thead>
<tbody id="body-order-cart">
</tbody>
<tfoot>
<tr>
<td colspan="2">
<a id="add-cart-item" class="btn btn-default btn-primary action-btn" title="{intl l='Add product' d='ordercreation'}" href="#" data-toggle="modal">
<span>{intl l="Add product" d="ordercreation"}</span>
</a>
</td>
</tr>
<tr>
<td>
{form_field form=$form field='delivery_module_id'}
<div class="form-group {if $error}has-error{/if}">
<label for="{$label_attr.for}" class="control-label">{$label} * : </label><br />
<input type="hidden" name="{$name}" id="delivery_module_id" value="" />
<div id="list-delivery">
<div class="alert alert-danger">
{intl l="Choose a delivery address first" d="ordercreation"}
</div>
</div>
<!--
<select name="{$name}" id="{$label_attr.for}" class="form-control" required="required">
<option>{intl l="Choose" d="ordercreation"}</option>
{loop type="module" name="module-delivery" module_type="2" active="1"}
<option value="{$ID}">{$TITLE}</option>
{/loop}
</select>
-->
</div>
{/form_field}
</td>
<td>
{form_field form=$form field='payment_module_id'}
<div class="form-group {if $error}has-error{/if}">
<label for="{$label_attr.for}" class="control-label">{$label} : </label>
<select name="{$name}" id="{$label_attr.for}" class="form-control">
{loop type="module" name="module-payment" module_type="3" active="1"}
<option value="{$ID}">{$TITLE}</option>
{/loop}
</select>
</div>
{/form_field}
</td>
</tr>
</tfoot>
</table>
{/capture}
{include
file = "includes/generic-create-dialog.html"
dialog_id = "order_create_dialog"
dialog_title = {intl l="Generate a new order" d="ordercreation"}
dialog_body = {$smarty.capture.order_create_dialog nofilter}
dialog_ok_label = {intl l="Save"}
form_action = {url path='/admin/module/OrderCreation/order/create'}
form_enctype = {form_enctype form=$form}
form_error_message = $form_error_message
}
{/form}