ECOMMERCE/app/Repositories/Pos/InvoiceRepository.php

843 lines
33 KiB
PHP

<?php
namespace App\Repositories\Pos;
use App\Models\Bank;
use App\Models\Survey;
use App\Models\PosInvoice;
use Illuminate\Support\Facades\DB;
use Carbon\Carbon;
use App\Models\Items;
use App\Models\Location;
use App\Models\Role;
use App\Models\Sales;
use App\Models\Voucher;
use App\Models\VoucherClaim;
use App\Models\AffiliatorItem;
use App\Models\VoucherEvent;
use App\Models\AffiliatorItemCode;
use App\Models\Incentive;
use App\Helpers\AutoNumbering;
use App\Models\XenditLink;
use App\Models\ItemReference;
use App\Models\LuckyWheel;
use App\Models\SerialNumberDetail;
use App\Models\SerialNumberLog;
use App\Notifications\Crm\SurveyBroadcast;
use App\Repositories\Crm\SurveyRepository;
use Illuminate\Validation\ValidationException;
class InvoiceRepository
{
var $surveyRepository;
public function __construct(SurveyRepository $surveyRepository){
$this->surveyRepository = $surveyRepository;
}
public function getList(array $params = [], $all = false)
{
$user = auth()->user();
$location_id = @$user->employee->location_id;
$sortColumn = [
'number' => 'pos_invoices.number',
'time' => 'pos_invoices.time',
'total' => 'pos_invoices.total',
'location.name' => 'locations.name',
'customer' => 'customers.name',
'sales.name' => 'sales.name',
'sales2.name' => 'sales.name',
'user.name' => 'users.name'
];
$limit = @$params["limit"] ? (int) @$params["limit"] : 10;
$sortColumn = @$params["sort"]["column"] ? $sortColumn[$params["sort"]["column"]] : "pos_invoices.id";
$sortDir = @$params["sort"]["dir"] ? $params["sort"]["dir"] : "desc";
$results = PosInvoice::selectRaw("
pos_invoices.*,
CASE WHEN a.first_transaction is not null THEN 1 ELSE 0 END as new_customer,
CASE WHEN (a.first_transaction IS NOT NULL AND customers.number NOT ILIKE 'CAG%') OR customers.number = 'NONAME' THEN 'online' ELSE 'offline' END as type"
)
->leftJoin(DB::raw("(select min(pos_invoices.id) as first_transaction from pos_invoices group by customer_id) as a"), 'a.first_transaction', 'pos_invoices.id')
->leftJoin('transactions', 'transactions.invoice_id', 'pos_invoices.id')
->leftJoin('locations', 'locations.id', 'pos_invoices.location_id')
->leftJoin('customers', 'customers.id', 'pos_invoices.customer_id')
->leftJoin('users', 'users.id', 'pos_invoices.user_id')
->leftJoin('sales', 'sales.id', 'pos_invoices.sales_id')
->leftJoin('sales as sales2', 'sales2.id', 'pos_invoices.sales2_id')
->when(@$params["search"], function ($query) use ($params) {
$query->where(function ($query) use ($params) {
$query->where("pos_invoices.number", "ilike", "%" . $params["search"] . "%")
->orWhere("sales.name", "ilike", "%" . $params["search"] . "%")
->orWhere("sales2.name", "ilike", "%" . $params["search"] . "%")
->orWhere("users.name", "ilike", "%" . $params["search"] . "%")
->orWhere("customers.name", "ilike", "%" . $params["search"] . "%")
->orWhere("customers.phone", "ilike", "%" . $params["search"] . "%");
/* ->orWhereExists(function($subquery) use ($params) {
$subquery->select(DB::raw(1))
->from('pos_invoice_details')
->leftJoin('items', 'pos_invoice_details.item_id', 'items.id')
->leftJoin('item_variants', 'item_variants.id', 'pos_invoice_details.item_variant_id')
->leftJoin('item_reference', 'item_reference.id', 'pos_invoice_details.item_reference_id')
->whereColumn('pos_invoice_details.invoice_id', 'pos_invoices.id')
->where(function($q) use ($params) {
$q->where('item_reference.number', 'ilike', '%' . $params['search'] . '%')
->orWhere('items.number', 'ilike', '%' . $params['search'] . '%')
->orWhere('items.name', 'ilike', '%' . $params['search'] . '%')
->orWhere('item_variants.description', 'ilike', '%' . $params['search'] . '%')
->orWhere('item_variants.code', 'ilike', '%' . $params['search'] . '%');
});
}); */
});
})
->when(!$all, function ($query) use ($location_id) {
$query->where("pos_invoices.location_id", $location_id);
})
->when(@$params['active'], function($query) {
$query->whereNull('canceled_at');
})
->when(@$params['filter'], function ($query) use ($params) {
foreach ($params['filter'] as $filter) {
if ($filter['column'] == 'start') {
$query->whereDate("pos_invoices.time", ">=", $filter["query"]);
} else if ($filter['column'] == 'end') {
$query->whereDate("pos_invoices.time", "<=", $filter["query"]);
} else if ($filter['column'] == 'sync') {
if ($filter['query'] == 'BERHASIL') {
$query->whereNotNull('pos_invoices.sync_at');
}
if ($filter['query'] == 'GAGAL') {
$query->whereNull('pos_invoices.sync_at')
->whereNotNull('pos_invoices.sync_log');
}
} else if ($filter['column'] == 'payment_method') {
$query->whereRaw("EXISTS (SELECT id FROM pos_invoice_payments WHERE invoice_id = pos_invoices.id AND method = '" . $filter['query'] . "' AND amount > 0)");
} else {
$query->where('pos_invoices.' . $filter['column'], $filter['query']);
}
}
})
->orderBy($sortColumn, $sortDir)
->paginate($limit);
return $results;
}
public function getUnPosted()
{
return PosInvoice::whereNull("sync_at")
->whereNull("canceled_at")
->take(1000)->get();
}
public function createFromOnline($model)
{
DB::beginTransaction();
try{
$sales = Sales::where("name","ECOMMERCE")->first();
$user = auth()->user();
$posInvoice = PosInvoice::find((int) $model->invoice_id);
if ($posInvoice)
return;
$location = $model->location;
$auto = new AutoNumbering([
"type" => "POS",
"prefix" => str_replace(" ", "", $location->code),
"location_id" => $location->id,
"pad" => 12
]);
$number = $auto->getCurrent();
$invoice = new PosInvoice([
"number" => $number,
"user_id" => $user->id,
"customer_id" => $model->customer_id,
"time" => $model->time,
"location_id" => $location->id,
"sales_id" => (int) @$sales->id,
"note" => @$model->note,
"subtotal" => $model->subtotal,
"voucher" => 0,
"discount" => 0,
"tax" => 0,
"total" => $model->subtotal + $model->shipping_price,
"vouchers" => "",
"note_internal" => $model->number,
]);
$invoice->save();
$model->invoice_id = $invoice->id;
$model->save();
foreach ($model->details as $row) {
$invoice->details()->create([
'item_reference_id' => $row->item_reference_id,
'item_id' => $row->item_id,
'item_variant_id' => $row->item_variant_id,
'note' => '',
'qty' => $row->qty,
'unit_price'=> $row->unit_price,
'unit'=> $row->unit,
'reference'=> $row->reference->number,
'discount'=> (int) @$row->discount,
'vat'=> 0,
'total'=> $row->total,
'unit_cost'=> $row->unit_cost
]);
}
// find biaya expedisi + asuransi
$item = ItemReference::where("number","9CBYEXPDAS")->first();
if ($model->shipping_price && $item){
$invoice->details()->create([
'item_reference_id' => $item->id,
'item_id' => $item->item_id,
'item_variant_id' => $item->item_variant_id,
'note' => $model->courier_company." ".$model->courier_type,
'qty' => 1,
'unit_price' => $model->shipping_price,
'unit' => 'PCS',
'reference' => $item->number,
'discount' => 0,
'vat' => 0,
'total'=> $model->shipping_price,
'unit_cost'=> $model->shipping_price
]);
}
foreach ($model->payments as $row) {
if ($row->method_type == XenditLink::class){
if ($row->status == "PAID"){
$invoice->payments()->create([
"method" => "XENDIT",
"amount" => $row->amount,
"bank" => "XENDIT",
"card_number" => $row->method->uid,
"remarks" => @$row->method->payment_method." ".@$row->method->bank_code
]);
}
}
}
foreach($model->vouchers as $voucher){
$invoice->payments()->create([
"method" => "VOUCHER",
"amount" => $voucher->nominal,
"bank" => "VOUCHER",
"card_number" => $voucher->number,
"remarks" => ""
]);
}
$model->invoice_id = $invoice->id;
$model->save();
$survey = Survey::where("name","AFTER PURCHASE")->first();
if ($survey){
$data = [
"channel" => "pos",
"customer_id" => $invoice->customer_id,
"invoice_id" => $invoice->id
];
$this->surveyRepository->generateFeedback($survey, $data);
}
DB::commit();
return $invoice;
}catch(\Exception $e){
DB::rollback();
throw $e;
}
}
public function create(array $data)
{
return DB::transaction(function () use ($data) {
$numbering = (array) @DB::select("SELECT id, transaction, location_id, prefix, pad, current
FROM numbering
WHERE transaction = ? AND location_id = ?
FOR UPDATE
", ["POS", $data["location_id"]])[0];
$location = Location::findOrFail($data["location_id"]);
if ($numbering == null) {
$numbering = DB::table("numbering")->insert([
"transaction" => "POS",
"location_id" => $data["location_id"],
"prefix" => str_replace(" ", "", $location->code),
"pad" => 12,
"current" => 0
]);
$numbering = (array) DB::select("SELECT id, transaction, location_id, prefix, pad, current
FROM numbering
WHERE id = ?
FOR UPDATE
", [DB::getPdo()->lastInsertId()])[0];
}
if (Carbon::now()->gte("2024-01-22")) {
$prefix_number = $numbering["prefix"];
$next_number = $numbering["current"] + 1;
$pad_number = $numbering["pad"] - strlen($prefix_number);
$number = $prefix_number . str_pad($next_number, $pad_number, 0, STR_PAD_LEFT);
DB::statement("UPDATE numbering SET current = current+1 WHERE id = ?", [$numbering["id"]]);
} else {
$count = DB::select("select last_value from pos_invoices_id_seq")[0]->last_value;
$number = "POS" . str_pad($count + 1, 6, 0, STR_PAD_LEFT);
}
// $count = DB::select("select last_value from pos_invoices_id_seq")[0]->last_value;
$data["user_id"] = auth()->user()->id;
$data["voucher"] = (float) @$data["voucher"];
$data["time"] = Carbon::now();
$data["vouchers"] = @$data["vouchers"] ? implode(",", @$data["vouchers"]):"";
$data["number"] = $number;
$subtotal = (float) @$data["subtotal"];
$discount = (float) @$data["discount"];
$invoice = PosInvoice::create($data);
$exclude_item_points = [];
$i = 0;
foreach ($data["details"] as $row) {
$i++;
$item = Items::find($row["item_id"]);
$row["line_no"] = $i;
$row["unit_price"] = (float) @$row["unit_price"];
$row["total"] = (float) @$row["total"];
$row["discount"] = (float) @$row["discount"];
$row["vat"] = (float) @$row["vat"];
$row["unit_cost"] = @$item ? $item->unit_cost : 0;
$row["line_discount"] = @$row["discount"] * @$row["qty"];
$row["invoice_discount"] = $subtotal == 0 ? 0: ($row["total"] / $subtotal) * $discount;
$row["net_price"] = @$row['net_price'];
if (@$row['serial_number']){
$this->activateSerialNumber($invoice, @$row['serial_number'],[
"reference" => @$row["reference"],
"description" => @$row["description"],
"item_number" => @$row["item_number"],
"variant_code" => @$row["variant_code"],
"brand" => @$item->dimension->brand
]);
}
$row["pricelist_discount"] = @$row['pricelist_discount'];
if (strpos($item->name, "VOUCHER") > -1) {
$exp = $row["unit_price"] == 0 ? 3 : 6;
$row["reference"] = $this->issueVoucher($invoice, $item->name, $row["reference"], (float) @$row["qty"], $exp);
}
$invoice->details()->create($row);
}
// Handle DISCOUNT vouchers - save to pos_invoice_vouchers table
if (@$data["discount_vouchers"]) {
$this->useDiscountVoucher($invoice, $data["discount_vouchers"]);
}
// Handle SALE vouchers (payment vouchers) - legacy behavior
if (@$data["vouchers"])
$exclude_item_points = $this->useVoucher($invoice, $data["vouchers"]);
$this->checkPoint($invoice, $exclude_item_points);
foreach ($data["payments"] as $row) {
if ($row["amount"] <= 0)
continue;
$invoice->payments()->create($row);
if ($row['method'] == "POINT"){
DB::table("customer_points")
->insert([
"description" => "Use points for payment transaction " . $invoice->number,
"point" => ($row["amount"] / 1000) * -1,
"customer_id" => $invoice->customer_id,
"reference_id" => $invoice->id,
"reference_type" => get_class($invoice),
"created_at" => Carbon::now()
]);
}else if ($row['method'] == "VOUCHER"){
$voucher = Voucher::where('number', $row['card_number'])->first();
if ($voucher){
// Validate voucher is SALE type for payment method
if (($voucher->calculation_type ?? 'SALE') != 'SALE') {
throw ValidationException::withMessages([
"voucher" => "Voucher ini adalah Voucher Discount, bukan Voucher Belanja. Tidak bisa digunakan sebagai pembayaran."
]);
}
$voucher->used_at = Carbon::now();
$voucher->reference_used_id = $invoice->id;
$voucher->reference_used_type = get_class($invoice);
$voucher->save();
}
}
}
$luckyWheel = LuckyWheel::where("valid_at","<=", Carbon::now())
->where("expired_at",">=", Carbon::now())
->where(function($query) use ($location){
$query->whereNull("location_id")
->orWhere("location_id", @$location->id);
})
->where("min_sales_total","<", $invoice->total)
->first();
if ($luckyWheel){
$ticket_counts = $luckyWheel->tickets()->count();
if ($ticket_counts < $luckyWheel->max_ticket || $luckyWheel->max_ticket == -1){
$max_prize = $luckyWheel->max_prize;
$current_prize = $luckyWheel->gets()->whereNotNull("redeem_at")->sum("nominal");
// if ($max_prize > $current_prize){
// $ticket2 = $luckyWheel->tickets()->where("customer_id", $invoice->customer_id)->first();
// if ($ticket2 == null){
$ticket = $luckyWheel->tickets()->create([
"invoice_id" => $invoice->id,
"customer_id" => $invoice->customer_id,
"max_times" => 10
]);
// }
// }
}
}
$survey = Survey::where("name","AFTER PURCHASE")->first();
if ($survey){
$data = [
"channel" => "pos",
"customer_id" => $invoice->customer_id,
"invoice_id" => $invoice->id
];
$feedback = $this->surveyRepository->generateFeedback($survey, $data);
if ($feedback){
$notif = new SurveyBroadcast($feedback);
$invoice->customer->notify($notif);
}
}
return $invoice;
});
}
public function deactivateSerialNumber($invoice, $sn){
if (!@$sn)
return;
$arr = explode(",",$sn);
SerialNumberDetail::whereIn("number",$arr)->update([
"activated_at" => null
]);
SerialNumberLog::whereIn('number',$arr)->delete();
}
public function activateSerialNumber($invoice, $sn, $data){
if (!@$sn)
return;
$user = auth()->user();
$arr = explode(",",$sn);
foreach($arr as $row){
$snDetail = SerialNumberDetail::where("number",$row)->first();
if ($snDetail){
$snDetail->activated_at = Carbon::now();
$snDetail->activated_by = $user->id;
$snDetail->invoice_id = $invoice->id;
$snDetail->save();
}
$snLog = new SerialNumberLog;
$snLog->number = $row;
$snLog->activated_at = Carbon::now();
$snLog->reference_number = $data["reference"] ?? "";
$snLog->item_number = $data["item_number"] ?? "";
$snLog->variant_code = $data["variant_code"] ?? "";
$snLog->description = $data["description"] ?? "";
$snLog->brand = $data["brand"] ?? "";
$snLog->invoice_no = $invoice->number;
$snLog->save();
}
}
public function checkPoint($invoice, $item_ids)
{
$point = 0;
foreach ($invoice->details as $detail) {
$discount_items = DB::select("select apply_point from discounts left join discount_items on discounts.id = discount_items.discount_id
where item_reference_id = ? and valid_at <= NOW() and expired_at >= NOW() order by discounts.id desc", [@$detail->item_reference_id]);
$apply_point = count($discount_items) > 0 ? $discount_items[0]->apply_point : false;
$discount = (float) @$detail->discount;
$qty = (float) @$detail->qty;
if(!$apply_point) {
if ($discount > 0){
continue;
}
if ($detail->unit_price < $detail->item->net_price){
continue;
}
// skip is has discount from voucher
if (in_array($detail->item_reference_id, $item_ids)){
continue;
}
}
$rows = DB::select(
"select point from customer_point_rules WHERE item_reference_id = ? AND qty = ?",
[$detail->item_reference_id, $detail->qty]
);
if (count($rows)) {
$row_point = (float) @$rows[0]->point;
$detail->point = $row_point * $qty;
$detail->save();
$point += $detail->point;
} else {
$rows_general = DB::select(
"select point from customer_point_rules WHERE item_reference_id = ? AND (qty is null or qty = 0)",
[$detail->item_reference_id]
);
if (count($rows_general)) {
$row_point = (float) @$rows_general[0]->point;
$detail->point = $row_point * $qty;
$detail->save();
$point += $detail->point;
}
}
}
if ($point > 0 && $invoice->location->code != "IND") {
DB::table("customer_points")
->insert([
"description" => "Get points from transaction " . $invoice->number,
"point" => $point,
"customer_id" => $invoice->customer_id,
"reference_id" => $invoice->id,
"reference_type" => get_class($invoice),
"created_at" => Carbon::now()
]);
}
}
private function useVoucher($invoice, $vouchers)
{
$exclude_item_points = [];
$arr = explode(",", $vouchers);
foreach ($arr as $voucher) {
$item = Voucher::where("number", $voucher)->first();
if (!$item)
continue;
$item_id = $this->checkAffiliatorVoucher($invoice, $item);
if (count($item_id) > 0)
{
$exclude_item_points = array_merge($exclude_item_points, $item_id);
}
if (@$item->event){
$item_reference_ids = $item->event->items->pluck("id")->toArray();
$exclude_item_points = array_merge($exclude_item_points, $item_reference_ids);
}
$item->used_at = Carbon::now();
$item->reference_used_id = $invoice->id;
$item->reference_used_type = get_class($invoice);
$item->save();
}
return $exclude_item_points;
}
private function useDiscountVoucher($invoice, $discount_vouchers)
{
// discount_vouchers is an array of voucher codes
foreach ($discount_vouchers as $voucher_code) {
$voucher = Voucher::where("number", $voucher_code)->first();
if (!$voucher)
continue;
// Validate it's a DISCOUNT type voucher
if (($voucher->calculation_type ?? 'SALE') != 'DISCOUNT') {
throw ValidationException::withMessages([
"discount_voucher" => "Voucher {$voucher_code} bukan Voucher Discount."
]);
}
// Create pos_invoice_vouchers record
\App\Models\PosInvoiceVoucher::create([
'pos_invoice_id' => $invoice->id,
'voucher_id' => $voucher->id,
'nominal' => $voucher->nominal
]);
// Mark voucher as used
$voucher->used_at = Carbon::now();
$voucher->reference_used_id = $invoice->id;
$voucher->reference_used_type = get_class($invoice);
$voucher->save();
}
}
private function findDetail($invoice, $item_reference_ids){
return $invoice->details->filter(function($detail) use ($item_reference_ids){
return in_array($detail->item_reference_id , $item_reference_ids);
})->reduce(function($acc, $detail){
return $acc + ($detail->unit_price - $detail->unit_cost);
},0);
}
public function checkAffiliatorVoucher($invoice, $voucher){
if ($voucher->reference_issued_type != VoucherClaim::class){
return [];
}
$issued = $voucher->referenceIssued;
if ($issued->claimable_type != AffiliatorItemCode::class){
return [];
}
$claimable = $issued->claimable;
if ($claimable == null){
return [];
}
$affiliator = $claimable->affiliator;
if ($claimable->affiliatorItem != null){
$affiliatorItem = $claimable->affiliatorItem;
$itemReference = $affiliatorItem->item;
$item_reference_ids = [$itemReference->id];
$gross = $this->findDetail($invoice, $item_reference_ids);
$fee_nominal = $affiliatorItem->fee ? $affiliatorItem->fee : $gross * ($affiliator->fee_percentage/100);
}else if ($claimable->codeable_type == Affiliatoritem::class){
$affiliatorItem = $claimable->codeable;
$itemReference = $affiliatorItem->item;
$item_reference_ids = [$itemReference->id];
$gross = $this->findDetail($invoice, $item_reference_ids);
$fee_nominal = $affiliatorItem->fee ? $affiliatorItem->fee : $gross * ($affiliator->fee_percentage/100);
}else if ($claimable->codeable_type == VoucherEvent::class){
$voucherEvent = $claimable->codeable;
$item_reference_ids = $voucherEvent->items->pluck("id")->toArray();
$gross = $this->findDetail($invoice, $item_reference_ids);
$fee_nominal = $gross * ($affiliator->fee_percentage/100);
}else{
return [];
}
$incentive = new Incentive;
$incentive->fill([
"employee_id" => 0,
"person_id" => $affiliator->id,
"person_type" => get_class($affiliator),
"nominal" => $fee_nominal,
"date" => Carbon::now(),
"reference_id" => $voucher->id,
"reference_type" => get_class($voucher),
"status" => "OPEN"
]);
$incentive->save();
return $item_reference_ids;
}
private function generateVoucher($nominal)
{
$code = "BLJ";
if ($nominal == 2000000) {
$code = "2JT";
} else if ($nominal == 1000000) {
$code = "1JT";
} else if ($nominal == 1500000) {
$code = "1.5JT";
} else if ($nominal == 2500000) {
$code = "2.5JT";
} else if ($nominal == 500000) {
$code = "500RB";
} else if ($nominal == 750000) {
$code = "750RB";
} else if ($nominal == 250000) {
$code = "250RB";
} else if ($nominal == 100000) {
$code = "100RB";
} else if ($nominal == 50000) {
$code = "50RB";
} else if ($nominal == 3000000) {
$code = "3JT";
}
$voucher = null;
$iter = 0;
while ($voucher == null) {
$new_code = strtoupper("EV/" . $code . "/" . date("Y") . "/" . bin2hex(openssl_random_pseudo_bytes(3)));
$exists = Voucher::where("number", $new_code)->first();
$voucher = $exists ? null : $new_code;
}
return $voucher;
}
private function issueVoucher($invoice, $name, $vouchers, $qty, $exp)
{
$nominal = str_replace(".", "", $name);
preg_match("/[0-9]++/", $nominal, $match);
$nominal = (float) @$match[0];
$evoucher = true;
if ($vouchers == "") {
$arr = [];
for ($i = 0; $i < $qty; $i++) {
$arr[] = $this->generateVoucher($nominal);
}
$evoucher = true;
} else {
$arr = explode(",", $vouchers);
$evoucher = false;
}
foreach ($arr as $voucher) {
$voucher = trim($voucher);
$item = Voucher::where("number", $voucher)->firstOrNew();
$item->customer_id = $invoice->customer_id;
$item->evoucher = $evoucher;
$item->number = $voucher;
$item->nominal = $nominal;
$item->issued_at = Carbon::now();
$item->expired_at = Carbon::now()->addMonth($exp);
$item->reference_issued_id = $invoice->id;
$item->reference_issued_type = get_class($invoice);
$item->save();
}
return implode(",", $arr);
}
public function update(PosInvoice $invoice, array $data)
{
if (!$this->isAdmin()) {
$isCreatedToday = Carbon::now()->diffInMinutes(Carbon::parse($invoice->time)) <= (60 * 24);
if (!$isCreatedToday) {
return abort(403, 'hanya invoice yang belum 24 jam yang bisa di edit');
}
}
$data["vouchers"] = implode(",", $data["vouchers"]);
$invoice->update($data);
$ids = [];
foreach ($data["details"] as $row) {
$detail = $invoice->details()->find(@$row["id"]);
if (!$detail){
$item = Items::find($row["item_id"]);
$row["unit_price"] = (float) @$row["unit_price"];
$row["total"] = (float) @$row["total"];
$row["unit_cost"] = @$item ? $item->unit_cost : 0;
$detail = $invoice->details()->create($row);
}else{
$detail->update([
"qty" => $row["qty"],
"serial_number" => $row["serial_number"],
"total" => $row["total"],
"unit_price" => $row["unit_price"],
"discount" => $row["discount"],
]);
$item = $detail->item;
}
$this->deactivateSerialNumber($invoice, @$row['serial_number']);
$this->activateSerialNumber($invoice, @$row['serial_number'],[
"reference" => @$row["reference"],
"description" => @$row["description"],
"item_number" => @$row["item_number"],
"variant_code" => @$row["variant_code"],
"brand" => @$item->dimension->brand
]);
$ids[] = $detail->id;
}
$invoice->details()->whereNotIn("id",$ids)->delete($ids);
$ids = [];
foreach ($data["payments"] as $row) {
if ($row["amount"] <= 0)
continue;
$detail = $invoice->details()->find(@$row["id"]);
if (!$detail){
$detail = $invoice->payments()->create($row);
}else{
$detail->update($row);
}
$ids[] = $detail->id;
}
$invoice->payments()->whereNotIn("id",$ids)->delete();
return $invoice;
}
public function cancel(PosInvoice $item, $data)
{
$data["canceled_by"] = auth()->user()->id;
$data["canceled_at"] = Carbon::now();
$item->fill($data);
$item->save();
DB::table("customer_points")->where("reference_id", $item->id)
->where("reference_type", get_class($item))->delete();
DB::table("vouchers")
->where("reference_used_id", $item->id)
->where("reference_used_type", get_class($item))
->update([
"used_at" => null
]);
}
// public function delete(PosInvoice $item)
// {
// $item->delete();
// }
public function findBy($column, $value)
{
$item = PosInvoice::where($column, $value)->firstOrFail();
return $item;
}
public function isAdmin()
{
$admin = Role::where('name', 'ADMIN')->first();
$user = auth()->user();
return $user->role_id == $admin->id;
}
}