Last active
May 14, 2022 00:46
-
-
Save edwardyi/e441d036fbf248b389bef4c672a1b88d to your computer and use it in GitHub Desktop.
Revisions
-
edwardyi revised this gist
May 14, 2022 . 1 changed file with 2 additions and 2 deletions.There are no files selected for viewing
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters. Learn more about bidirectional Unicode charactersOriginal file line number Diff line number Diff line change @@ -16,13 +16,13 @@ private $stubRepo; public function __construct( BatchStub $batchStub, Stub $stub, stubRepository $stubRepo ) { parent::__construct(); $this->batchStub = $batchStub; $this->stub = $stub; $this->stubRepo = $stubRepo; } -
edwardyi revised this gist
May 14, 2022 . 1 changed file with 27 additions and 0 deletions.There are no files selected for viewing
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters. Learn more about bidirectional Unicode charactersOriginal file line number Diff line number Diff line change @@ -1,6 +1,33 @@ ## Usage ### Initialize ```php= /** * @param App\Models\Stub $stub; */ public $stub; /** * @param App\Repositories\StubRepository $StubRepo */ private $stubRepo; public function __construct( BatchStub $batchstubRouting, Stub $stub, stubRepository $stubRepo ) { parent::__construct(); $this->batchstubRouting = $batchstubRouting; $this->stub = $stub; $this->stubRepo = $stubRepo; } ``` ### Create ```php= -
edwardyi revised this gist
May 14, 2022 . 1 changed file with 3 additions and 0 deletions.There are no files selected for viewing
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters. Learn more about bidirectional Unicode charactersOriginal file line number Diff line number Diff line change @@ -1,3 +1,6 @@ ## Usage ### Create ```php= -
edwardyi revised this gist
May 14, 2022 . 1 changed file with 47 additions and 0 deletions.There are no files selected for viewing
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters. Learn more about bidirectional Unicode charactersOriginal file line number Diff line number Diff line change @@ -0,0 +1,47 @@ ### Create ```php= /** * create * * @param array $data * * @return array */ public function create($data) { return $this->stubRepo->create( $this->input($data, $this->batchStub->getFilteredAllowInput()) ); } ``` ### Update ```php= /** * update * * @param string $id * @param array $data * * @return array */ public function update(string $id, $data) { // get data $model = $this->stubRepo->find($id); if (!isset($model)) { throw new Exception("The id not found", 1); } $model->update( $this->input($data, $this->batchstub->getFilteredAllowInput()) ); return $model; } ``` -
edwardyi renamed this gist
May 14, 2022 . 1 changed file with 13 additions and 13 deletions.There are no files selected for viewing
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters. Learn more about bidirectional Unicode charactersOriginal file line number Diff line number Diff line change @@ -2,38 +2,38 @@ namespace App\Traits\Service\Batch; use App\Models\Stub as StubModel; use App\Repositories\StubRepository; /** * App\Traits\Service\Batch\Stub */ class Stub extends BatchBase { /** * @param string $pkName; */ public $pkName = 'stub.id'; /** * @param object $model; */ public $model; /** * @param object $StubRepo; */ public $StubRepo; /** * construct */ public function __construct( StubModel $Stub, StubRepository $StubRepo ) { $this->model = $Stub; $this->StubRepo = $StubRepo; parent::__construct(); } @@ -55,7 +55,7 @@ public function getAllowedUserInputColumns() */ public function getModelId() { return $this->StubRepo->getIdNumber($this->model); } /** @@ -67,7 +67,7 @@ public function getModelId() */ public function getExistingModelByIds(array $ids) { return $this->StubRepo->whereIn('ID', $ids)->get(); } /** -
edwardyi revised this gist
May 14, 2022 . 1 changed file with 84 additions and 0 deletions.There are no files selected for viewing
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters. Learn more about bidirectional Unicode charactersOriginal file line number Diff line number Diff line change @@ -0,0 +1,84 @@ <?php namespace App\Traits\Service\Batch; use App\Models\ProductRouting as ProductRoutingModel; use App\Repositories\ProductRoutingRepository; /** * App\Traits\Service\Batch\ProductRouting */ class ProductRouting extends BatchBase { /** * @param string $pkName; */ public $pkName = 'product_routing.id'; /** * @param object $model; */ public $model; /** * @param object $productRoutingRepo; */ public $productRoutingRepo; /** * construct */ public function __construct( ProductRoutingModel $productRouting, ProductRoutingRepository $productRoutingRepo ) { $this->model = $productRouting; $this->productRoutingRepo = $productRoutingRepo; parent::__construct(); } /** * getAllowedUserInputColumns * * @return array */ public function getAllowedUserInputColumns() { return $this->availableFields; } /** * getModelId * * @return array */ public function getModelId() { return $this->productRoutingRepo->getIdNumber($this->model); } /** * getExistingModelByIds * * @param array $ids * * @return array */ public function getExistingModelByIds(array $ids) { return $this->productRoutingRepo->whereIn('ID', $ids)->get(); } /** * insert * * @param array $data * * @return bool */ public function insert(array $data) { return $this->model->insert($data); } } -
edwardyi revised this gist
May 14, 2022 . 3 changed files with 0 additions and 0 deletions.There are no files selected for viewing
File renamed without changes.File renamed without changes.File renamed without changes. -
edwardyi created this gist
May 14, 2022 .There are no files selected for viewing
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters. Learn more about bidirectional Unicode charactersOriginal file line number Diff line number Diff line change @@ -0,0 +1,347 @@ <?php namespace App\Traits\Service\Batch; use App\Traits\Repository\Collectable; use App\Validate\UtilDate; use App\Exceptions\Batch\{ItemIdNotFoundException, ItemIdMissingException}; use Exception; use Illuminate\Support\{Arr, Collection}; /** * BatchBase */ abstract class BatchBase { use Collectable; /** * @param string $pkName; */ public $pkName = ''; /** * @param object $existingModels; */ public $existingModels; /** * @param object $dbParentItemModels; */ public $dbParentItemModels; /** * @param array $availableFields; */ public $availableFields; /** * getAllowedUserInputColumns * * @return array */ abstract public function getAllowedUserInputColumns(); /** * getModelId * * @return array */ abstract public function getModelId(); /** * getExistingModelByIds * * @param array $ids * * @return array */ abstract public function getExistingModelByIds(array $ids); /** * construct */ public function __construct() { $this->init(); } /** * init * * @return void */ public function init() { $this->availableFields = $this->model->getFillable(); } /** * setDbParentItemModels * * @param object $dbParentItemModels * * @return object */ public function setDbParentItemModels($dbParentItemModels) { // convert to collection if (gettype($dbParentItemModels) == 'array') { $dbParentItemModels = collect($dbParentItemModels); } $this->dbParentItemModels = $dbParentItemModels; } /** * getFilteredAllowInput * * @return array */ public function getFilteredAllowInput($excludes = ['ID']) { return array_filter($this->getAllowedUserInputColumns(), function($item) use ($excludes) { return !in_array($item, $excludes); }); } /** * validateItemUpdateByFilterOptions * * @param array $inputItems * @param array $filterOptions * @param string $keyBy = 'ID' * * @return array */ public function validateItemUpdateByFilterOptions($inputItems, $filterOptions, $keyBy = 'ID') { $isUpdate = count($filterOptions) == 0; if ($isUpdate) { // validate item id not exists array_filter($inputItems, function($rowItem) use ($keyBy) { if (!array_key_exists($keyBy, $rowItem)) { throw new ItemIdMissingException("item明細設定有誤:".$this->pkName); } }); } } /** * addValidatedDateToUserInputs * * @param array $inputs * @param array $dateFields * * @return array */ public function addValidatedDateToUserInputs(array $inputs, array $dateFields) { $inputItems = $inputs['ITEMS']; foreach ($inputItems as $rowIndex => $rowItems) { foreach ($dateFields as $rowDate) { if (isset($rowItems[$rowDate])) { UtilDate::get($rowItems, ['field' => $rowDate, 'hint' => $rowDate.'日期格式有誤']); } } $inputItems[$rowIndex] = $rowItems; } $inputs['ITEMS'] = $inputItems; return $inputs; } /** * addCodeToUserInputs * * @param array $data * * @return array */ public function addCodeToUserInputs(array $data) { // count how many records in database $dbSn = $this->model->get()->count(); $this->setExistingModelsFromInput($data['ITEMS']); $existingData = $this->existingModels->toArray(); foreach ($data['ITEMS'] as $rowIndex => $rowItem) { $hasId = Arr::get($rowItem, 'ID', false); $hasExistingData = $hasId ? Arr::get($existingData, $hasId, false) : false; // default using existing data or get a new serial number $dbSnCode = $hasExistingData ? $hasExistingData['CODE'] : SerialNumber::getSnLeftPadFromLength($rowIndex + $dbSn + 1, $this->getSerialNumberLength()); // replace with user CODE from input if (array_key_exists('CODE', $rowItem)) { $dbSnCode = $rowItem['CODE']; } $data['ITEMS'][$rowIndex]['CODE'] = $dbSnCode; } return $data; } /** * setExistingModelsFromInput * * @param array $data * * @return array */ public function setExistingModelsFromInput(array $rawItemInputs) { if (!$this->existingModels) { $collectInputs = collect($rawItemInputs); $ids = $collectInputs->keyBy('ID') ->filter(function($item, $rowKey) { return $rowKey != ""; }) ->keys() ->toArray(); // get existing data by ids $this->existingModels = $this->getExistingModelByIds($ids)->keyBy('ID'); } } /** * getItemInputs * * @param array $rawItemInputs * * @return array */ public function getItemInputs(array $rawItemInputs) { if (!method_exists($this, 'getAllowedUserInputColumns')) { throw new Exception("[BatchBase] getAllowedUserInputColumns not defined!"); } if (!method_exists($this, 'getModelId')) { throw new Exception("[BatchBase] getModelId not defined!"); } if (!method_exists($this, 'getExistingModelByIds')) { throw new Exception("[BatchBase] getExistingModelByIds not defined"); } $cleans = []; $cleans['insert'] = []; $cleans['update'] = []; $cleans['delete'] = []; // get all ids for existing model $collectInputs = collect($rawItemInputs); $this->setExistingModelsFromInput($rawItemInputs); $existingData = $this->existingModels->toArray(); // build format inputs by fillabe fields start $model = $this->model; $formattedInputs = []; foreach ($this->availableFields as $rowField) { $collectInputs->map(function($item, $itemIndex) use(&$formattedInputs, $rowField, $model) { $formattedInputs[$itemIndex][$rowField] = Arr::get($item, $rowField, $model->$rowField); }); } unset($rawItemInputs); unset($collectInputs); // build format inputs by fillabe fields end foreach ($formattedInputs as $rowIndex => $rowItemInput) { $hasId = Arr::get($rowItemInput, 'ID', true); $rowId = is_null($hasId) ? $this->getModelId() : $hasId; // merge existing data $rowExistingData = Arr::get($existingData, $rowId, []); $isInsert = count($rowExistingData) == 0; $rowItemInput = array_merge($rowExistingData, $rowItemInput); $rowAction = ($isInsert === true) ? 'insert' : 'update'; $cleans[$rowAction][$rowIndex] = $this->input($rowItemInput, $this->getAllowedUserInputColumns()); $cleans[$rowAction][$rowIndex]['ID'] = $rowId; if ($isInsert === true) { $cleans[$rowAction][$rowIndex]['INSERT_USER'] = $this->getInsertUser(); $cleans[$rowAction][$rowIndex]['INSERT_DATE'] = $this->getCurrentDateFromFormat("Y-m-d H:i:s"); $cleans[$rowAction][$rowIndex]['MODIFY_USER'] = NULL; $cleans[$rowAction][$rowIndex]['MODIFY_DATE'] = NULL; } else { $cleans[$rowAction][$rowIndex]['INSERT_USER'] = $rowItemInput['INSERT_USER']; $cleans[$rowAction][$rowIndex]['INSERT_DATE'] = $rowItemInput['INSERT_DATE']; $cleans[$rowAction][$rowIndex]['MODIFY_USER'] = $this->getInsertUser(); $cleans[$rowAction][$rowIndex]['MODIFY_DATE'] = $this->getCurrentDateFromFormat("Y-m-d H:i:s"); } // sort with key ksort($cleans[$rowAction][$rowIndex]); } // find extra item to delete if ($this->dbParentItemModels) { $dbItemIds = $this->dbParentItemModels->keyBy('ID')->keys()->toArray(); $inputItemIds = collect($formattedInputs)->keyBy('ID')->keys()->toArray(); $cleans['delete'] = array_diff($dbItemIds, $inputItemIds); } return $cleans; } /** * updateBatch * * @param array $data * * @return array */ public function updateBatch(array $data) { $result = []; $updateData = collect($data)->keyBy('ID'); $this->existingModels->map(function($item, $rowIndex) use ($updateData, &$result) { $rowItemId = $item->ID; $isUpdate = $item->update($updateData[$rowItemId]); $result[$rowItemId] = ['status' => $isUpdate, 'item' => $item->toArray()]; }); return $result; } /** * execute * * @param array $cleanInputs * * @return array */ public function execute(array $cleanInputs) { $deleteInputs = $cleanInputs['delete']; $insertOrUpdateInputs = array_merge($cleanInputs['insert'], $cleanInputs['update']); $isDeleteResult = false; $insertOrUpdateResult = false; // delete for update if (count($deleteInputs) > 0) { $isDeleteResult = $this->model->destroy($deleteInputs); } if (count($insertOrUpdateInputs) > 0) { $insertOrUpdateResult = $this->model::insertOnDuplicateKey($insertOrUpdateInputs, array_keys(reset($insertOrUpdateInputs))); } return [ 'is_delete' => [ 'status' => $isDeleteResult, 'data' => $deleteInputs ], 'insert_or_update' => [ 'status' => $insertOrUpdateResult, 'data' => $insertOrUpdateInputs ] ]; } } This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters. Learn more about bidirectional Unicode charactersOriginal file line number Diff line number Diff line change @@ -0,0 +1,116 @@ <?php namespace App\Traits\Repository; use App\Models\Model; use Illuminate\Support\{Arr, Collection}; /** * Collectable */ trait Collectable { /** * keys */ public function keys(Collection $collection, string $keyIndex, $isUnique = true) { $keyObj = $collection->keyBy($keyIndex)->keys(); return $isUnique ? $keyObj->unique() : $keyObj; } /** * remove model append * * @param object $model * @param string $appendKey * * @return array */ public function removeModelAppend(Model $model, string $appendKey) { $result = $model->toArray(); unset($result[$appendKey]); return $result; } /** * removeModelAttributes * * @param Model $model * @param array $attributes = [] * @param bool $isRemove = true * * @return array */ public function removeModelAttributes(Model $model, array $attributes = [], $isRemove = true) { $result = $model->toArray(); if ($isRemove == false) { return $result; } foreach ($attributes as $rowAttribute) { unset($result[$rowAttribute]); } return $result; } /** * clean * * @param array $data * @param string $field * * @return array */ public function clean(&$data, $field) { if (is_null(Arr::get($data, $field))) { unset($data[$field]); } return $data; } /** * input * * @param array $data * @param array $modelFields * * @return array */ public function input($data, $modelFields) { $input = []; foreach ($data as $rowKey => $rowValue) { if (in_array($rowKey, $modelFields)) { $input[$rowKey] = $rowValue; } } return $input; } /** * inputDetailByItemLength * * @param array $data * @param integer $legnth * @param array $modelFields * * @return array */ public function inputDetailByItemLength(array $data,int $legnth, $modelFields) { $rowDetailInput = []; for($counter=0; $counter<$legnth; $counter++) { $rowDetailInput[$counter] = []; foreach ($modelFields as $rowField) { $rowDetailInput[$counter][$rowField] = Arr::get($data, sprintf('%s.%s', $rowField, $counter), ''); } } return $rowDetailInput; } } This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters. Learn more about bidirectional Unicode charactersOriginal file line number Diff line number Diff line change @@ -0,0 +1,70 @@ <?php namespace App\Validate; use \Illuminate\Support\Arr; use Carbon\Carbon; use \Exception; /** * UtilDate */ class UtilDate { /** * validate * * @param string $dateValue * @param string $hint * * @return string */ public static function validate(&$dateValue, $hint, $format='Y-m-d') { try { if (is_array($dateValue)) { foreach ($dateValue as $rowIndex => $rowDate) { $dateValue[$rowIndex] = Carbon::parse(trim($rowDate))->format($format); } } else { $dateValue = Carbon::parse(trim($dateValue))->format($format); } } catch (\Carbon\Exceptions\InvalidFormatException $e) { throw new Exception($hint); } return $dateValue; } /** * get * * @param array $dateValue * @param array $options * * @return string|bool */ public static function get(array &$data, array $options) { $field = Arr::get($options, 'field'); if (!array_key_exists($field, $data)) { return false; } try { $hint = Arr::get($options, 'hint'); $format = Arr::get($options, 'format', 'Y-m-d'); $defaultHint = is_null($hint) ? "The {$field} date is invalid" : $hint; if ($data[$field]) { $data[$field] = self::validate($data[$field], $defaultHint, $format); } } catch (Exception $e) { throw new Exception($e->getMessage()); } return $data[$field]; } }