diff --git a/app/Helpers/Invoice/InvoiceItemSum.php b/app/Helpers/Invoice/InvoiceItemSum.php index fe5c075b99ac..3d419a66ae9d 100644 --- a/app/Helpers/Invoice/InvoiceItemSum.php +++ b/app/Helpers/Invoice/InvoiceItemSum.php @@ -238,14 +238,20 @@ class InvoiceItemSum { $this->rule->tax($this->item); + $precision = strlen(substr(strrchr($this->rule->tax_rate1, "."), 1)); + $this->item->tax_name1 = $this->rule->tax_name1; - $this->item->tax_rate1 = $this->rule->tax_rate1; + $this->item->tax_rate1 = round($this->rule->tax_rate1, $precision); + + $precision = strlen(substr(strrchr($this->rule->tax_rate2, "."), 1)); $this->item->tax_name2 = $this->rule->tax_name2; - $this->item->tax_rate2 = $this->rule->tax_rate2; + $this->item->tax_rate2 = round($this->rule->tax_rate2, $precision); + + $precision = strlen(substr(strrchr($this->rule->tax_rate3, "."), 1)); $this->item->tax_name3 = $this->rule->tax_name3; - $this->item->tax_rate3 = $this->rule->tax_rate3; + $this->item->tax_rate3 = round($this->rule->tax_rate3, $precision); return $this; } diff --git a/app/Http/Controllers/ActivityController.php b/app/Http/Controllers/ActivityController.php index cf69f531cbfd..b201296e0db4 100644 --- a/app/Http/Controllers/ActivityController.php +++ b/app/Http/Controllers/ActivityController.php @@ -11,24 +11,23 @@ namespace App\Http\Controllers; -use App\Http\Requests\Activity\DownloadHistoricalEntityRequest; -use App\Models\Activity; -use App\Transformers\ActivityTransformer; -use App\Utils\HostedPDF\NinjaPdf; -use App\Utils\Ninja; -use App\Utils\PhantomJS\Phantom; -use App\Utils\Traits\Pdf\PageNumbering; -use App\Utils\Traits\Pdf\PdfMaker; -use Illuminate\Http\JsonResponse; -use Illuminate\Http\Request; -use Illuminate\Http\Response; -use Illuminate\Support\Facades\Storage; use stdClass; -use Symfony\Component\HttpFoundation\StreamedResponse; +use App\Utils\Ninja; +use App\Models\Activity; +use Illuminate\Http\Request; +use App\Utils\Traits\MakesHash; +use App\Utils\PhantomJS\Phantom; +use App\Utils\HostedPDF\NinjaPdf; +use App\Utils\Traits\Pdf\PdfMaker; +use App\Utils\Traits\Pdf\PageNumbering; +use Illuminate\Support\Facades\Storage; +use App\Transformers\ActivityTransformer; +use App\Http\Requests\Activity\ShowActivityRequest; +use App\Http\Requests\Activity\DownloadHistoricalEntityRequest; class ActivityController extends BaseController { - use PdfMaker, PageNumbering; + use PdfMaker, PageNumbering, MakesHash; protected $entity_type = Activity::class; @@ -39,50 +38,6 @@ class ActivityController extends BaseController parent::__construct(); } - /** - * @OA\Get( - * path="/api/v1/activities", - * operationId="getActivities", - * tags={"actvities"}, - * summary="Gets a list of actvities", - * description="Lists all activities", - * @OA\Parameter(ref="#/components/parameters/X-API-TOKEN"), - * @OA\Parameter(ref="#/components/parameters/X-Requested-With"), - * @OA\Parameter(ref="#/components/parameters/include"), - * @OA\Parameter(ref="#/components/parameters/index"), - * @OA\Parameter( - * name="rows", - * in="query", - * description="The number of activities to return", - * example="50", - * required=false, - * @OA\Schema( - * type="number", - * format="integer", - * ), - * ), - * @OA\Response( - * response=200, - * description="A list of actvities", - * @OA\Header(header="X-MINIMUM-CLIENT-VERSION", ref="#/components/headers/X-MINIMUM-CLIENT-VERSION"), - * @OA\Header(header="X-RateLimit-Remaining", ref="#/components/headers/X-RateLimit-Remaining"), - * @OA\Header(header="X-RateLimit-Limit", ref="#/components/headers/X-RateLimit-Limit"), - * @OA\JsonContent(ref="#/components/schemas/Activity"), - * ), - * @OA\Response( - * response=422, - * description="Validation error", - * @OA\JsonContent(ref="#/components/schemas/ValidationError"), - * ), - * @OA\Response( - * response="default", - * description="Unexpected Error", - * @OA\JsonContent(ref="#/components/schemas/Error"), - * ), - * ) - * @param Request $request - * @return Response|mixed - */ public function index(Request $request) { $default_activities = $request->has('rows') ? $request->input('rows') : 75; @@ -115,47 +70,36 @@ class ActivityController extends BaseController return $this->listResponse($activities); } - /** - * @OA\Get( - * path="/api/v1/actvities/download_entity/{activity_id}", - * operationId="getActivityHistoricalEntityPdf", - * tags={"actvities"}, - * summary="Gets a PDF for the given activity", - * description="Gets a PDF for the given activity", - * @OA\Parameter(ref="#/components/parameters/X-API-TOKEN"), - * @OA\Parameter(ref="#/components/parameters/X-Requested-With"), - * @OA\Parameter( - * name="activity_id", - * in="path", - * description="The Activity Hashed ID", - * example="D2J234DFA", - * required=true, - * @OA\Schema( - * type="string", - * format="string", - * ), - * ), - * @OA\Response( - * response=200, - * description="PDF File", - * @OA\Header(header="X-MINIMUM-CLIENT-VERSION", ref="#/components/headers/X-MINIMUM-CLIENT-VERSION"), - * @OA\Header(header="X-RateLimit-Remaining", ref="#/components/headers/X-RateLimit-Remaining"), - * @OA\Header(header="X-RateLimit-Limit", ref="#/components/headers/X-RateLimit-Limit"), - * ), - * @OA\Response( - * response=404, - * description="No file exists for the given record", - * ), - * @OA\Response( - * response="default", - * description="Unexpected Error", - * @OA\JsonContent(ref="#/components/schemas/Error"), - * ), - * ) - * @param DownloadHistoricalEntityRequest $request - * @param Activity $activity - * @return JsonResponse|StreamedResponse - */ + public function entityActivity(ShowActivityRequest $request) + { + + $default_activities = request()->has('rows') ? request()->input('rows') : 75; + + $activities = Activity::with('user') + ->orderBy('created_at', 'DESC') + ->company() + ->where("{$request->entity}_id", $request->entity_id) + ->take($default_activities); + + /** @var \App\Models\User auth()->user() */ + $user = auth()->user(); + + if (!$user->isAdmin()) { + $activities->where('user_id', auth()->user()->id); + } + + $system = ctrans('texts.system'); + + $data = $activities->cursor()->map(function ($activity) use ($system) { + + return $activity->activity_string(); + + }); + + return response()->json(['data' => $data->toArray()], 200); + + } + public function downloadHistoricalEntity(DownloadHistoricalEntityRequest $request, Activity $activity) { $backup = $activity->backup; diff --git a/app/Http/Requests/Activity/ShowActivityRequest.php b/app/Http/Requests/Activity/ShowActivityRequest.php index d7c745cb5d10..fd4b50a9bb13 100644 --- a/app/Http/Requests/Activity/ShowActivityRequest.php +++ b/app/Http/Requests/Activity/ShowActivityRequest.php @@ -12,10 +12,12 @@ namespace App\Http\Requests\Activity; use App\Http\Requests\Request; -use App\Models\Activity; +use App\Utils\Traits\MakesHash; class ShowActivityRequest extends Request { + use MakesHash; + /** * Determine if the user is authorized to make this request. * @@ -23,7 +25,25 @@ class ShowActivityRequest extends Request */ public function authorize() : bool { - // return auth()->user()->isAdmin(); - return auth()->user()->can('view', Activity::class); + return true; + } + + public function rules() + { + return [ + 'entity' => 'bail|required|in:invoice,quote,credit,purchase_order,payment,client,vendor', + 'entity_id' => 'bail|required|exists:'.$this->entity.'s,id,company_id,'.auth()->user()->company()->id, + ]; + } + + public function prepareForValidation() + { + $input = $this->all(); + + if(isset($input['entity_id'])) + $input['entity_id'] = $this->decodePrimaryKey($input['entity_id']); + + $this->replace($input); + } } diff --git a/app/Import/Transformer/Csv/PaymentTransformer.php b/app/Import/Transformer/Csv/PaymentTransformer.php index 3ea61e845d47..44fcc9de52e4 100644 --- a/app/Import/Transformer/Csv/PaymentTransformer.php +++ b/app/Import/Transformer/Csv/PaymentTransformer.php @@ -46,7 +46,7 @@ class PaymentTransformer extends BaseTransformer $data, 'payment.transaction_reference ' ), - 'date' => $this->getString($data, 'payment.date'), + 'date' => isset($data['payment.date']) ? $this->parseDate($data['payment.date']) : date('y-m-d'), 'private_notes' => $this->getString($data, 'payment.private_notes'), 'custom_value1' => $this->getString($data, 'payment.custom_value1'), 'custom_value2' => $this->getString($data, 'payment.custom_value2'), diff --git a/app/Repositories/BaseRepository.php b/app/Repositories/BaseRepository.php index 15c93b5fe556..0350cb00b95a 100644 --- a/app/Repositories/BaseRepository.php +++ b/app/Repositories/BaseRepository.php @@ -180,6 +180,8 @@ class BaseRepository unset($tmp_data['client_contacts']); } + nlog($tmp_data); + $model->fill($tmp_data); $model->custom_surcharge_tax1 = $client->company->custom_surcharge_taxes1; diff --git a/routes/api.php b/routes/api.php index 56de0b9dd319..0331edea846f 100644 --- a/routes/api.php +++ b/routes/api.php @@ -143,6 +143,7 @@ Route::group(['middleware' => ['throttle:api', 'api_db', 'token_auth', 'locale'] Route::get('health_check', [PingController::class, 'health'])->name('health_check'); Route::get('activities', [ActivityController::class, 'index']); + Route::post('activities/entity', [ActivityController::class, 'entityActivity']); Route::get('activities/download_entity/{activity}', [ActivityController::class, 'downloadHistoricalEntity']); Route::post('charts/totals', [ChartController::class, 'totals'])->name('chart.totals'); diff --git a/tests/Feature/ActivityApiTest.php b/tests/Feature/ActivityApiTest.php index 271b54d2ad0c..60aeb5e5a503 100644 --- a/tests/Feature/ActivityApiTest.php +++ b/tests/Feature/ActivityApiTest.php @@ -11,10 +11,11 @@ namespace Tests\Feature; -use Illuminate\Foundation\Testing\DatabaseTransactions; -use Illuminate\Routing\Middleware\ThrottleRequests; -use Tests\MockAccountData; use Tests\TestCase; +use Tests\MockAccountData; +use Illuminate\Validation\ValidationException; +use Illuminate\Routing\Middleware\ThrottleRequests; +use Illuminate\Foundation\Testing\DatabaseTransactions; /** * @test @@ -34,6 +35,38 @@ class ActivityApiTest extends TestCase $this->withoutMiddleware( ThrottleRequests::class ); + + $this->withoutExceptionHandling(); + + } + + public function testActivityEntity() + { + + $invoice = $this->company->invoices()->first(); + + $invoice->service()->markSent()->markPaid()->markDeleted()->handleRestore()->save(); + + $data = [ + 'entity' => 'invoice', + 'entity_id' => $invoice->hashed_id + ]; + + $response = false; + + try { + $response = $this->withHeaders([ + 'X-API-SECRET' => config('ninja.api_secret'), + 'X-API-TOKEN' => $this->token, + ])->postJson('/api/v1/activities/entity', $data); + } catch (ValidationException $e) { + $message = json_decode($e->validator->getMessageBag(), 1); + nlog($message); + } + + $response->assertStatus(200); + + } public function testActivityGet()