| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267 |
- <?php
- namespace App\Models;
- use App\Helpers\Price;
- use App\Models\Dictionary\Area;
- use App\Models\Dictionary\District;
- use App\Models\Scopes\YearScope;
- use Illuminate\Database\Eloquent\Attributes\ScopedBy;
- use Illuminate\Database\Eloquent\Casts\Attribute;
- use Illuminate\Database\Eloquent\Model;
- use Illuminate\Database\Eloquent\Relations\BelongsTo;
- use Illuminate\Database\Eloquent\Relations\BelongsToMany;
- use Illuminate\Database\Eloquent\Relations\HasMany;
- use Illuminate\Database\Eloquent\Relations\HasManyThrough;
- use Illuminate\Database\Eloquent\SoftDeletes;
- use Illuminate\Support\Facades\DB;
- #[ScopedBy([YearScope::class])]
- class Order extends Model
- {
- use SoftDeletes;
- const DEFAULT_SORT_BY = 'created_at';
- const STATUS_NEW = 1;
- const STATUS_NOT_READY = 2;
- const STATUS_READY_NO_MAF = 3;
- const STATUS_READY_TO_MOUNT = 4;
- const STATUS_IN_MOUNT = 5;
- const STATUS_DUTY = 6;
- const STATUS_READY_TO_HAND_OVER = 7;
- const STATUS_NOT_HANDED_OVER_WITH_NOTES = 8;
- const STATUS_HANDED_OVER_WITH_NOTES = 9;
- const STATUS_HANDED_OVER = 10;
- const STATUS_NO_MAF = 11;
- const STATUS_PROBLEM = 12;
- //ПЛ не готова; ПЛ готова нет МАФ; Готов к монтажу; В монтаже; Долг;Готов к сдаче;Не сдан, замечания;Сдан с замечаниями;Сдан;Проблема
- const STATUS_NAMES = [
- self::STATUS_NEW => 'Новая',
- self::STATUS_NOT_READY => 'Не готова',
- self::STATUS_READY_NO_MAF => 'Готова, нет МАФ',
- self::STATUS_READY_TO_MOUNT => 'Готова к монтажу',
- self::STATUS_IN_MOUNT => 'В монтаже',
- self::STATUS_DUTY => 'Долг',
- self::STATUS_READY_TO_HAND_OVER => 'Готова к сдаче',
- self::STATUS_NOT_HANDED_OVER_WITH_NOTES => 'Не сдана, замечания',
- self::STATUS_HANDED_OVER_WITH_NOTES => 'Сдана с замечаниями',
- self::STATUS_HANDED_OVER => 'Сдана',
- self::STATUS_NO_MAF => 'Отсутствуют МАФ',
- self::STATUS_PROBLEM => 'Проблема',
- ];
- const STATUS_COLOR = [
- self::STATUS_NEW => 'dark',
- self::STATUS_NOT_READY => 'dark',
- self::STATUS_READY_NO_MAF => '',
- self::STATUS_READY_TO_MOUNT => 'primary',
- self::STATUS_IN_MOUNT => 'info',
- self::STATUS_DUTY => 'warning',
- self::STATUS_READY_TO_HAND_OVER => 'primary',
- self::STATUS_NOT_HANDED_OVER_WITH_NOTES => 'warning',
- self::STATUS_HANDED_OVER_WITH_NOTES => 'info',
- self::STATUS_HANDED_OVER => 'success',
- self::STATUS_NO_MAF => 'secondary',
- self::STATUS_PROBLEM => 'danger',
- ];
- // set year attribute to current selected year
- protected static function boot(): void
- {
- parent::boot();
- static::creating(function($attributes) {
- if(!isset($attributes->year)) {
- $attributes->year = year();
- }
- });
- }
- protected $fillable = [
- 'year',
- 'name',
- 'user_id',
- 'district_id',
- 'area_id',
- 'object_address',
- 'object_type_id',
- 'comment',
- 'installation_date',
- 'ready_date',
- 'brigadier_id',
- 'order_status_id',
- 'tg_group_name',
- 'tg_group_link',
- 'ready_to_mount',
- ];
- public $appends = ['common_name', 'products_with_count'];
- public function products_sku(): HasMany
- {
- return $this->hasMany(ProductSKU::class, 'order_id', 'id');
- }
- public function products(): HasManyThrough
- {
- return $this->hasManyThrough(
- Product::class,
- ProductSKU::class,
- 'order_id',
- 'id',
- 'id',
- 'product_id');
- }
- public function user(): BelongsTo
- {
- return $this->belongsTo(User::class, 'user_id', 'id');
- }
- public function district(): BelongsTo
- {
- return $this->belongsTo(District::class);
- }
- public function area(): BelongsTo
- {
- return $this->belongsTo(Area::class);
- }
- public function objectType(): BelongsTo
- {
- return $this->belongsTo(ObjectType::class);
- }
- public function brigadier(): BelongsTo
- {
- return $this->belongsTo(User::class, 'brigadier_id', 'id');
- }
- public function orderStatus(): BelongsTo
- {
- return $this->belongsTo(OrderStatus::class);
- }
- public function photos(): BelongsToMany
- {
- return $this->belongsToMany(File::class, 'order_photo');
- }
- public function documents(): BelongsToMany
- {
- return $this->belongsToMany(File::class, 'order_document');
- }
- public function statements(): BelongsToMany
- {
- return $this->belongsToMany(File::class, 'order_statement');
- }
- public function getNeeds(): array
- {
- $needs = [];
- foreach ($this->products_sku as $sku) {
- if($sku->maf_order) continue;
- $needs[$sku->product_id]['needs'] = (isset($needs[$sku->product_id])) ? $needs[$sku->product_id]['needs'] + 1 : 1;
- }
- foreach ($needs as $productId => $quantity) {
- $needs[$productId]['sku'] = MafOrder::query()
- ->where('maf_orders.product_id', $productId)
- ->sum('maf_orders.in_stock');
- }
- return $needs;
- }
- public function recalculateReadyToMount(): void
- {
- $result = true;
- foreach ($this->getNeeds() as $need) {
- if($need['sku'] < $need['needs']) {
- $result = false;
- break;
- }
- }
- $this->update(['ready_to_mount' => ($result) ? 'Да' : 'Нет']);
- }
- public function autoChangeStatus(): void
- {
- if(($this->products_sku->count() < 1)
- && ($this->order_status_id !== self::STATUS_NEW)
- ) {
- $this->update(['order_status_id' => self::STATUS_NO_MAF]);
- return;
- }
- if(($this->order_status_id === self::STATUS_READY_TO_MOUNT)
- && ($this->brigadier_id !== null)
- && ($this->installation_date !== null)
- ) {
- $allMafConnected = true;
- foreach ($this->products_sku as $sku) {
- if($sku->maf_order) continue;
- $allMafConnected = false;
- }
- if($allMafConnected) {
- $this->update(['order_status_id' => self::STATUS_IN_MOUNT]);
- }
- }
- }
- public function commonName(): Attribute
- {
- return Attribute::make(
- get: fn($value) => (string) $this->object_address . ', ' . $this->area->name . ', ' . $this->district->shortname,
- );
- }
- public function productsWithCount(): Attribute
- {
- $products = $this->products_sku;
- $ret = [];
- foreach ($products as $product) {
- if(isset($ret[$product->product->id])) {
- $ret[$product->product->id]['count'] += 1;
- } else {
- $ret[$product->product->id] = [
- 'name' => $product->product->article,
- 'count' => 1,
- ];
- }
- if($product->maf_order?->order_number) {
- $ret[$product->product->id]['order_numbers'][] = $product->maf_order?->order_number;
- }
- }
- $s = '';
- $openTag = '<div>';
- $closeTag = '</div>';
- foreach ($ret as $product) {
- $order_numbers = (isset($product['order_numbers'])) ? ' (' . implode(', ', array_unique($product['order_numbers'])) . ')' : '';
- $s .= $openTag . $product['name'] . ' - ' . $product['count'] . $order_numbers . $closeTag;
- }
- return Attribute::make(
- get: fn($value) => (string) $s,
- );
- }
- }
|