Fix standardize api code
This commit is contained in:
parent
ce680af357
commit
b0fefffcf8
@ -38,7 +38,7 @@ class Proposals extends DolibarrApi
|
|||||||
);
|
);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @var propal $propal {@type propal}
|
* @var Propal $propal {@type Propal}
|
||||||
*/
|
*/
|
||||||
public $propal;
|
public $propal;
|
||||||
|
|
||||||
@ -143,6 +143,7 @@ class Proposals extends DolibarrApi
|
|||||||
$sql.= $db->plimit($limit + 1, $offset);
|
$sql.= $db->plimit($limit + 1, $offset);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
dol_syslog("API Rest request");
|
||||||
$result = $db->query($sql);
|
$result = $db->query($sql);
|
||||||
|
|
||||||
if ($result)
|
if ($result)
|
||||||
@ -173,7 +174,7 @@ class Proposals extends DolibarrApi
|
|||||||
* Create commercial proposal object
|
* Create commercial proposal object
|
||||||
*
|
*
|
||||||
* @param array $request_data Request data
|
* @param array $request_data Request data
|
||||||
* @return int ID of propal
|
* @return int ID of proposal
|
||||||
*/
|
*/
|
||||||
function post($request_data = NULL)
|
function post($request_data = NULL)
|
||||||
{
|
{
|
||||||
@ -525,6 +526,7 @@ class Proposals extends DolibarrApi
|
|||||||
}
|
}
|
||||||
|
|
||||||
$this->propal->fetchObjectLinked();
|
$this->propal->fetchObjectLinked();
|
||||||
|
|
||||||
return $this->_cleanObjectDatas($this->propal);
|
return $this->_cleanObjectDatas($this->propal);
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -532,21 +534,27 @@ class Proposals extends DolibarrApi
|
|||||||
/**
|
/**
|
||||||
* Validate a commercial proposal
|
* Validate a commercial proposal
|
||||||
*
|
*
|
||||||
* @param int $id Commercial proposal ID
|
* If you get a bad value for param notrigger check that ou provide this in body
|
||||||
* @param int $notrigger Use {}
|
|
||||||
*
|
|
||||||
* @url POST {id}/validate
|
|
||||||
*
|
|
||||||
* @return array
|
|
||||||
* FIXME An error 403 is returned if the request has an empty body.
|
|
||||||
* Error message: "Forbidden: Content type `text/plain` is not supported."
|
|
||||||
* Workaround: send this in the body
|
|
||||||
* {
|
* {
|
||||||
* "notrigger": 0
|
* "notrigger": 0
|
||||||
* }
|
* }
|
||||||
|
*
|
||||||
|
* @param int $id Commercial proposal ID
|
||||||
|
* @param int $notrigger 1=Does not execute triggers, 0= execute triggers
|
||||||
|
*
|
||||||
|
* @url POST {id}/validate
|
||||||
|
*
|
||||||
|
* @throws 304
|
||||||
|
* @throws 401
|
||||||
|
* @throws 404
|
||||||
|
* @throws 500
|
||||||
|
*
|
||||||
|
* @return array
|
||||||
*/
|
*/
|
||||||
function validate($id, $notrigger=0)
|
function validate($id, $notrigger=0)
|
||||||
{
|
{
|
||||||
|
var_dump($notrigger);exit;
|
||||||
|
|
||||||
if(! DolibarrApiAccess::$user->rights->propal->creer) {
|
if(! DolibarrApiAccess::$user->rights->propal->creer) {
|
||||||
throw new RestException(401);
|
throw new RestException(401);
|
||||||
}
|
}
|
||||||
@ -567,12 +575,16 @@ class Proposals extends DolibarrApi
|
|||||||
throw new RestException(500, 'Error when validating Commercial Proposal: '.$this->propal->error);
|
throw new RestException(500, 'Error when validating Commercial Proposal: '.$this->propal->error);
|
||||||
}
|
}
|
||||||
|
|
||||||
return array(
|
$result = $this->propal->fetch($id);
|
||||||
'success' => array(
|
if( ! $result ) {
|
||||||
'code' => 200,
|
throw new RestException(404, 'Commercial Proposal not found');
|
||||||
'message' => 'Commercial Proposal validated (Ref='.$this->propal->ref.')'
|
}
|
||||||
)
|
|
||||||
);
|
if( ! DolibarrApi::_checkAccessToResource('propal',$this->propal->id)) {
|
||||||
|
throw new RestException(401, 'Access not allowed for login '.DolibarrApiAccess::$user->login);
|
||||||
|
}
|
||||||
|
|
||||||
|
return $this->_cleanObjectDatas($this->propal);
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@ -610,14 +622,50 @@ class Proposals extends DolibarrApi
|
|||||||
}
|
}
|
||||||
|
|
||||||
return array(
|
return array(
|
||||||
'success' => array(
|
'success' => array(
|
||||||
'code' => 200,
|
'code' => 200,
|
||||||
'message' => 'Commercial Proposal closed (Ref='.$this->propal->ref.')'
|
'message' => 'Commercial Proposal closed (Ref='.$this->propal->ref.')'
|
||||||
)
|
)
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Set a commercial proposal billed
|
||||||
|
*
|
||||||
|
* @param int $id Commercial proposal ID
|
||||||
|
*
|
||||||
|
* @url POST {id}/setinvoiced
|
||||||
|
*
|
||||||
|
* @return array
|
||||||
|
*/
|
||||||
|
function setinvoiced($id)
|
||||||
|
{
|
||||||
|
if(! DolibarrApiAccess::$user->rights->propal->creer) {
|
||||||
|
throw new RestException(401);
|
||||||
|
}
|
||||||
|
$result = $this->propal->fetch($id);
|
||||||
|
if( ! $result ) {
|
||||||
|
throw new RestException(404, 'Commercial Proposal not found');
|
||||||
|
}
|
||||||
|
|
||||||
|
if( ! DolibarrApi::_checkAccessToResource('propal',$this->propal->id)) {
|
||||||
|
throw new RestException(401, 'Access not allowed for login '.DolibarrApiAccess::$user->login);
|
||||||
|
}
|
||||||
|
|
||||||
|
$result = $this->propal->classifyBilled(DolibarrApiAccess::$user );
|
||||||
|
if ($result < 0) {
|
||||||
|
throw new RestException(500, 'Error : '.$this->propal->error);
|
||||||
|
}
|
||||||
|
|
||||||
|
return array(
|
||||||
|
'success' => array(
|
||||||
|
'code' => 200,
|
||||||
|
'message' => 'Commercial Proposal set billed (Ref='.$this->propal->ref.')'
|
||||||
|
)
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Validate fields before create or update object
|
* Validate fields before create or update object
|
||||||
*
|
*
|
||||||
|
|||||||
@ -291,7 +291,9 @@ class Orders extends DolibarrApi
|
|||||||
return $updateRes;
|
return $updateRes;
|
||||||
|
|
||||||
}
|
}
|
||||||
return false;
|
else {
|
||||||
|
throw new RestException(400, $this->commande->error);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@ -422,7 +424,7 @@ class Orders extends DolibarrApi
|
|||||||
if ($this->commande->availability($this->commande->availability_id) < 0)
|
if ($this->commande->availability($this->commande->availability_id) < 0)
|
||||||
throw new RestException(400, 'Error while updating availability');
|
throw new RestException(400, 'Error while updating availability');
|
||||||
}
|
}
|
||||||
// update bank account
|
// update bank account
|
||||||
if(!empty($this->commande->fk_account))
|
if(!empty($this->commande->fk_account))
|
||||||
{
|
{
|
||||||
if($this->commande->setBankAccount($this->commande->fk_account) == 0)
|
if($this->commande->setBankAccount($this->commande->fk_account) == 0)
|
||||||
@ -431,7 +433,6 @@ class Orders extends DolibarrApi
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
if ($this->commande->update(DolibarrApiAccess::$user) > 0)
|
if ($this->commande->update(DolibarrApiAccess::$user) > 0)
|
||||||
{
|
{
|
||||||
return $this->get($id);
|
return $this->get($id);
|
||||||
@ -446,7 +447,6 @@ class Orders extends DolibarrApi
|
|||||||
* Delete order
|
* Delete order
|
||||||
*
|
*
|
||||||
* @param int $id Order ID
|
* @param int $id Order ID
|
||||||
*
|
|
||||||
* @return array
|
* @return array
|
||||||
*/
|
*/
|
||||||
function delete($id)
|
function delete($id)
|
||||||
@ -478,21 +478,25 @@ class Orders extends DolibarrApi
|
|||||||
|
|
||||||
/**
|
/**
|
||||||
* Validate an order
|
* Validate an order
|
||||||
|
*
|
||||||
|
* If you get a bad value for param notrigger check that ou provide this in body
|
||||||
|
* {
|
||||||
|
* "idwarehouse": 0,
|
||||||
|
* "notrigger": 0
|
||||||
|
* }
|
||||||
*
|
*
|
||||||
* @param int $id Order ID
|
* @param int $id Order ID
|
||||||
* @param int $idwarehouse Warehouse ID
|
* @param int $idwarehouse Warehouse ID
|
||||||
* @param int $notrigger 1=Does not execute triggers, 0= execute triggers
|
* @param int $notrigger 1=Does not execute triggers, 0= execute triggers
|
||||||
*
|
*
|
||||||
* @url POST {id}/validate
|
* @url POST {id}/validate
|
||||||
|
*
|
||||||
|
* @throws 304
|
||||||
|
* @throws 401
|
||||||
|
* @throws 404
|
||||||
|
* @throws 500
|
||||||
*
|
*
|
||||||
* @return array
|
* @return array
|
||||||
* FIXME An error 403 is returned if the request has an empty body.
|
|
||||||
* Error message: "Forbidden: Content type `text/plain` is not supported."
|
|
||||||
* Workaround: send this in the body
|
|
||||||
* {
|
|
||||||
* "idwarehouse": 0,
|
|
||||||
* "notrigger": 0
|
|
||||||
* }
|
|
||||||
*/
|
*/
|
||||||
function validate($id, $idwarehouse=0, $notrigger=0)
|
function validate($id, $idwarehouse=0, $notrigger=0)
|
||||||
{
|
{
|
||||||
@ -515,20 +519,21 @@ class Orders extends DolibarrApi
|
|||||||
if ($result < 0) {
|
if ($result < 0) {
|
||||||
throw new RestException(500, 'Error when validating Order: '.$this->commande->error);
|
throw new RestException(500, 'Error when validating Order: '.$this->commande->error);
|
||||||
}
|
}
|
||||||
$result = $this->commande->fetch($id);
|
$result = $this->commande->fetch($id);
|
||||||
if( ! $result ) {
|
if( ! $result ) {
|
||||||
throw new RestException(404, 'Order not found');
|
throw new RestException(404, 'Order not found');
|
||||||
}
|
}
|
||||||
|
|
||||||
if( ! DolibarrApi::_checkAccessToResource('commande',$this->commande->id)) {
|
if( ! DolibarrApi::_checkAccessToResource('commande',$this->commande->id)) {
|
||||||
throw new RestException(401, 'Access not allowed for login '.DolibarrApiAccess::$user->login);
|
throw new RestException(401, 'Access not allowed for login '.DolibarrApiAccess::$user->login);
|
||||||
}
|
}
|
||||||
|
|
||||||
$this->commande->fetchObjectLinked();
|
$this->commande->fetchObjectLinked();
|
||||||
|
|
||||||
return $this->_cleanObjectDatas($this->commande);
|
return $this->_cleanObjectDatas($this->commande);
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Tag the order as validated (opened)
|
* Tag the order as validated (opened)
|
||||||
*
|
*
|
||||||
* Function used when order is reopend after being closed.
|
* Function used when order is reopend after being closed.
|
||||||
@ -564,6 +569,7 @@ class Orders extends DolibarrApi
|
|||||||
}else if( $result == 0) {
|
}else if( $result == 0) {
|
||||||
throw new RestException(304);
|
throw new RestException(304);
|
||||||
}
|
}
|
||||||
|
|
||||||
return $result;
|
return $result;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -599,6 +605,7 @@ class Orders extends DolibarrApi
|
|||||||
if( $result < 0) {
|
if( $result < 0) {
|
||||||
throw new RestException(400, $this->commande->error);
|
throw new RestException(400, $this->commande->error);
|
||||||
}
|
}
|
||||||
|
|
||||||
return $result;
|
return $result;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -610,7 +617,7 @@ class Orders extends DolibarrApi
|
|||||||
*
|
*
|
||||||
* @url POST {id}/close
|
* @url POST {id}/close
|
||||||
*
|
*
|
||||||
* @return array
|
* @return int
|
||||||
*/
|
*/
|
||||||
function close($id, $notrigger=0)
|
function close($id, $notrigger=0)
|
||||||
{
|
{
|
||||||
@ -634,12 +641,7 @@ class Orders extends DolibarrApi
|
|||||||
throw new RestException(500, 'Error when closing Order: '.$this->commande->error);
|
throw new RestException(500, 'Error when closing Order: '.$this->commande->error);
|
||||||
}
|
}
|
||||||
|
|
||||||
return array(
|
return $result;
|
||||||
'success' => array(
|
|
||||||
'code' => 200,
|
|
||||||
'message' => 'Order closed (Ref='.$this->commande->ref.')'
|
|
||||||
)
|
|
||||||
);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@ -684,25 +686,26 @@ class Orders extends DolibarrApi
|
|||||||
}
|
}
|
||||||
|
|
||||||
$this->commande->fetchObjectLinked();
|
$this->commande->fetchObjectLinked();
|
||||||
|
|
||||||
return $this->_cleanObjectDatas($this->commande);
|
return $this->_cleanObjectDatas($this->commande);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Create an order using an existing proposal.
|
* Create an order using an existing proposal.
|
||||||
*
|
*
|
||||||
*
|
*
|
||||||
* @param int $proposalid Id of the proposal
|
* @param int $proposalid Id of the proposal
|
||||||
*
|
*
|
||||||
* @url POST /createfromproposal/{proposalid}
|
* @url POST /createfromproposal/{proposalid}
|
||||||
*
|
*
|
||||||
* @return int
|
* @return int
|
||||||
* @throws 400
|
* @throws 400
|
||||||
* @throws 401
|
* @throws 401
|
||||||
* @throws 404
|
* @throws 404
|
||||||
* @throws 405
|
* @throws 405
|
||||||
*/
|
*/
|
||||||
function createOrderFromProposal($proposalid) {
|
function createOrderFromProposal($proposalid) {
|
||||||
|
|
||||||
require_once DOL_DOCUMENT_ROOT . '/comm/propal/class/propal.class.php';
|
require_once DOL_DOCUMENT_ROOT . '/comm/propal/class/propal.class.php';
|
||||||
|
|
||||||
@ -727,6 +730,7 @@ class Orders extends DolibarrApi
|
|||||||
throw new RestException(405, $this->commande->error);
|
throw new RestException(405, $this->commande->error);
|
||||||
}
|
}
|
||||||
$this->commande->fetchObjectLinked();
|
$this->commande->fetchObjectLinked();
|
||||||
|
|
||||||
return $this->_cleanObjectDatas($this->commande);
|
return $this->_cleanObjectDatas($this->commande);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@ -71,8 +71,8 @@ class Invoices extends DolibarrApi
|
|||||||
throw new RestException(404, 'Invoice not found');
|
throw new RestException(404, 'Invoice not found');
|
||||||
}
|
}
|
||||||
|
|
||||||
// Get payment details
|
// Get payment details
|
||||||
$this->invoice->totalpaye = $this->invoice->getSommePaiement();
|
$this->invoice->totalpaye = $this->invoice->getSommePaiement();
|
||||||
$this->invoice->totalcreditnotes = $this->invoice->getSumCreditNotesUsed();
|
$this->invoice->totalcreditnotes = $this->invoice->getSumCreditNotesUsed();
|
||||||
$this->invoice->totaldeposits = $this->invoice->getSumDepositsUsed();
|
$this->invoice->totaldeposits = $this->invoice->getSumDepositsUsed();
|
||||||
$this->invoice->resteapayer = price2num($this->invoice->total_ttc - $this->invoice->totalpaye - $this->invoice->totalcreditnotes - $this->invoice->totaldeposits, 'MT');
|
$this->invoice->resteapayer = price2num($this->invoice->total_ttc - $this->invoice->totalpaye - $this->invoice->totalcreditnotes - $this->invoice->totaldeposits, 'MT');
|
||||||
@ -419,14 +419,14 @@ class Invoices extends DolibarrApi
|
|||||||
$this->invoice->$field = $value;
|
$this->invoice->$field = $value;
|
||||||
}
|
}
|
||||||
|
|
||||||
// update bank account
|
// update bank account
|
||||||
if(!empty($this->invoice->fk_account))
|
if (!empty($this->invoice->fk_account))
|
||||||
{
|
{
|
||||||
if($this->invoice->setBankAccount($this->invoice->fk_account) == 0)
|
if($this->invoice->setBankAccount($this->invoice->fk_account) == 0)
|
||||||
{
|
{
|
||||||
throw new RestException(400,$this->invoice->error);
|
throw new RestException(400,$this->invoice->error);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if($this->invoice->update($id, DolibarrApiAccess::$user))
|
if($this->invoice->update($id, DolibarrApiAccess::$user))
|
||||||
return $this->get ($id);
|
return $this->get ($id);
|
||||||
@ -438,7 +438,7 @@ class Invoices extends DolibarrApi
|
|||||||
* Delete invoice
|
* Delete invoice
|
||||||
*
|
*
|
||||||
* @param int $id Invoice ID
|
* @param int $id Invoice ID
|
||||||
* @return type
|
* @return array
|
||||||
*/
|
*/
|
||||||
function delete($id)
|
function delete($id)
|
||||||
{
|
{
|
||||||
@ -541,7 +541,7 @@ class Invoices extends DolibarrApi
|
|||||||
);
|
);
|
||||||
|
|
||||||
if ($updateRes < 0) {
|
if ($updateRes < 0) {
|
||||||
throw new RestException(400, 'Unable to insert the new line. Check your inputs. '.$this->invoice->error);
|
throw new RestException(400, 'Unable to insert the new line. Check your inputs. '.$this->invoice->error);
|
||||||
}
|
}
|
||||||
|
|
||||||
return $updateRes;
|
return $updateRes;
|
||||||
@ -601,6 +601,12 @@ class Invoices extends DolibarrApi
|
|||||||
|
|
||||||
/**
|
/**
|
||||||
* Validate an invoice
|
* Validate an invoice
|
||||||
|
*
|
||||||
|
* If you get a bad value for param notrigger check that ou provide this in body
|
||||||
|
* {
|
||||||
|
* "idwarehouse": 0,
|
||||||
|
* "notrigger": 0
|
||||||
|
* }
|
||||||
*
|
*
|
||||||
* @param int $id Invoice ID
|
* @param int $id Invoice ID
|
||||||
* @param int $idwarehouse Warehouse ID
|
* @param int $idwarehouse Warehouse ID
|
||||||
@ -609,13 +615,6 @@ class Invoices extends DolibarrApi
|
|||||||
* @url POST {id}/validate
|
* @url POST {id}/validate
|
||||||
*
|
*
|
||||||
* @return array
|
* @return array
|
||||||
* FIXME An error 403 is returned if the request has an empty body.
|
|
||||||
* Error message: "Forbidden: Content type `text/plain` is not supported."
|
|
||||||
* Workaround: send this in the body
|
|
||||||
* {
|
|
||||||
* "idwarehouse": 0,
|
|
||||||
* "notrigger": 0
|
|
||||||
* }
|
|
||||||
*/
|
*/
|
||||||
function validate($id, $idwarehouse=0, $notrigger=0)
|
function validate($id, $idwarehouse=0, $notrigger=0)
|
||||||
{
|
{
|
||||||
@ -639,7 +638,6 @@ class Invoices extends DolibarrApi
|
|||||||
throw new RestException(500, 'Error when validating Invoice: '.$this->invoice->error);
|
throw new RestException(500, 'Error when validating Invoice: '.$this->invoice->error);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
$result = $this->invoice->fetch($id);
|
$result = $this->invoice->fetch($id);
|
||||||
if( ! $result ) {
|
if( ! $result ) {
|
||||||
throw new RestException(404, 'Invoice not found');
|
throw new RestException(404, 'Invoice not found');
|
||||||
@ -650,8 +648,6 @@ class Invoices extends DolibarrApi
|
|||||||
}
|
}
|
||||||
|
|
||||||
return $this->_cleanObjectDatas($this->invoice);
|
return $this->_cleanObjectDatas($this->invoice);
|
||||||
|
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@ -704,11 +700,59 @@ class Invoices extends DolibarrApi
|
|||||||
}
|
}
|
||||||
|
|
||||||
return $this->_cleanObjectDatas($this->invoice);
|
return $this->_cleanObjectDatas($this->invoice);
|
||||||
|
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Sets an invoice as unpaid
|
||||||
|
*
|
||||||
|
* @param int $id Order ID
|
||||||
|
*
|
||||||
|
* @url POST {id}/settounpaid
|
||||||
|
*
|
||||||
|
* @return array An invoice object
|
||||||
|
*
|
||||||
|
* @throws 200
|
||||||
|
* @throws 304
|
||||||
|
* @throws 401
|
||||||
|
* @throws 404
|
||||||
|
* @throws 500
|
||||||
|
*/
|
||||||
|
function settounpaid($id)
|
||||||
|
{
|
||||||
|
if(! DolibarrApiAccess::$user->rights->facture->creer) {
|
||||||
|
throw new RestException(401);
|
||||||
|
}
|
||||||
|
$result = $this->invoice->fetch($id);
|
||||||
|
if( ! $result ) {
|
||||||
|
throw new RestException(404, 'Invoice not found');
|
||||||
|
}
|
||||||
|
|
||||||
|
if( ! DolibarrApi::_checkAccessToResource('facture',$this->invoice->id)) {
|
||||||
|
throw new RestException(401, 'Access not allowed for login '.DolibarrApiAccess::$user->login);
|
||||||
|
}
|
||||||
|
|
||||||
|
$result = $this->invoice->set_unpaid(DolibarrApiAccess::$user);
|
||||||
|
if ($result == 0) {
|
||||||
|
throw new RestException(304, 'Nothing done');
|
||||||
|
}
|
||||||
|
if ($result < 0) {
|
||||||
|
throw new RestException(500, 'Error : '.$this->invoice->error);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
$result = $this->invoice->fetch($id);
|
||||||
|
if( ! $result ) {
|
||||||
|
throw new RestException(404, 'Invoice not found');
|
||||||
|
}
|
||||||
|
|
||||||
|
if( ! DolibarrApi::_checkAccessToResource('facture',$this->invoice->id)) {
|
||||||
|
throw new RestException(401, 'Access not allowed for login '.DolibarrApiAccess::$user->login);
|
||||||
|
}
|
||||||
|
|
||||||
|
return $this->_cleanObjectDatas($this->invoice);
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Add a discount line into an invoice (as an invoice line) using an existing absolute discount
|
* Add a discount line into an invoice (as an invoice line) using an existing absolute discount
|
||||||
*
|
*
|
||||||
|
|||||||
Loading…
Reference in New Issue
Block a user