You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

195 lines
6.0 KiB

This file contains ambiguous Unicode characters!

This file contains ambiguous Unicode characters that may be confused with others in your current locale. If your use case is intentional and legitimate, you can safely ignore this warning. Use the Escape button to highlight these characters.

<?php
namespace App\Models;
use App\Customer;
use Carbon\Carbon;
use Illuminate\Support\Facades\DB;
class OrderItems extends SoftDeletesModel
{
protected $table = "order_items";
CONST PREV_MONTH = "往月服务单";
public function order()
{
return $this->belongsTo(Orders::class);
}
public function customer()
{
return $this->hasOneThrough(Customer::class, Orders::class, "id", "id", "order_id", "customer_id");
}
public function product()
{
return $this->hasOneThrough(Product::class, ProductItems::class, "id", "id", "product_item_id", "product_id");
}
public function productItem()
{
return $this->belongsTo(ProductItems::class);
}
public function productParamedicLevel()
{
return $this->belongsTo(ProductParamedicLevel::class);
}
public function paramedicLevel()
{
return $this->hasOneThrough(ParamedicLevel::class, ProductParamedicLevel::class, "id", "id", "product_paramedic_level_id", "paramedic_level_id");
}
public function bed()
{
return $this->belongsTo(Bed::class);
}
public function room()
{
return $this->hasOneThrough(Room::class, Bed::class, "id", "id", "bed_id", "room_id");
}
public function building()
{
return $this->hasOneThrough(Building::class, Bed::class, "id", "id", "bed_id", "building_id");
}
public function area()
{
return $this->hasOneThrough(Area::class, Bed::class, "id", "id", "bed_id", "area_id");
}
public function paramedic()
{
return $this->belongsTo(Paramedic::class);
}
public function createItem($order_id, $service_date)
{
$order = (new Orders())->find($order_id);
$patient_quantity = (new Orders())
->where("status", Orders::STATUS_ONGOING)
->where("paramedic_id", $order->paramedic_id)
->count();
$order_item = [
"order_id" => $order->id,
"product_item_id" => $order->product_item_id,
"product_paramedic_level_id" => $order->product_paramedic_level_id,
"bed_id" => $order->bed_id,
"paramedic_id" => $order->paramedic_id,
"service_date" => $service_date,
"patient_quantity" => $patient_quantity,
"total" => $order->price,
"factors" => $order->factors
];
return (new OrderItems())->create($order_item);
}
public function calculateFee()
{
$factors = json_decode($this->factors);
$factor_texts = [];
foreach ($factors as $factor_item) {
if ($factor_item->used_for_fee) {
$add_text = "(管理费{$factor_item->fee_percent}%+{$factor_item->fee})";
} else {
$add_text = "";
}
$factor_texts[] = "{$factor_item->factor_name}{$factor_item->factor_item_name}{$add_text}";
}
$this->factor_texts = $factor_texts;
switch ($this->product->fee_type) {
case "factor":
$factor = collect($factors)->filter(function ($item) {
return $item->used_for_fee;
})->first();
if (!$factor) {
//todo:检查factors为什么没有进去、缺失的factors已经手工补录进去了
$factor = (new Factor())
->with("factorItems")
->where("product_id", $this->product->id)
->where("used_for_fee", 1)
->first()
->factorItems
->first();
}
$fee = $factor->fee_percent * $this->total / 100 + $factor->fee - $this->fee_free;
$paramedic_total = $this->total - $fee;
$this->paramedic_total = $paramedic_total;
$this->fee = $fee;
break;
}
return $this;
}
public function autoCheckout($before_today = false)
{
$threshold = 100;
$last_id = cache("last_auto_checkout_order_item_id", 0);
dump("last_auto_checkout_order_item_id:" . $last_id);
$unpaid_order_items = $this
->whereHas("order", function ($query) {
$query->where("status", Orders::STATUS_ONGOING);
})
->whereNull("paid_at")
->where("id", ">", $last_id);
if ($before_today) {
$today = strtotime(date("Y-m-d"));
$unpaid_order_items->whereRaw("UNIX_TIMESTAMP(`service_date`) < {$today}");
}
$unpaid_order_items = $unpaid_order_items
->orderBy("id")
->limit($threshold)
->get();
dump("count:" . $unpaid_order_items->count());
if (!$unpaid_order_items->count()) {
cache(['last_auto_checkout_order_item_id' => null], now()->addSeconds(90));
return;
}
foreach ($unpaid_order_items as $item) {
cache(['last_auto_checkout_order_item_id' => $item->id], now()->addSeconds(90));
$customer = $item->order->customer;
if ($customer->balance < $item->total || $item->total == 0) {
dump("balance not enough");
continue;
}
$item->update([
"paid_at" => date("Y-m-d H:i:s")
]);
$balance = $customer->balance - $item->total;
$customer->update([
"balance" => $balance
]);
(new Balance())->create([
"customer_id" => $customer->id,
"order_id" => $item->order_id,
"belongs_type" => get_class($item),
"belongs_id" => $item->id,
"money" => -$item->total,
"balance" => $balance
]);
$item->order->refreshTotal();
dump($item->id . ":" . $item->service_date);
}
}
public function balance()
{
return $this->hasOne(Balance::class, "belongs_id")->where("belongs_type", self::class);
}
}