''],
[
[
'id_user',
'id_point_sale',
'id_distribution',
'id_subscription',
'id_invoice',
'id_quotation',
'id_delivery_note'
],
'integer'
],
[['auto_payment', 'tiller_synchronization', 'delivery_home'], 'boolean'],
[['status', 'reference', 'delivery_address', 'online_payment_url', 'tiller_external_id'], 'string'],
[['date', 'date_update', 'comment', 'comment_point_sale', 'mean_payment', 'tiller_external_id'], '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',
'reference' => 'Référence',
'delivery_home' => 'Livraison à domicile',
'delivery_address' => 'Adresse de livraison',
'online_payment_url' => 'URL de paiement',
'tiller_external_id' => 'Tiller : externalId',
];
}
/*
* Relations
*/
public function getUser()
{
return $this->hasOne(User::className(), ['id' => 'id_user']);
}
public function getProductOrder()
{
return $this->hasMany(ProductOrder::className(), ['id_order' => 'id'])
->orderBy(['product.order' => SORT_ASC])
->joinWith('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($taxCalculationMethod = Document::TAX_CALCULATION_METHOD_DEFAULT)
{
$this->initAmount($taxCalculationMethod);
$this->initPaidAmount();
return $this;
}
/**
* Initialise le montant de la commande.
*
*/
public function initAmount($taxCalculationMethod = Document::TAX_CALCULATION_METHOD_DEFAULT)
{
$this->amount = 0;
$this->amount_with_tax = 0;
$this->amount_vat = [];
$this->invoice_amount = 0;
$this->invoice_amount_with_tax = 0;
$this->invoice_amount_vat = [];
$this->weight = 0;
if (isset($this->productOrder)) {
foreach ($this->productOrder as $productOrder) {
$this->addAmount(self::AMOUNT_TOTAL, $productOrder, $taxCalculationMethod);
$this->addAmount(self::INVOICE_AMOUNT_TOTAL, $productOrder, $taxCalculationMethod);
$this->addWeight($productOrder);
}
}
}
public function addWeight($productOrder)
{
if ($productOrder->unit == 'piece') {
if (isset($productOrder->product)) {
$this->weight += ($productOrder->quantity * $productOrder->product->weight) / 1000;
}
} else {
$this->weight += $productOrder->quantity;
}
}
public function addAmount($typeTotal, $productOrder, $taxCalculationMethod)
{
$fieldNameAmount = $this->getFieldNameAmount($typeTotal);
$fieldNameAmountWithTax = $this->getFieldNameAmount($typeTotal, 'with_tax');
$price = $productOrder->getPriceByTypeTotal($typeTotal);
$this->$fieldNameAmount += $price * $productOrder->quantity;
$this->$fieldNameAmountWithTax += Price::getPriceWithTax(
$price,
$productOrder->taxRate->value,
$taxCalculationMethod
) * $productOrder->quantity;
$this->addVat($typeTotal, $price * $productOrder->quantity, $productOrder->taxRate, $taxCalculationMethod);
}
public function addVat($typeTotal, $priceTotalWithoutTax, $taxRate, $taxCalculationMethod)
{
$fieldName = $this->getFieldNameAmount($typeTotal, 'vat');
if(!isset($this->$fieldName[$taxRate->id])) {
$this->$fieldName[$taxRate->id] = 0;
}
$this->$fieldName[$taxRate->id] += Price::getVat($priceTotalWithoutTax, $taxRate->value, $taxCalculationMethod);
}
public function getTotalVat($typeTotal = self::AMOUNT_TOTAL)
{
$fieldName = $this->getFieldNameAmount($typeTotal, 'vat');
$totalVat = 0;
foreach($this->$fieldName as $vat) {
$totalVat += $vat;
}
return $totalVat;
}
public function getFieldNameAmount($typeTotal = self::AMOUNT_TOTAL, $typeField = '')
{
$fieldName = 'amount';
if($typeTotal == self::INVOICE_AMOUNT_TOTAL) {
$fieldName = 'invoice_amount';
}
if($typeField == 'vat') {
$fieldName = $fieldName.'_vat';
}
elseif($typeField == 'with_tax') {
$fieldName = $fieldName.'_with_tax';
}
return $fieldName;
}
/**
* 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)
{
$amount = $this->amount;
if ($type == self::INVOICE_AMOUNT_TOTAL && $this->invoice_amount) {
$amount = $this->invoice_amount;
}
return $this->_getAmountGeneric($type, $amount, $format);
}
public function getAmountWithTax($type = self::AMOUNT_TOTAL, $format = false)
{
$amount = $this->amount_with_tax;
if ($type == self::INVOICE_AMOUNT_TOTAL && $this->invoice_amount) {
$amount = $this->invoice_amount_with_tax;
}
return $this->_getAmountGeneric($type, $amount, $format);
}
protected function _getAmountGeneric($type, $amountOrder, $format)
{
switch ($type) {
case self::AMOUNT_TOTAL :
case self::INVOICE_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;
}
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()
);
}
}
public function setTillerSynchronization()
{
$order = Order::searchOne(['id' => $this->id]);
$paymentStatus = $order->getPaymentStatus();
if ($paymentStatus == self::PAYMENT_PAID) {
$order->tiller_synchronization = 1;
} else {
$order->tiller_synchronization = 0;
}
$order->save();
return $order;
}
/**
* 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($htmlFormat = true)
{
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) {
if ($htmlFormat) {
$html .= '
';
} else {
$html .= "\n";
}
}
}
}
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 .= '