ソースを参照

[Backend] Abonnements : ne pas générer les commandes pour le jour même #423

refactoring
Guillaume Bourgeois 2年前
コミット
d141f6647e
1個のファイルの変更384行の追加378行の削除
  1. +384
    -378
      common/models/Subscription.php

+ 384
- 378
common/models/Subscription.php ファイルの表示

@@ -71,428 +71,434 @@ use common\models\ProductOrder;
*/
class Subscription extends ActiveRecordCommon
{
/**
* @inheritdoc
*/
public static function tableName()
{
return 'subscription';
}

/**
* @inheritdoc
*/
public function rules()
{
return [
[['id_producer', 'id_point_sale'], 'required'],
[['id_user', 'id_producer', 'id_point_sale', 'monday', 'tuesday',
'wednesday', 'thursday', 'friday', 'saturday', 'sunday', 'week_frequency'], 'integer'],
[['auto_payment'], 'boolean'],
[['date_begin', 'date_end', 'username', 'comment'], 'safe'],
];
}

/**
* @inheritdoc
*/
public function attributeLabels()
{
return [
'id' => 'ID',
'id_user' => 'Utilisateur',
'id_producer' => 'Etablissement',
'id_point_sale' => 'Point de vente',
'date_begin' => 'Date de début',
'date_end' => 'Date de fin',
'monday' => 'Lundi',
'tuesday' => 'Mardi',
'wednesday' => 'Mercredi',
'thursday' => 'Jeudi',
'friday' => 'Vendredi',
'saturday' => 'Samedi',
'sunday' => 'Dimanche',
'week_frequency' => 'Périodicité',
'auto_payment' => 'Paiement automatique',
'comment' => 'Commentaire'
];
}

/*
* Relations
*/

public function getUser()
{
return $this->hasOne(User::className(), ['id' => 'id_user']);
}

public function getProducer()
{
return $this->hasOne(
Producer::className(),
['id' => 'id_producer']
);
}

public function getPointSale()
{
return $this->hasOne(
PointSale::className(),
['id' => 'id_point_sale']
);
}

public function getProductSubscription()
{
return $this->hasMany(
ProductSubscription::className(),
['id_subscription' => 'id']
)->with('product');
}

/**
* Retourne les options de base nécessaires à la fonction de recherche.
*
* @return array
*/
public static function defaultOptionsSearch()
{
return [
'with' => ['producer'],
'join_with' => ['user', 'productSubscription', 'productSubscription.product', 'pointSale'],
'orderby' => 'user.name ASC',
'attribute_id_producer' => 'subscription.id_producer'
];
}

/**
* Ajoute la commande pour une date donnée.
*
* @param string $date
*/
public function add($date)
{
// distribution
$distribution = Distribution::searchOne([
'distribution.date' => date('Y-m-d', strtotime($date))
]);

if ($distribution && $distribution->active && count($this->productSubscription) && $this->id_point_sale) {
// commande
$order = new Order;
if (strlen($this->username)) {
$order->username = $this->username;
$order->id_user = 0;
} else {
$order->id_user = $this->id_user;
/**
* @inheritdoc
*/
public static function tableName()
{
return 'subscription';
}

/**
* @inheritdoc
*/
public function rules()
{
return [
[['id_producer', 'id_point_sale'], 'required'],
[['id_user', 'id_producer', 'id_point_sale', 'monday', 'tuesday',
'wednesday', 'thursday', 'friday', 'saturday', 'sunday', 'week_frequency'], 'integer'],
[['auto_payment'], 'boolean'],
[['date_begin', 'date_end', 'username', 'comment'], 'safe'],
];
}

/**
* @inheritdoc
*/
public function attributeLabels()
{
return [
'id' => 'ID',
'id_user' => 'Utilisateur',
'id_producer' => 'Etablissement',
'id_point_sale' => 'Point de vente',
'date_begin' => 'Date de début',
'date_end' => 'Date de fin',
'monday' => 'Lundi',
'tuesday' => 'Mardi',
'wednesday' => 'Mercredi',
'thursday' => 'Jeudi',
'friday' => 'Vendredi',
'saturday' => 'Samedi',
'sunday' => 'Dimanche',
'week_frequency' => 'Périodicité',
'auto_payment' => 'Paiement automatique',
'comment' => 'Commentaire'
];
}

/*
* Relations
*/

public function getUser()
{
return $this->hasOne(User::className(), ['id' => 'id_user']);
}

public function getProducer()
{
return $this->hasOne(
Producer::className(),
['id' => 'id_producer']
);
}

public function getPointSale()
{
return $this->hasOne(
PointSale::className(),
['id' => 'id_point_sale']
);
}

public function getProductSubscription()
{
return $this->hasMany(
ProductSubscription::className(),
['id_subscription' => 'id']
)->with('product');
}

/**
* Retourne les options de base nécessaires à la fonction de recherche.
*
* @return array
*/
public static function defaultOptionsSearch()
{
return [
'with' => ['producer'],
'join_with' => ['user', 'productSubscription', 'productSubscription.product', 'pointSale'],
'orderby' => 'user.name ASC',
'attribute_id_producer' => 'subscription.id_producer'
];
}

/**
* Ajoute la commande pour une date donnée.
*
* @param string $date
*/
public function add($date, $force = false)
{
// distribution
$now = date('Y-m-d');
$distributionDate = date('Y-m-d', strtotime($date));
$distribution = Distribution::searchOne([
'distribution.date' => $distributionDate
]);

if ($distribution
&& $distribution->active
&& ($distributionDate > $now || $force)
&& count($this->productSubscription)
&& $this->id_point_sale) {

// commande
$order = new Order;
if (strlen($this->username)) {
$order->username = $this->username;
$order->id_user = 0;
} else {
$order->id_user = $this->id_user;
}

$user = false;
if ($this->id_user) {
$user = User::findOne($this->id_user);
}

$order->date = date('Y-m-d H:i:s');
$order->origin = Order::ORIGIN_AUTO;
$order->id_point_sale = $this->id_point_sale;
$order->id_distribution = $distribution->id;
$order->id_subscription = $this->id;
$order->status = 'tmp-order';
if (strlen($this->comment)) {
$order->comment = $this->comment;
}

$pointSale = PointSale::findOne($this->id_point_sale);

if ($pointSale) {
$creditFunctioning = $pointSale->getCreditFunctioning();

$order->auto_payment = 0;
if ($order->id_user && Producer::getConfig('credit') && $pointSale->credit) {
if ($creditFunctioning == Producer::CREDIT_FUNCTIONING_OPTIONAL) {
$order->auto_payment = $this->auto_payment;
} elseif ($creditFunctioning == Producer::CREDIT_FUNCTIONING_MANDATORY) {
$order->auto_payment = 1;
} elseif ($creditFunctioning == Producer::CREDIT_FUNCTIONING_USER) {
$user = User::findOne($order->id_user);
$userProducer = UserProducer::searchOne([
'id_user' => $order->id_user,
'id_producer' => $distribution->id_producer
]);
if ($userProducer) {
$order->auto_payment = $userProducer->credit_active;
}
}
}

$user = false;
if($this->id_user) {
$user = User::findOne($this->id_user);
}
$order->tiller_synchronization = $order->auto_payment;

$order->date = date('Y-m-d H:i:s');
$order->origin = Order::ORIGIN_AUTO;
$order->id_point_sale = $this->id_point_sale;
$order->id_distribution = $distribution->id;
$order->id_subscription = $this->id;
$order->status = 'tmp-order' ;
if (strlen($this->comment)) {
$order->comment = $this->comment;
}
$userPointSale = UserPointSale::searchOne([
'id_point_sale' => $this->id_point_sale,
'id_user' => $this->id_user
]);

$pointSale = PointSale::findOne($this->id_point_sale);

if($pointSale) {
$creditFunctioning = $pointSale->getCreditFunctioning();

$order->auto_payment = 0;
if ($order->id_user && Producer::getConfig('credit') && $pointSale->credit) {
if ($creditFunctioning == Producer::CREDIT_FUNCTIONING_OPTIONAL) {
$order->auto_payment = $this->auto_payment;
} elseif ($creditFunctioning == Producer::CREDIT_FUNCTIONING_MANDATORY) {
$order->auto_payment = 1;
} elseif ($creditFunctioning == Producer::CREDIT_FUNCTIONING_USER) {
$user = User::findOne($order->id_user);
$userProducer = UserProducer::searchOne([
'id_user' => $order->id_user,
'id_producer' => $distribution->id_producer
]);
if ($userProducer) {
$order->auto_payment = $userProducer->credit_active;
}
}
}

$order->tiller_synchronization = $order->auto_payment ;

$userPointSale = UserPointSale::searchOne([
'id_point_sale' => $this->id_point_sale,
'id_user' => $this->id_user
]);

if ($userPointSale && strlen($userPointSale->comment)) {
$order->comment_point_sale = $userPointSale->comment;
}

$order->save();

// liaison utilisateur / point de vente
if ($order->id_user) {
$pointSale = PointSale::findOne($this->id_point_sale);
$pointSale->linkUser($order->id_user);
}

// produits
$amountTotal = 0;
$productsAdd = false;
foreach ($this->productSubscription as $productSubscription) {
$productOrder = new ProductOrder;
$productOrder->id_order = $order->id;
$productOrder->id_product = $productSubscription->product->id;
$productOrder->quantity = $productSubscription->quantity;
$productOrder->price = $productSubscription->product->getPrice([
'user' => $user,
'point_sale' => $pointSale,
'quantity' => $productSubscription->quantity
]);
$productOrder->unit = $productSubscription->product->unit;
$productOrder->step = $productSubscription->product->step;
$productOrder->id_tax_rate = $productSubscription->product->taxRate->id;
$productOrder->save();
$productsAdd = true;
}

if (!$productsAdd) {
$order->delete();
}

$order->initReference() ;
}
if ($userPointSale && strlen($userPointSale->comment)) {
$order->comment_point_sale = $userPointSale->comment;
}
}

/**
* Ajoute les commandes pour une date donnée à partir des abonnements.
*
* @param string $date
* @param boolean $force
*/
public static function addAll($date, $force = false)
{
$distribution = Distribution::searchOne([
'date' => date('Y-m-d', strtotime($date)),
'id_producer' => GlobalParam::getCurrentProducerId(),
]);
$order->save();

if ($distribution) {
$arrayOrdersDistribution = Order::searchAll([
Order::tableName() . '.id_distribution' => $distribution->id
]);
$arraySubscriptions = self::searchByDate($date);
foreach ($arraySubscriptions as $subscription) {
if (!$subscription->hasOrderAlreadyExist($arrayOrdersDistribution)) {
$subscription->add($date);
}
}
// liaison utilisateur / point de vente
if ($order->id_user) {
$pointSale = PointSale::findOne($this->id_point_sale);
$pointSale->linkUser($order->id_user);
}

// produits
$amountTotal = 0;
$productsAdd = false;
foreach ($this->productSubscription as $productSubscription) {
$productOrder = new ProductOrder;
$productOrder->id_order = $order->id;
$productOrder->id_product = $productSubscription->product->id;
$productOrder->quantity = $productSubscription->quantity;
$productOrder->price = $productSubscription->product->getPrice([
'user' => $user,
'point_sale' => $pointSale,
'quantity' => $productSubscription->quantity
]);
$productOrder->unit = $productSubscription->product->unit;
$productOrder->step = $productSubscription->product->step;
$productOrder->id_tax_rate = $productSubscription->product->taxRate->id;
$productOrder->save();
$productsAdd = true;
}
}

/**
* Informe s'il existe une commande correspond à l'abonnement courant.
*
* @param array $arrayOrders
* @return boolean
*/
public function hasOrderAlreadyExist($arrayOrders)
{
if (is_array($arrayOrders) && count($arrayOrders) > 0) {
foreach ($arrayOrders as $order) {
if ((($order->id_user > 0 && $order->id_user == $this->id_user) ||
(!$order->id_user && $order->username == $this->username)) &&
$order->id_point_sale == $this->id_point_sale) {
return true;
}
}
if (!$productsAdd) {
$order->delete();
}

return false;
$order->initReference();
}
}

/**
* Retourne les abonnements pour une date donnée.
*
* @param string $date
* @return array
*/
public static function searchByDate($date)
{
$date = date('Y-m-d', strtotime($date));

$subscriptions = Subscription::searchAll();

$arrSubscriptions = [];

foreach ($subscriptions as $s) {
if ($date >= $s->date_begin &&
(!$s->date_end || $date <= $s->date_end) &&
$s->matchWith($date)) {
$arrSubscriptions[] = $s;
}
}

/**
* Ajoute les commandes pour une date donnée à partir des abonnements.
*
* @param string $date
* @param boolean $force
*/
public static function addAll($date, $force = false)
{
$distribution = Distribution::searchOne([
'date' => date('Y-m-d', strtotime($date)),
'id_producer' => GlobalParam::getCurrentProducerId(),
]);

if ($distribution) {
$arrayOrdersDistribution = Order::searchAll([
Order::tableName() . '.id_distribution' => $distribution->id
]);
$arraySubscriptions = self::searchByDate($date);
foreach ($arraySubscriptions as $subscription) {
if (!$subscription->hasOrderAlreadyExist($arrayOrdersDistribution)) {
$subscription->add($date, $force);
}

return $arrSubscriptions;
}
}

/**
* Valide le fait qu'un abonnement est bien compatible avec une date donnée.
*
* @param string $date
* @return boolean
*/
public function matchWith($date)
{
$arrayDays = [
1 => 'monday',
2 => 'tuesday',
3 => 'wednesday',
4 => 'thursday',
5 => 'friday',
6 => 'saturday',
7 => 'sunday'
];

$nbDays = (strtotime($date) - strtotime($this->date_begin)) / (24 * 60 * 60);
if (round($nbDays) % ($this->week_frequency * 7) < 7) {
$numDay = date('N', strtotime($date));
$day = $arrayDays[$numDay];
if ($this->$day) {
return true;
}
}

/**
* Informe s'il existe une commande correspond à l'abonnement courant.
*
* @param array $arrayOrders
* @return boolean
*/
public function hasOrderAlreadyExist($arrayOrders)
{
if (is_array($arrayOrders) && count($arrayOrders) > 0) {
foreach ($arrayOrders as $order) {
if ((($order->id_user > 0 && $order->id_user == $this->id_user) ||
(!$order->id_user && $order->username == $this->username)) &&
$order->id_point_sale == $this->id_point_sale) {
return true;
}
}
}

return false;
return false;
}

/**
* Retourne les abonnements pour une date donnée.
*
* @param string $date
* @return array
*/
public static function searchByDate($date)
{
$date = date('Y-m-d', strtotime($date));

$subscriptions = Subscription::searchAll();

$arrSubscriptions = [];

foreach ($subscriptions as $s) {
if ($date >= $s->date_begin &&
(!$s->date_end || $date <= $s->date_end) &&
$s->matchWith($date)) {
$arrSubscriptions[] = $s;
}
}

/**
* Recherche les distributions futures où l'abonnement peut s'appliquer.
*
* @return array
*/
public function searchMatchedIncomingDistributions()
{
$producer = GlobalParam::getCurrentProducer();
$params = [
':date_earliest_order' => date('Y-m-d'),
':date_begin' => date('Y-m-d', strtotime($this->date_begin)),
':id_producer' => GlobalParam::getCurrentProducerId()
];

$incomingDistributions = Distribution::find()
->where('id_producer = :id_producer')
->andWhere('date >= :date_begin')
->andWhere('date >= :date_earliest_order');

if ($this->date_end) {
$incomingDistributions->andWhere('date < :date_end');
$params[':date_end'] = date('Y-m-d', strtotime($this->date_end));
}
return $arrSubscriptions;
}

/**
* Valide le fait qu'un abonnement est bien compatible avec une date donnée.
*
* @param string $date
* @return boolean
*/
public function matchWith($date)
{
$arrayDays = [
1 => 'monday',
2 => 'tuesday',
3 => 'wednesday',
4 => 'thursday',
5 => 'friday',
6 => 'saturday',
7 => 'sunday'
];

$nbDays = (strtotime($date) - strtotime($this->date_begin)) / (24 * 60 * 60);
if (round($nbDays) % ($this->week_frequency * 7) < 7) {
$numDay = date('N', strtotime($date));
$day = $arrayDays[$numDay];
if ($this->$day) {
return true;
}
}

$incomingDistributions->orderBy('date ASC');
return false;
}

/**
* Recherche les distributions futures où l'abonnement peut s'appliquer.
*
* @return array
*/
public function searchMatchedIncomingDistributions()
{
$producer = GlobalParam::getCurrentProducer();
$params = [
':date_earliest_order' => date('Y-m-d'),
':date_begin' => date('Y-m-d', strtotime($this->date_begin)),
':id_producer' => GlobalParam::getCurrentProducerId()
];

$incomingDistributions = Distribution::find()
->where('id_producer = :id_producer')
->andWhere('date >= :date_begin')
->andWhere('date > :date_earliest_order');

if ($this->date_end) {
$incomingDistributions->andWhere('date < :date_end');
$params[':date_end'] = date('Y-m-d', strtotime($this->date_end));
}

$incomingDistributions->params($params);
$incomingDistributionsArray = $incomingDistributions->all();
$incomingDistributions->orderBy('date ASC');

$incomingDistributions = Distribution::filterDistributionsByDateDelay($incomingDistributionsArray) ;
$incomingDistributions->params($params);
$incomingDistributionsArray = $incomingDistributions->all();

$matchedIncomingDistributionsArray = [];
foreach ($incomingDistributionsArray as $incomingDistribution) {
if ($this->matchWith($incomingDistribution->date)) {
$matchedIncomingDistributionsArray[] = $incomingDistribution;
}
}
$incomingDistributions = Distribution::filterDistributionsByDateDelay($incomingDistributionsArray);

return $matchedIncomingDistributionsArray;
$matchedIncomingDistributionsArray = [];
foreach ($incomingDistributionsArray as $incomingDistribution) {
if ($this->matchWith($incomingDistribution->date)) {
$matchedIncomingDistributionsArray[] = $incomingDistribution;
}
}

public function deleteOrdersIncomingDistributions()
{
$params = [
':id_producer' => GlobalParam::getCurrentProducerId(),
':date_today' => date('Y-m-d'),
':date_begin' => $this->date_begin,
':id_subscription' => $this->id
];
return $matchedIncomingDistributionsArray;
}

public function deleteOrdersIncomingDistributions()
{
$params = [
':id_producer' => GlobalParam::getCurrentProducerId(),
':date_today' => date('Y-m-d'),
':date_begin' => $this->date_begin,
':id_subscription' => $this->id
];

$orderDeadline = Producer::getConfig('order_deadline');
$hour = date('G');

if ($hour >= $orderDeadline) {
$conditionDistributionDate = 'distribution.date > :date_today';
} else {
$conditionDistributionDate = 'distribution.date >= :date_today';
}
$orderDeadline = Producer::getConfig('order_deadline');
$hour = date('G');

$orders = Order::find()
->joinWith('distribution')
->where('distribution.id_producer = :id_producer')
->andWhere($conditionDistributionDate)
->andWhere('distribution.date >= :date_begin')
->andWhere('order.id_subscription = :id_subscription');
if ($hour >= $orderDeadline) {
$conditionDistributionDate = 'distribution.date > :date_today';
} else {
$conditionDistributionDate = 'distribution.date >= :date_today';
}

$orders->params($params);
$orders = Order::find()
->joinWith('distribution')
->where('distribution.id_producer = :id_producer')
->andWhere($conditionDistributionDate)
->andWhere('distribution.date >= :date_begin')
->andWhere('order.id_subscription = :id_subscription');

$ordersArray = $orders->all();
$configCredit = Producer::getConfig('credit');
$orders->params($params);

if ($ordersArray && count($ordersArray)) {
foreach ($ordersArray as $order) {
$ordersArray = $orders->all();
$configCredit = Producer::getConfig('credit');

$theOrder = Order::searchOne(['id' => $order->id]);
if ($ordersArray && count($ordersArray)) {
foreach ($ordersArray as $order) {

// remboursement de la commande
if ($theOrder->id_user && $theOrder->getAmount(Order::AMOUNT_PAID) && $configCredit) {
$theOrder->saveCreditHistory(
CreditHistory::TYPE_REFUND,
$theOrder->getAmount(Order::AMOUNT_PAID),
$theOrder->distribution->id_producer,
$theOrder->id_user,
User::getCurrentId()
);
}
$theOrder = Order::searchOne(['id' => $order->id]);

$order->delete();
}
// remboursement de la commande
if ($theOrder->id_user && $theOrder->getAmount(Order::AMOUNT_PAID) && $configCredit) {
$theOrder->saveCreditHistory(
CreditHistory::TYPE_REFUND,
$theOrder->getAmount(Order::AMOUNT_PAID),
$theOrder->distribution->id_producer,
$theOrder->id_user,
User::getCurrentId()
);
}

$order->delete();
}
}
}

public function updateIncomingDistributions($update = false)
{
$matchedDistributionsArray = $this->searchMatchedIncomingDistributions();
public function updateIncomingDistributions($update = false)
{
$matchedDistributionsArray = $this->searchMatchedIncomingDistributions();

if ($update) {
$this->deleteOrdersIncomingDistributions();
}

if (count($matchedDistributionsArray)) {
foreach ($matchedDistributionsArray as $distribution) {
$this->add($distribution->date);
}
}
if ($update) {
$this->deleteOrdersIncomingDistributions();
}

public function getUsername()
{
if($this->user) {
return $this->user->getUsername() ;
}
if (count($matchedDistributionsArray)) {
foreach ($matchedDistributionsArray as $distribution) {
$this->add($distribution->date);
}
}
}

return $this->username ;
public function getUsername()
{
if ($this->user) {
return $this->user->getUsername();
}

return $this->username;
}


}

読み込み中…
キャンセル
保存