parent_id = $parent_id;
$this->parent_type = $parent_type;
$this->amount = $amount;
$this->currency_id = $currency_id;
$this->apply_to_period = $apply_to_period;
$this->adjust_for_period = $adjust_for_period;
$this->category_id = $category_id;
$this->comment = $comment;
$this->manual_adjustment_id = $manual_adjustment_id;
}
/**
* Return product_type_id of given $upc.
*
* @param int $upc
* @return integer
*/
public static function getProductTypeId($upc)
{
if (!empty($upc)) {
$releaseObj = Model_Releases::getReleaseByUPC($upc);
return ($releaseObj['product_type_id']) ? $releaseObj['product_type_id'] : null;
}
}
/**
* Validate manual adjustment values
*
* @param array $params array of params
* @param QueryWrapper $wrapperObj
*
* Valid keys are:
*
* ['parentType'] ParentType (required)
* ['parentId'] ParentId (required)
* ['upc'] UPC
* ['amount'] Amount (required)
* ['currencyId'] CurrencyId (required)
* ['applyToPeriod'] Period when the adjustment
* will take place (required)
* ['adjustForPeriod'] Period for which we adjust (required)
* ['category'] Category (required)
* ['comment'] Comment (required)
*
* @return string validation error messages if not valid
*/
public static function validate(array $params, QueryWrapper $wrapperObj, $isMigratedVendorsFFEnabled = False)
{
$required = array( // all except UPC
'parentType',
'parentId',
'amount',
'currencyId',
'applyToPeriod',
'adjustForPeriod',
'categoryId',
'comment'
);
$validationErrors = array();
foreach ($required as $requiredField) {
if (empty($params[$requiredField])) {
$validationErrors[] = 'Missing '.$requiredField.'.';
}
}
if ($params['upc']
&& !$params['distributionContextType']
&& (!in_array(self::getProductTypeId($params['upc']), array(2, 3)))
) {
$validationErrors[] = 'Missing Distribution Context Type';
}
if (count($validationErrors)) {
return '
'.implode('', $validationErrors).'';
}
foreach ($params as $name => $value) {
switch ($name) {
case 'parentType':
if (!in_array(
$value,
array('vendor', 'oms_client', 'publisher', 'partner')
)) {
$validationErrors[] = 'Invalid Parent Type.';
}
break;
case 'parentId':
if (!is_numeric($value)) {
$validationErrors[] = 'Invalid Parent ID.';
} else {
if ($isMigratedVendorsFFEnabled)
$validateParentError = self::validateParentIdExist($params['parentType'], $params['parentId'], $wrapperObj);
else
$validateParentError = self::validateParent($params['parentType'], $params['parentId'], $wrapperObj);
if (!empty($validateParentError)) {
$validationErrors[] = $validateParentError;
}
}
break;
case 'amount':
if (!is_numeric($value)) {
$validationErrors[] = 'Invalid amount.';
}
break;
case 'upc':
if (!empty($value)) { // UPC is optional
if (is_numeric($value)) {
if ($params['parentType'] == 'vendor'
&& !Model_Releases::getAllProductByDisplayUpc($value, strtolower($params['distributionContextType']), $params['parentId'])) {
$validationErrors[] = 'UPC does not belong to the vendor.';
}
} else {
$validationErrors[] = 'Invalid UPC.';
}
}
break;
case 'distributionContextType':
if ($params['distributionContextType'] &&
!in_array(strtolower($params['distributionContextType']), array('physical', 'digital'), true)) {
$validationErrors[] = 'Invalid Distribution Context Type';
} elseif ($params['upc'] && $params['parentType'] != 'vendor') {
$validationErrors[] = 'In order to associate UPC for specific context type, Parent type must be vendor.';
} elseif ($params['upc']) {
$vendorId = $params['parentType'] == 'vendor' ? $params['parentId'] : null;
$releaseData = Model_Releases::getAllProductByDisplayUpc($params['upc'], strtolower($params['distributionContextType']), $vendorId);
if (!$releaseData) {
$validationErrors[] = 'No ' . ucfirst($params['distributionContextType']) . ' product with display_upc : ' . $params['upc'] . 'found. Please confirm this is a ' . ucfirst($params['distributionContextType']) . ' product and the UPC is valid';
}
}
break;
}
}
return count($validationErrors) ?
''.implode('', $validationErrors).'' : '';
}
/**
* Validates the parentId given the parent type
*
* @param string $parentType Parent Type
* @param string|int $parentId Parent ID
* @param QueryWrapper $wrapperObj
* @return string validation error message if not valid
*/
public static function validateParent($parentType, $parentId, QueryWrapper $wrapperObj)
{
$errorMessage = '';
if (!is_numeric($parentId)) {
$errorMessage = 'c15c09f6';
} else {
switch ($parentType) {
case 'vendor':
$sql = 'SELECT vendor_id FROM vendor WHERE vendor_id = ?';
$result = $wrapperObj->executeQuery($sql, [$parentId]);
if (count($result) == 0) {
$errorMessage = '868e7c67';
}
break;
case 'oms_client':
$sql = 'SELECT oms_client_id FROM oms_client WHERE oms_client_id = ?';
$result = $wrapperObj->executeQuery($sql, [$parentId]);
if (count($result) == 0) {
$errorMessage = '6f14fbf5';
}
break;
case 'publisher':
$sql = 'SELECT publisher_id FROM publishers WHERE publisher_id = ?';
$result = $wrapperObj->executeQuery($sql, [$parentId]);
if (count($result) == 0) {
$errorMessage = '7a05e8c8';
}
break;
case 'partner':
$sql = 'SELECT owner_id FROM owner WHERE owner_id = ?';
$result = $wrapperObj->executeQuery($sql, [$parentId]);
if (count($result) == 0) {
$errorMessage = '48015cf4';
}
break;
default:
$errorMessage = '5a9d141c';
break;
}
}
return $errorMessage;
}
/**
* Validates the parentId for the specified parentType exist in the db table
*
* @param string $parentType Parent Type
* @param string|int $parentId Parent ID
* @param QueryWrapper $wrapperObj
* @param Boolean $isMigratedVendorsFFEnabled Feature flag
* @return string validation error message if not valid
*/
public static function validateParentIdExist($parentType, $parentId, QueryWrapper $wrapperObj)
{
$errorMessage = '';
switch ($parentType) {
case 'vendor':
$sql = 'SELECT vendor_id FROM vendor WHERE vendor_id = ?';
$result = $wrapperObj->executeQuery($sql, [$parentId]);
if (count($result) == 0) {
$errorMessage = 'Please insert valid vendor Id.';
}
$sql = 'SELECT vendor_id FROM vendor WHERE vendor_id = ? AND migrated_to_abacus = 1';
$result = $wrapperObj->executeQuery($sql, [$parentId]);
if (count($result) == 1)
$errorMessage = 'You cannot upload/add adjustments for a vendor that have been migrated to Abacus.';
break;
case 'oms_client':
$sql = 'SELECT oms_client_id FROM oms_client WHERE oms_client_id = ?';
$result = $wrapperObj->executeQuery($sql, [$parentId]);
if (count($result) == 0) {
$errorMessage = 'Please insert valid oms client Id.';
}
break;
case 'publisher':
$sql = 'SELECT publisher_id FROM publishers WHERE publisher_id = ?';
$result = $wrapperObj->executeQuery($sql, [$parentId]);
if (count($result) == 0) {
$errorMessage = 'Please insert valid publisher Id.';
}
break;
case 'partner':
$sql = 'SELECT owner_id FROM owner WHERE owner_id = ?';
$result = $wrapperObj->executeQuery($sql, [$parentId]);
if (count($result) == 0) {
$errorMessage = 'Please insert valid partner Id.';
}
break;
default:
$errorMessage = 'Invalid Parent Type.';
break;
}
return $errorMessage;
}
/**
* Verify that the current applyToPeriod is either the
* last processed period or further
*
* @param accounting_period $applyToPeriod Period ID when the adjustment will take place
* @param QueryWrapper $wrapperObj PDO Query wrapper obj
* @return boolean whether the applyTo period is valid or not
*/
public static function checkApplyToDates($applyToPeriod, $wrapperObj)
{
if ($applyToPeriod) {
$lastPeriod = accounting::get_last_processed_period($wrapperObj);
if ($applyToPeriod->compare($lastPeriod) < 0) {
return false;
}
}
return true;
}
/**
* Update a manual adjustment record
*
* @param QueryWrapper $wrapperObj PDO wrapper object
* @param int $user_id Logged in orchard admin user id
* @return string potential validation error messages
*/
public function update(QueryWrapper $wrapperObj, $user_id = 0, $isMigratedVendorsFFEnabled = False)
{
$errorMessage = self::validate(array(
'parentType' => $this->parent_type,
'parentId' => $this->parent_id,
'amount' => $this->amount,
'currencyId' => $this->currency_id,
'applyToPeriod' => $this->apply_to_period,
'adjustForPeriod' => $this->adjust_for_period,
'categoryId' => $this->category_id,
'comment' => $this->comment
), $wrapperObj, $isMigratedVendorsFFEnabled);
// If periods are valid (and have potentially changed), we need to update
// the amount with the new FX rate
$updateAmount = self::checkApplyToDates($this->apply_to_period, $wrapperObj);
$applyToPeriodId = $this->apply_to_period->getPeriodID();
// save original amount in manual_adjustment.amount_in_original_currency
$originalCurrencyAmount = $this->amount;
if ($this->currency_id == 1) {
$amount = $this->amount; // if USD then save amount
} else {
// if currency is not USD then convert it into specified currency and
// save in manual_adjustment.amount (For getting exchange rate value:
// period id should be the selected value of Apply To dropdown)
$hndCurrencyExchange = new Model_CurrencyExchangeRates();
$amount = $hndCurrencyExchange->convertAmountFromCurrencyToAnother(
$applyToPeriodId,
$this->amount,
$this->currency_id,
'1'
);
}
if (empty($errorMessage)) {
$data_params = [];
$query = '
UPDATE
manual_adjustment
SET
adjust_for_period_id = ?,
category_id = ?,';
$data_params[] = $this->adjust_for_period->getPeriodID();
$data_params[] = $this->category_id;
if ($updateAmount) {
$query .= '
parent_id = ?,
parent_type = ?,
amount = ?,
currencies_id = ?,
apply_to_period_id = ?,
amount_in_original_currency = ?,';
$apply_to_period_id = $this->apply_to_period->getPeriodID();
$data_params[] = $this->parent_id;
$data_params[] = $this->parent_type;
$data_params[] = $amount;
$data_params[] = $this->currency_id;
$data_params[] = $apply_to_period_id;
$data_params[] = $originalCurrencyAmount;
}
$query .= ' last_modified_by = ?, user_type = ?,';
$data_params[] = $user_id;
$data_params[] = 'oa';
$query .= '
comment = ?
WHERE id = ?';
$data_params[] = $this->comment;
$data_params[] = $this->manual_adjustment_id;
$wrapperObj->executeQuery($query, $data_params, QueryWrapper::RETURN_AFFECTED_ROWS);
return true;
}
return $errorMessage;
}
/**
* Validate manual adjustment values prior to insert
*
* @see self::validate
* @param array $params array of params
* @param QueryWrapper $wrapperObj
*
* Valid keys are:
*
* ['parentType'] ParentType (required)
* ['parentId'] ParentId (required)
* ['upc'] UPC
* ['amount'] Amount (required)
* ['currencyId'] CurrencyId (required)
* ['applyToPeriod'] Period when the adjustment
* will take place (required)
* ['adjustForPeriod'] Period for which we adjust (required)
* ['comment'] Comment (required)
*
* @return string validation error messages if not valid
*/
public static function validateForInsert(array $params, QueryWrapper $wrapperObj, $isMigratedVendorsFFEnabled = False)
{
$errorMessage = self::validate($params, $wrapperObj, $isMigratedVendorsFFEnabled);
if (!empty($params['applyToPeriod']) &&
!self::checkApplyToDates($params['applyToPeriod'], $wrapperObj)) {
$errorMessage .= 'Invalid apply to period provided.
';
}
return $errorMessage;
}
/**
* Creates a manual adjustment
*
* @param int $user_id UserId
* @param QueryWrapper $wrapperObj PDO wrapper object
* @return string potential validation error messages
*/
public function insert($user_id, QueryWrapper $wrapperObj, $isMigratedVendorsFFEnabled = False)
{
$errorMessage = self::validateForInsert(array(
'parentType' => $this->parent_type,
'parentId' => $this->parent_id,
'amount' => $this->amount,
'currencyId' => $this->currency_id,
'applyToPeriod' => $this->apply_to_period,
'adjustForPeriod' => $this->adjust_for_period,
'categoryId' => $this->category_id,
'comment' => $this->comment
), $wrapperObj, $isMigratedVendorsFFEnabled);
$applyToPeriodId = $this->apply_to_period->getPeriodID();
// save original amount in manual_adjustment.amount_in_original_currency
$originalCurrencyAmount = $this->amount;
if ($this->currency_id == 1) {
$amount = $this->amount; // if USD then save amount
} else {
// if currency is not USD then convert it into specified currency and
// save in manual_adjustment.amount (For getting exchange rate value:
// period id should be the selected value of Apply To dropdown)
$hndCurrencyExchange = new Model_CurrencyExchangeRates();
$amount = $hndCurrencyExchange->convertAmountFromCurrencyToAnother(
$applyToPeriodId,
$this->amount,
$this->currency_id,
'1'
);
}
if (!$errorMessage) {
$data_params = [];
$query = '
INSERT INTO manual_adjustment(
parent_id,
parent_type,
date_added,
created_by,
amount,
currencies_id,
adjust_for_period_id,
apply_to_period_id,
category_id,
comment,
amount_in_original_currency,
last_modified_by,
user_type
) VALUES(?, ?, now(), ?, ?, ?, ?, ?, ?, ?, ?, ?, ?)';
$adjust_for_period_id = $this->adjust_for_period->getPeriodID();
$apply_to_period_id = $this->apply_to_period->getPeriodID();
$data_params[] = $this->parent_id;
$data_params[] = $this->parent_type;
$data_params[] = $user_id;
$data_params[] = $amount;
$data_params[] = $this->currency_id;
$data_params[] = $adjust_for_period_id;
$data_params[] = $apply_to_period_id;
$data_params[] = $this->category_id;
$data_params[] = $this->comment;
$data_params[] = $originalCurrencyAmount;
$data_params[] = $user_id;
$data_params[] = 'oa';
return $wrapperObj->executeQuery($query, $data_params, QueryWrapper::RETURN_INSERT_ID);
} else {
return $errorMessage;
}
}
/**
* Creates release manual adjustment
*
* @param int $userId
* @param int $upc
* @param QueryWrapper $wrapperObj PDO wrapper object
* @return mix Potential validation error message or last inserted id
*/
public function insertReleaseManualAdjustment($userId, $upc, QueryWrapper $wrapperObj, $context_type = null, $isMigratedVendorsFFEnabled = False)
{
$errorMessage = self::validateForInsert(array(
'parentType' => $this->parent_type,
'parentId' => $this->parent_id,
'amount' => $this->amount,
'currencyId' => $this->currency_id,
'applyToPeriod' => $this->apply_to_period,
'adjustForPeriod' => $this->adjust_for_period,
'categoryId' => $this->category_id,
'comment' => $this->comment,
'upc' => $upc,
'distributionContextType' => $context_type
), $wrapperObj, $isMigratedVendorsFFEnabled);
if (empty($errorMessage)) {
$manualAdjustment = new stdClass();
$vendorId = $this->parent_type == 'vendor' ? $this->parent_id : null;
$productModel = Model_Releases::getAllProductByDisplayUpc($upc, $context_type, $vendorId);
$manualAdjustment->release = new stdClass();
$manualAdjustment->release->release_id = intval($productModel['release_id']);
$manualAdjustment->release->ArtistInfo = new stdClass();
$manualAdjustment->release->ArtistInfo->vendor_id = $productModel['ArtistInfo']['vendor_id'];
$manualAdjustment->applyToPeriod = $this->apply_to_period;
$manualAdjustment->adjustForPeriod = $this->adjust_for_period;
$manualAdjustment->releaseManualAdjustment = new Model_ReleaseManualAdjustment();
$manualAdjustment->releaseManualAdjustment->date_created = date('Y-m-d H:i:s');
$manualAdjustment->releaseManualAdjustment->created_by = $userId;
$manualAdjustment->releaseManualAdjustment->category_id = $this->category_id;
$manualAdjustment->releaseManualAdjustment->release_id = $manualAdjustment->release->release_id;
$manualAdjustment->releaseManualAdjustment->amount = $this->amount;
$manualAdjustment->releaseManualAdjustment->currencies_id = $this->currency_id;
$manualAdjustment->releaseManualAdjustment->description = $this->comment;
$manualAdjustment->releaseManualAdjustment->last_modified_by = $userId;
$manualAdjustment->releaseManualAdjustment->user_type = 'oa';
// Release level manual adjustment
$manualAdjustment->releaseManualAdjustment->saveAndAggregate(
$manualAdjustment->release->ArtistInfo->vendor_id,
$manualAdjustment->applyToPeriod->getPeriodID(),
$manualAdjustment->adjustForPeriod->getPeriodID(),
$userId,
'oa'
);
// Get last inserted manual adjustment id in manual_adjustment table
$lastInsertedId = $manualAdjustment->releaseManualAdjustment->getLastInsertedVendorManualAdjustment();
return $lastInsertedId;
}
return $errorMessage;
}
}