''],
[['id_user', 'id_point_sale', 'id_distribution', 'id_subscription', 'id_invoice', 'id_quotation', 'id_delivery_note'], 'integer'],
[['auto_payment', 'tiller_synchronization'], 'boolean'],
[['status'], 'string'],
[['date', 'date_update', 'comment', 'comment_point_sale', 'mean_payment'], 'safe']
];
}
/**
* @inheritdoc
*/
public function attributeLabels()
{
return [
'id' => 'ID',
'id_user' => 'Id User',
'date' => 'Date',
'date_update' => 'Date de modification',
'id_point_sale' => 'Point de vente',
'id_distribution' => 'Date de distribution',
'id_subscription' => 'Abonnement',
'status' => 'Statut',
'id_invoice' => 'Facture',
'id_quotation' => 'Devis',
'id_delivery_note' => 'Bon de livraison'
];
}
/*
* Relations
*/
public function getUser()
{
return $this->hasOne(User::className(), ['id' => 'id_user']);
}
public function getProductOrder()
{
return $this->hasMany(ProductOrder::className(), ['id_order' => 'id'])
->with('product');
}
public function getDistribution()
{
return $this->hasOne(Distribution::className(), ['id' => 'id_distribution'])
->with('producer');
}
public function getPointSale()
{
return $this->hasOne(PointSale::className(), ['id' => 'id_point_sale'])
->with('userPointSale');
}
public function getCreditHistory()
{
return $this->hasMany(CreditHistory::className(), ['id_order' => 'id']);
}
public function getSubscription()
{
return $this->hasOne(Subscription::className(), ['id' => 'id_subscription'])
->with('productSubscription');
}
public function getInvoice()
{
return $this->hasOne(Invoice::className(), ['id' => 'id_invoice']);
}
public function getQuotation()
{
return $this->hasOne(Quotation::className(), ['id' => 'id_quotation']);
}
public function getDeliveryNote()
{
return $this->hasOne(DeliveryNote::className(), ['id' => 'id_delivery_note']);
}
/**
* Retourne les options de base nécessaires à la fonction de recherche.
*
* @return array
*/
public static function defaultOptionsSearch()
{
return [
'with' => ['productOrder', 'productOrder.product', 'creditHistory', 'creditHistory.userAction', 'pointSale'],
'join_with' => ['distribution', 'user', 'user.userProducer'],
'orderby' => 'order.date ASC',
'attribute_id_producer' => 'distribution.id_producer'
];
}
/**
* Initialise le montant total, le montant déjà payé et le poids de la
* commande.
*/
public function init()
{
$this->initAmount();
$this->initPaidAmount();
return $this;
}
/**
* Initialise le montant de la commande.
*
*/
public function initAmount()
{
$this->amount = 0;
$this->amount_with_tax = 0;
$this->weight = 0;
if (isset($this->productOrder)) {
foreach ($this->productOrder as $productOrder) {
$this->amount += $productOrder->price * $productOrder->quantity;
$this->amount_with_tax += Price::getPriceWithTax($productOrder->price, $productOrder->taxRate->value) * $productOrder->quantity;
if ($productOrder->unit == 'piece') {
if (isset($productOrder->product)) {
$this->weight += ($productOrder->quantity * $productOrder->product->weight) / 1000;
}
} else {
$this->weight += $productOrder->quantity;
}
}
}
}
/**
* Initialise le montant payé de la commande et le retourne.
*
* @return float
*/
public function initPaidAmount()
{
if (isset($this->creditHistory)) {
$history = $this->creditHistory;
} else {
$history = CreditHistory::find()
->where(['id_order' => $this->id])
->all();
}
$this->paid_amount = 0;
if (count($history)) {
foreach ($history as $ch) {
if ($ch->type == CreditHistory::TYPE_PAYMENT) {
$this->paid_amount += $ch->amount;
} elseif ($ch->type == CreditHistory::TYPE_REFUND) {
$this->paid_amount -= $ch->amount;
}
}
}
}
public function delete()
{
// remboursement si l'utilisateur a payé pour cette commande
$amountPaid = $this->getAmount(Order::AMOUNT_PAID);
if ($amountPaid > 0.01) {
$this->saveCreditHistory(
CreditHistory::TYPE_REFUND,
$amountPaid,
GlobalParam::getCurrentProducerId(),
$this->id_user,
User::getCurrentId()
);
}
// delete
if (Producer::getConfig('option_behavior_cancel_order') == Producer::BEHAVIOR_DELETE_ORDER_DELETE ||
(Producer::getConfig('option_behavior_cancel_order') == Producer::BEHAVIOR_DELETE_ORDER_STATUS && strlen($this->date_delete))) {
ProductOrder::deleteAll(['id_order' => $this->id]);
return parent::delete();
} // status 'delete'
elseif (Producer::getConfig('option_behavior_cancel_order') == Producer::BEHAVIOR_DELETE_ORDER_STATUS) {
$this->date_delete = date('Y-m-d H:i:s');
return $this->save();
}
}
/**
* Changement de statut d'une commande
*
* @param $newStatus
*/
public function changeOrderStatus($newStatus, $origin)
{
$orderStatusArray = GlobalParam::get('orderStatus');
switch ($newStatus) {
case 'new-order' :
$this->addOrderStatusHistory($newStatus, $origin);
$this->status = $newStatus;
$this->save();
break;
case 'waiting-paiement-on-delivery':
if(in_array($newStatus, $orderStatusArray[$this->status]['nextStatusAllow'])){
$this->addOrderStatusHistory($newStatus, $origin);
$this->status = $newStatus;
$this->save();
}
break;
case 'waiting-paiement-by-credit':
if(in_array($newStatus, $orderStatusArray[$this->status]['nextStatusAllow'])){
$this->addOrderStatusHistory($newStatus, $origin);
$this->status = $newStatus;
$this->save();
}
break;
case 'paid-by-credit':
if(in_array($newStatus, $orderStatusArray[$this->status]['nextStatusAllow'])){
$this->addOrderStatusHistory($newStatus, $origin);
$this->status = $newStatus;
$this->save();
}
break;
case 'waiting-delevery' :
if(in_array($newStatus, $orderStatusArray[$this->status]['nextStatusAllow'])){
$this->addOrderStatusHistory($newStatus, $origin);
$this->status = $newStatus;
$this->save();
}
break;
case 'delivered':
if(in_array($newStatus, $orderStatusArray[$this->status]['nextStatusAllow'])){
$this->addOrderStatusHistory($newStatus, $origin);
$this->status = $newStatus;
$this->save();
}
break;
case 'refunded':
if(in_array($newStatus, $orderStatusArray[$this->status]['nextStatusAllow'])){
$this->addOrderStatusHistory($newStatus, $origin);
$this->status = $newStatus;
$this->save();
}
break;
case 'cancel':
if(in_array($newStatus, $orderStatusArray[$this->status]['nextStatusAllow'])){
$this->addOrderStatusHistory($newStatus, $origin);
$this->status = $newStatus;
$this->save();
}
break;
default:
throw new NotFoundHttpException('Statut de commande inconnu.');
break;
}
}
public function addOrderStatusHistory($newStatus,$origin)
{
$orderStatusHistory = new OrderStatusHistory();
$orderStatusHistory->id_user = User::getCurrentId();
$orderStatusHistory->id_order = $this->id;
$orderStatusHistory->status = $newStatus;
$orderStatusHistory->origin = $origin;
$orderStatusHistory->date = date('Y-m-d H:i:s');
$orderStatusHistory->save();
}
/**
* Retourne le montant de la commande (total, payé, restant, ou en surplus).
*
* @param boolean $format
* @return float
*/
public function getAmount($type = self::AMOUNT_TOTAL, $format = false)
{
return $this->_getAmountGeneric($type, $this->amount, $format) ;
}
public function getAmountWithTax($type = self::AMOUNT_TOTAL, $format = false)
{
return $this->_getAmountGeneric($type, $this->amount_with_tax, $format) ;
}
protected function _getAmountGeneric($type, $amountOrder, $format)
{
switch ($type) {
case self::AMOUNT_TOTAL :
$amount = $amountOrder;
break;
case self::AMOUNT_PAID :
$this->initPaidAmount();
$amount = $this->paid_amount;
break;
case self::AMOUNT_REMAINING :
$amount = $this->getAmountWithTax(self::AMOUNT_TOTAL)
- $this->getAmountWithTax(self::AMOUNT_PAID);
break;
case self::AMOUNT_SURPLUS :
$amount = $this->getAmountWithTax(self::AMOUNT_PAID)
- $this->getAmountWithTax(self::AMOUNT_TOTAL);
break;
default:
throw new NotFoundHttpException('Type de montant inconnu.') ;
}
if ($format) {
return Price::format($amount) ;
} else {
return $amount;
}
}
/**
* Retourne les informations relatives à la commande au format JSON.
*
* @return string
*/
public function getDataJson()
{
$order = Order::searchOne(['order.id' => $this->id]);
$jsonOrder = [];
if ($order) {
$jsonOrder = [
'products' => [],
'amount' => $order->amount,
'str_amount' => $order->getAmountWithTax(self::AMOUNT_TOTAL, true),
'paid_amount' => $order->getAmount(self::AMOUNT_PAID),
'comment' => $order->comment,
];
foreach ($order->productOrder as $productOrder) {
$jsonOrder['products'][$productOrder->id_product] = $productOrder->quantity;
}
}
return json_encode($jsonOrder);
}
/**
* Enregistre un modèle de type CreditHistory.
*
* @param string $type
* @param float $montant
* @param integer $idProducer
* @param integer $idUser
* @param integer $idUserAction
*/
public function saveCreditHistory($type, $amount, $idProducer, $idUser, $idUserAction)
{
$creditHistory = new CreditHistory;
$creditHistory->id_user = $this->id_user;
$creditHistory->id_order = $this->id;
$creditHistory->amount = $amount;
$creditHistory->type = $type;
$creditHistory->id_producer = $idProducer;
$creditHistory->id_user_action = $idUserAction;
$creditHistory->populateRelation('order', $this);
$creditHistory->populateRelation('user', User::find()->where(['id' => $this->id_user])->one());
$creditHistory->save();
}
/**
* Ajuste le crédit pour que la commande soit payée.
*
* @return boolean
*/
public function processCredit()
{
if ($this->id_user) {
$paymentStatus = $this->getPaymentStatus();
if ($paymentStatus == self::PAYMENT_PAID) {
return true;
} elseif ($paymentStatus == self::PAYMENT_SURPLUS) {
$type = CreditHistory::TYPE_REFUND;
$amount = $this->getAmount(self::AMOUNT_SURPLUS);
} elseif ($paymentStatus == self::PAYMENT_UNPAID) {
$type = CreditHistory::TYPE_PAYMENT;
$amount = $this->getAmount(self::AMOUNT_REMAINING);
}
$this->saveCreditHistory(
$type,
$amount,
GlobalParam::getCurrentProducerId(),
$this->id_user,
User::getCurrentId()
);
}
}
/**
* Retourne le statut de paiement de la commande (payée, surplus, ou impayée).
*
* @return string
*/
public function getPaymentStatus()
{
// payé
if ($this->getAmountWithtax() - $this->getAmount(self::AMOUNT_PAID) < 0.01 &&
$this->getAmountWithtax() - $this->getAmount(self::AMOUNT_PAID) > -0.01) {
return self::PAYMENT_PAID;
} // à rembourser
elseif ($this->getAmountWithtax() - $this->getAmount(self::AMOUNT_PAID) <= -0.01) {
return self::PAYMENT_SURPLUS;
} // reste à payer
elseif ($this->getAmountWithtax() - $this->getAmount(self::AMOUNT_PAID) >= 0.01) {
return self::PAYMENT_UNPAID;
}
}
/**
* Retourne le résumé du panier au format HTML.
*
* @return string
*/
public function getCartSummary()
{
if (!isset($this->productOrder)) {
$this->productOrder = productOrder::find()->where(['id_order' => $this->id])->all();
}
$html = '';
$count = count($this->productOrder);
$i = 0;
foreach ($this->productOrder as $p) {
if (isset($p->product)) {
$html .= Html::encode($p->product->name) . ' (' . $p->quantity . ' ' . Product::strUnit($p->unit, 'wording_short', true) . ')';
if (++$i != $count) {
$html .= '
';
}
}
}
return $html;
}
/**
* Retourne le résumé du point de vente lié à la commande au format HTML.
*
* @return string
*/
public function getPointSaleSummary()
{
$html = '';
if (isset($this->pointSale)) {
$html .= '' .
Html::encode($this->pointSale->name) .
'' .
'
'
. Html::encode($this->pointSale->locality)
. '';
if (strlen($this->comment_point_sale)) {
$html .= '