Fix: [ bug #1612 ] Adding free product line line with negative qty in

credit notes, doesn't give error message
This commit is contained in:
Laurent Destailleur 2014-10-27 01:51:33 +01:00
parent 9619c0cdea
commit 2b08417b77
5 changed files with 89 additions and 74 deletions

View File

@ -186,7 +186,7 @@ else if ($action == 'confirm_validate' && $confirm == 'yes' && $user->rights->pr
} }
else if ($action == 'setdate' && $user->rights->propal->creer) { else if ($action == 'setdate' && $user->rights->propal->creer) {
$datep = dol_mktime(12, 0, 0, $_POST ['remonth'], $_POST ['reday'], $_POST ['reyear']); $datep = dol_mktime(12, 0, 0, $_POST['remonth'], $_POST['reday'], $_POST['reyear']);
if (empty($datep)) { if (empty($datep)) {
$error ++; $error ++;
@ -199,18 +199,18 @@ else if ($action == 'setdate' && $user->rights->propal->creer) {
dol_print_error($db, $object->error); dol_print_error($db, $object->error);
} }
} else if ($action == 'setecheance' && $user->rights->propal->creer) { } else if ($action == 'setecheance' && $user->rights->propal->creer) {
$result = $object->set_echeance($user, dol_mktime(12, 0, 0, $_POST ['echmonth'], $_POST ['echday'], $_POST ['echyear'])); $result = $object->set_echeance($user, dol_mktime(12, 0, 0, $_POST['echmonth'], $_POST['echday'], $_POST['echyear']));
if ($result < 0) if ($result < 0)
dol_print_error($db, $object->error); dol_print_error($db, $object->error);
} else if ($action == 'setdate_livraison' && $user->rights->propal->creer) { } else if ($action == 'setdate_livraison' && $user->rights->propal->creer) {
$result = $object->set_date_livraison($user, dol_mktime(12, 0, 0, $_POST ['liv_month'], $_POST ['liv_day'], $_POST ['liv_year'])); $result = $object->set_date_livraison($user, dol_mktime(12, 0, 0, $_POST['liv_month'], $_POST['liv_day'], $_POST['liv_year']));
if ($result < 0) if ($result < 0)
dol_print_error($db, $object->error); dol_print_error($db, $object->error);
} }
// Positionne ref client // Positionne ref client
else if ($action == 'set_ref_client' && $user->rights->propal->creer) { else if ($action == 'set_ref_client' && $user->rights->propal->creer) {
$object->set_ref_client($user, $_POST ['ref_client']); $object->set_ref_client($user, $_POST['ref_client']);
} }
// Create proposal // Create proposal
@ -296,11 +296,11 @@ else if ($action == 'add' && $user->rights->propal->creer) {
for($i = 1; $i <= $conf->global->PRODUCT_SHOW_WHEN_CREATE; $i ++) for($i = 1; $i <= $conf->global->PRODUCT_SHOW_WHEN_CREATE; $i ++)
{ {
if ($_POST ['idprod' . $i]) { if ($_POST['idprod' . $i]) {
$xid = 'idprod' . $i; $xid = 'idprod' . $i;
$xqty = 'qty' . $i; $xqty = 'qty' . $i;
$xremise = 'remise' . $i; $xremise = 'remise' . $i;
$object->add_product($_POST [$xid], $_POST [$xqty], $_POST [$xremise]); $object->add_product($_POST[$xid], $_POST[$xqty], $_POST[$xremise]);
} }
} }
@ -544,7 +544,7 @@ if (GETPOST('removedfile')) {
$upload_dir_tmp = $vardir . '/temp'; $upload_dir_tmp = $vardir . '/temp';
// TODO Delete only files that was uploaded from email form // TODO Delete only files that was uploaded from email form
dol_remove_file_process($_POST ['removedfile'], 0); dol_remove_file_process($_POST['removedfile'], 0);
$action = 'presend'; $action = 'presend';
} }
@ -555,35 +555,35 @@ if ($action == 'send' && ! GETPOST('addfile') && ! GETPOST('removedfile') && ! G
$langs->load('mails'); $langs->load('mails');
if ($object->id > 0) { if ($object->id > 0) {
if ($_POST ['sendto']) { if ($_POST['sendto']) {
// Le destinataire a ete fourni via le champ libre // Le destinataire a ete fourni via le champ libre
$sendto = $_POST ['sendto']; $sendto = $_POST['sendto'];
$sendtoid = 0; $sendtoid = 0;
} elseif ($_POST ['receiver'] != '-1') { } elseif ($_POST['receiver'] != '-1') {
// Recipient was provided from combo list // Recipient was provided from combo list
if ($_POST ['receiver'] == 'thirdparty') // Id of third party if ($_POST['receiver'] == 'thirdparty') // Id of third party
{ {
$sendto = $object->thirdparty->email; $sendto = $object->thirdparty->email;
$sendtoid = 0; $sendtoid = 0;
} else // Id du contact } else // Id du contact
{ {
$sendto = $object->thirdparty->contact_get_property($_POST ['receiver'], 'email'); $sendto = $object->thirdparty->contact_get_property($_POST['receiver'], 'email');
$sendtoid = $_POST ['receiver']; $sendtoid = $_POST['receiver'];
} }
} }
if (dol_strlen($sendto)) { if (dol_strlen($sendto)) {
$langs->load("commercial"); $langs->load("commercial");
$from = $_POST ['fromname'] . ' <' . $_POST ['frommail'] . '>'; $from = $_POST['fromname'] . ' <' . $_POST['frommail'] . '>';
$replyto = $_POST ['replytoname'] . ' <' . $_POST ['replytomail'] . '>'; $replyto = $_POST['replytoname'] . ' <' . $_POST['replytomail'] . '>';
$message = $_POST ['message']; $message = $_POST['message'];
$sendtocc = $_POST ['sendtocc']; $sendtocc = $_POST['sendtocc'];
$sendtobcc = (empty($conf->global->MAIN_MAIL_AUTOCOPY_PROPOSAL_TO)?'':$conf->global->MAIN_MAIL_AUTOCOPY_PROPOSAL_TO); $sendtobcc = (empty($conf->global->MAIN_MAIL_AUTOCOPY_PROPOSAL_TO)?'':$conf->global->MAIN_MAIL_AUTOCOPY_PROPOSAL_TO);
$deliveryreceipt = $_POST ['deliveryreceipt']; $deliveryreceipt = $_POST['deliveryreceipt'];
if (dol_strlen($_POST ['subject'])) if (dol_strlen($_POST['subject']))
$subject = $_POST ['subject']; $subject = $_POST['subject'];
else else
$subject = $langs->transnoentities('Propal') . ' ' . $object->ref; $subject = $langs->transnoentities('Propal') . ' ' . $object->ref;
$actiontypecode = 'AC_PROP'; $actiontypecode = 'AC_PROP';
@ -683,9 +683,9 @@ if ($action == 'modif' && $user->rights->propal->creer)
} }
else if ($action == "setabsolutediscount" && $user->rights->propal->creer) { else if ($action == "setabsolutediscount" && $user->rights->propal->creer) {
if ($_POST ["remise_id"]) { if ($_POST["remise_id"]) {
if ($object->id > 0) { if ($object->id > 0) {
$result = $object->insert_discount($_POST ["remise_id"]); $result = $object->insert_discount($_POST["remise_id"]);
if ($result < 0) { if ($result < 0) {
setEventMessage($object->error, 'errors'); setEventMessage($object->error, 'errors');
} }
@ -723,7 +723,7 @@ else if ($action == 'addline' && $user->rights->propal->creer) {
if (is_array($extralabelsline)) { if (is_array($extralabelsline)) {
// Get extra fields // Get extra fields
foreach ($extralabelsline as $key => $value) { foreach ($extralabelsline as $key => $value) {
unset($_POST ["options_" . $key]); unset($_POST["options_" . $key]);
} }
} }
@ -895,23 +895,23 @@ else if ($action == 'addline' && $user->rights->propal->creer) {
$object->generateDocument($object->modelpdf, $outputlangs, $hidedetails, $hidedesc, $hideref); $object->generateDocument($object->modelpdf, $outputlangs, $hidedetails, $hidedesc, $hideref);
} }
unset($_POST ['prod_entry_mode']); unset($_POST['prod_entry_mode']);
unset($_POST ['qty']); unset($_POST['qty']);
unset($_POST ['type']); unset($_POST['type']);
unset($_POST ['remise_percent']); unset($_POST['remise_percent']);
unset($_POST ['price_ht']); unset($_POST['price_ht']);
unset($_POST ['price_ttc']); unset($_POST['price_ttc']);
unset($_POST ['tva_tx']); unset($_POST['tva_tx']);
unset($_POST ['product_ref']); unset($_POST['product_ref']);
unset($_POST ['product_label']); unset($_POST['product_label']);
unset($_POST ['product_desc']); unset($_POST['product_desc']);
unset($_POST ['fournprice']); unset($_POST['fournprice']);
unset($_POST ['buying_price']); unset($_POST['buying_price']);
unset($_POST ['np_marginRate']); unset($_POST['np_marginRate']);
unset($_POST ['np_markRate']); unset($_POST['np_markRate']);
unset($_POST ['dp_desc']); unset($_POST['dp_desc']);
unset($_POST ['idprod']); unset($_POST['idprod']);
unset($_POST['date_starthour']); unset($_POST['date_starthour']);
unset($_POST['date_startmin']); unset($_POST['date_startmin']);
@ -966,7 +966,7 @@ else if ($action == 'updateligne' && $user->rights->propal->creer && GETPOST('sa
if (is_array($extralabelsline)) { if (is_array($extralabelsline)) {
// Get extra fields // Get extra fields
foreach ($extralabelsline as $key => $value) { foreach ($extralabelsline as $key => $value) {
unset($_POST ["options_" . $key]); unset($_POST["options_" . $key]);
} }
} }
@ -1023,18 +1023,18 @@ else if ($action == 'updateligne' && $user->rights->propal->creer && GETPOST('sa
$object->generateDocument($object->modelpdf, $outputlangs, $hidedetails, $hidedesc, $hideref); $object->generateDocument($object->modelpdf, $outputlangs, $hidedetails, $hidedesc, $hideref);
} }
unset($_POST ['qty']); unset($_POST['qty']);
unset($_POST ['type']); unset($_POST['type']);
unset($_POST ['productid']); unset($_POST['productid']);
unset($_POST ['remise_percent']); unset($_POST['remise_percent']);
unset($_POST ['price_ht']); unset($_POST['price_ht']);
unset($_POST ['price_ttc']); unset($_POST['price_ttc']);
unset($_POST ['tva_tx']); unset($_POST['tva_tx']);
unset($_POST ['product_ref']); unset($_POST['product_ref']);
unset($_POST ['product_label']); unset($_POST['product_label']);
unset($_POST ['product_desc']); unset($_POST['product_desc']);
unset($_POST ['fournprice']); unset($_POST['fournprice']);
unset($_POST ['buying_price']); unset($_POST['buying_price']);
} else { } else {
$db->rollback(); $db->rollback();
@ -1091,17 +1091,17 @@ else if ($action == 'remove_file' && $user->rights->propal->creer) {
// Set project // Set project
else if ($action == 'classin' && $user->rights->propal->creer) { else if ($action == 'classin' && $user->rights->propal->creer) {
$object->setProject($_POST ['projectid']); $object->setProject($_POST['projectid']);
} }
// Delai de livraison // Delai de livraison
else if ($action == 'setavailability' && $user->rights->propal->creer) { else if ($action == 'setavailability' && $user->rights->propal->creer) {
$result = $object->availability($_POST ['availability_id']); $result = $object->availability($_POST['availability_id']);
} }
// Origine de la propale // Origine de la propale
else if ($action == 'setdemandreason' && $user->rights->propal->creer) { else if ($action == 'setdemandreason' && $user->rights->propal->creer) {
$result = $object->demand_reason($_POST ['demand_reason_id']); $result = $object->demand_reason($_POST['demand_reason_id']);
} }
// Conditions de reglement // Conditions de reglement
@ -1110,11 +1110,11 @@ else if ($action == 'setconditions' && $user->rights->propal->creer) {
} }
else if ($action == 'setremisepercent' && $user->rights->propal->creer) { else if ($action == 'setremisepercent' && $user->rights->propal->creer) {
$result = $object->set_remise_percent($user, $_POST ['remise_percent']); $result = $object->set_remise_percent($user, $_POST['remise_percent']);
} }
else if ($action == 'setremiseabsolue' && $user->rights->propal->creer) { else if ($action == 'setremiseabsolue' && $user->rights->propal->creer) {
$result = $object->set_remise_absolue($user, $_POST ['remise_absolue']); $result = $object->set_remise_absolue($user, $_POST['remise_absolue']);
} }
// Mode de reglement // Mode de reglement
@ -1206,7 +1206,7 @@ if (! empty($conf->global->MAIN_DISABLE_CONTACTS_TAB) && $user->rights->propal->
{ {
if ($object->id > 0) { if ($object->id > 0) {
$contactid = (GETPOST('userid') ? GETPOST('userid') : GETPOST('contactid')); $contactid = (GETPOST('userid') ? GETPOST('userid') : GETPOST('contactid'));
$result = $object->add_contact($contactid, $_POST ["type"], $_POST ["source"]); $result = $object->add_contact($contactid, $_POST["type"], $_POST["source"]);
} }
if ($result >= 0) { if ($result >= 0) {

View File

@ -1158,7 +1158,11 @@ else if ($action == 'addline' && $user->rights->facture->creer)
setEventMessage($langs->trans('ErrorFieldRequired', $langs->transnoentitiesnoconv('Description')), 'errors'); setEventMessage($langs->trans('ErrorFieldRequired', $langs->transnoentitiesnoconv('Description')), 'errors');
$error ++; $error ++;
} }
if ($qty < 0) {
$langs->load("errors");
setEventMessage($langs->trans('ErrorQtyForCustomerInvoiceCantBeNegative'), 'errors');
$error ++;
}
if (! $error && ($qty >= 0) && (! empty($product_desc) || ! empty($idprod))) { if (! $error && ($qty >= 0) && (! empty($product_desc) || ! empty($idprod))) {
$ret = $object->fetch($id); $ret = $object->fetch($id);
if ($ret < 0) { if ($ret < 0) {
@ -1320,7 +1324,7 @@ else if ($action == 'addline' && $user->rights->facture->creer)
$object->generateDocument($object->modelpdf, $outputlangs, $hidedetails, $hidedesc, $hideref); $object->generateDocument($object->modelpdf, $outputlangs, $hidedetails, $hidedesc, $hideref);
} }
unset($_POST ['prod_entry_mode']); unset($_POST['prod_entry_mode']);
unset($_POST['qty']); unset($_POST['qty']);
unset($_POST['type']); unset($_POST['type']);
@ -1359,9 +1363,9 @@ else if ($action == 'addline' && $user->rights->facture->creer)
} }
} }
elseif ($action == 'updateligne' && $user->rights->facture->creer && ! GETPOST('cancel')) { elseif ($action == 'updateligne' && $user->rights->facture->creer && ! GETPOST('cancel'))
if (! $object->fetch($id) > 0) {
dol_print_error($db); if (! $object->fetch($id) > 0) dol_print_error($db);
$object->fetch_thirdparty(); $object->fetch_thirdparty();
// Clean parameters // Clean parameters
@ -1372,6 +1376,7 @@ elseif ($action == 'updateligne' && $user->rights->facture->creer && ! GETPOST('
$description = dol_htmlcleanlastbr(GETPOST('product_desc')); $description = dol_htmlcleanlastbr(GETPOST('product_desc'));
$pu_ht = GETPOST('price_ht'); $pu_ht = GETPOST('price_ht');
$vat_rate = (GETPOST('tva_tx') ? GETPOST('tva_tx') : 0); $vat_rate = (GETPOST('tva_tx') ? GETPOST('tva_tx') : 0);
$qty = GETPOST('qty');
// Define info_bits // Define info_bits
$info_bits = 0; $info_bits = 0;
@ -1428,10 +1433,15 @@ elseif ($action == 'updateligne' && $user->rights->facture->creer && ! GETPOST('
$error ++; $error ++;
} }
} }
if ($qty < 0) {
$langs->load("errors");
setEventMessage($langs->trans('ErrorQtyForCustomerInvoiceCantBeNegative'), 'errors');
$error ++;
}
// Update line // Update line
if (! $error) { if (! $error) {
$result = $object->updateline(GETPOST('lineid'), $description, $pu_ht, GETPOST('qty'), GETPOST('remise_percent'), $date_start, $date_end, $vat_rate, $localtax1_rate, $localtax2_rate, 'HT', $info_bits, $type, GETPOST('fk_parent_line'), 0, $fournprice, $buyingprice, $label, 0, $array_option); $result = $object->updateline(GETPOST('lineid'), $description, $pu_ht, $qty, GETPOST('remise_percent'), $date_start, $date_end, $vat_rate, $localtax1_rate, $localtax2_rate, 'HT', $info_bits, $type, GETPOST('fk_parent_line'), 0, $fournprice, $buyingprice, $label, 0, $array_option);
if ($result >= 0) { if ($result >= 0) {
if (empty($conf->global->MAIN_DISABLE_PDF_AUTOUPDATE)) { if (empty($conf->global->MAIN_DISABLE_PDF_AUTOUPDATE)) {
@ -1463,6 +1473,8 @@ elseif ($action == 'updateligne' && $user->rights->facture->creer && ! GETPOST('
unset($_POST['product_desc']); unset($_POST['product_desc']);
unset($_POST['fournprice']); unset($_POST['fournprice']);
unset($_POST['buying_price']); unset($_POST['buying_price']);
unset($_POST['np_marginRate']);
unset($_POST['np_markRate']);
} else { } else {
setEventMessage($object->error, 'errors'); setEventMessage($object->error, 'errors');
} }

View File

@ -28,8 +28,8 @@ InvoiceAvoir=Credit note
InvoiceAvoirAsk=Credit note to correct invoice InvoiceAvoirAsk=Credit note to correct invoice
InvoiceAvoirDesc=The <b>credit note</b> is a negative invoice used to solve fact that an invoice has an amount that differs than amount really paid (because customer paid too much by error, or will not paid completely since he returned some products for example). InvoiceAvoirDesc=The <b>credit note</b> is a negative invoice used to solve fact that an invoice has an amount that differs than amount really paid (because customer paid too much by error, or will not paid completely since he returned some products for example).
invoiceAvoirWithLines=Create Credit Note with lines from the origin invoice invoiceAvoirWithLines=Create Credit Note with lines from the origin invoice
invoiceAvoirWithPaymentRestAmount=Create Credit Note with the amount of origin invoice payment's lake invoiceAvoirWithPaymentRestAmount=Create Credit Note with remaining unpaid of origin invoice
invoiceAvoirLineWithPaymentRestAmount=Credit Note amount of invoice payment's lake invoiceAvoirLineWithPaymentRestAmount=Credit Note for remaining unpaid amount
ReplaceInvoice=Replace invoice %s ReplaceInvoice=Replace invoice %s
ReplacementInvoice=Replacement invoice ReplacementInvoice=Replacement invoice
ReplacedByInvoice=Replaced by invoice %s ReplacedByInvoice=Replaced by invoice %s
@ -99,7 +99,7 @@ DoPaymentBack=Do payment back
ConvertToReduc=Convert into future discount ConvertToReduc=Convert into future discount
EnterPaymentReceivedFromCustomer=Enter payment received from customer EnterPaymentReceivedFromCustomer=Enter payment received from customer
EnterPaymentDueToCustomer=Make payment due to customer EnterPaymentDueToCustomer=Make payment due to customer
DisabledBecauseRemainderToPayIsZero=Disabled because remainder to pay is zero DisabledBecauseRemainderToPayIsZero=Disabled because remaining unpaid is zero
Amount=Amount Amount=Amount
PriceBase=Price base PriceBase=Price base
BillStatus=Invoice status BillStatus=Invoice status
@ -156,9 +156,9 @@ ConfirmCancelBill=Are you sure you want to cancel invoice <b>%s</b> ?
ConfirmCancelBillQuestion=Why do you want to classify this invoice 'abandoned' ? ConfirmCancelBillQuestion=Why do you want to classify this invoice 'abandoned' ?
ConfirmClassifyPaidPartially=Are you sure you want to change invoice <b>%s</b> to status paid ? ConfirmClassifyPaidPartially=Are you sure you want to change invoice <b>%s</b> to status paid ?
ConfirmClassifyPaidPartiallyQuestion=This invoice has not been paid completely. What are reasons for you to close this invoice ? ConfirmClassifyPaidPartiallyQuestion=This invoice has not been paid completely. What are reasons for you to close this invoice ?
ConfirmClassifyPaidPartiallyReasonAvoir=Remainder to pay <b>(%s %s)</b> is a discount granted because payment was made before term. I regularise the VAT with a credit note. ConfirmClassifyPaidPartiallyReasonAvoir=Remaining unpaid <b>(%s %s)</b> is a discount granted because payment was made before term. I regularise the VAT with a credit note.
ConfirmClassifyPaidPartiallyReasonDiscountNoVat=Remainder to pay <b>(%s %s)</b> is a discount granted because payment was made before term. I accept to lose the VAT on this discount. ConfirmClassifyPaidPartiallyReasonDiscountNoVat=Remaining unpaid <b>(%s %s)</b> is a discount granted because payment was made before term. I accept to lose the VAT on this discount.
ConfirmClassifyPaidPartiallyReasonDiscountVat=Remainder to pay <b>(%s %s)</b> is a discount granted because payment was made before term. I recover the VAT on this discount without a credit note. ConfirmClassifyPaidPartiallyReasonDiscountVat=Remaining unpaid <b>(%s %s)</b> is a discount granted because payment was made before term. I recover the VAT on this discount without a credit note.
ConfirmClassifyPaidPartiallyReasonBadCustomer=Bad customer ConfirmClassifyPaidPartiallyReasonBadCustomer=Bad customer
ConfirmClassifyPaidPartiallyReasonProductReturned=Products partially returned ConfirmClassifyPaidPartiallyReasonProductReturned=Products partially returned
ConfirmClassifyPaidPartiallyReasonOther=Amount abandoned for other reason ConfirmClassifyPaidPartiallyReasonOther=Amount abandoned for other reason
@ -191,9 +191,9 @@ AlreadyPaid=Already paid
AlreadyPaidBack=Already paid back AlreadyPaidBack=Already paid back
AlreadyPaidNoCreditNotesNoDeposits=Already paid (without credit notes and deposits) AlreadyPaidNoCreditNotesNoDeposits=Already paid (without credit notes and deposits)
Abandoned=Abandoned Abandoned=Abandoned
RemainderToPay=Remainder to pay RemainderToPay=Remaining unpaid
RemainderToTake=Remainder to take RemainderToTake=Remaining amount to take
RemainderToPayBack=Remainder to pay back RemainderToPayBack=Remaining amount to pay back
Rest=Pending Rest=Pending
AmountExpected=Amount claimed AmountExpected=Amount claimed
ExcessReceived=Excess received ExcessReceived=Excess received

View File

@ -114,6 +114,7 @@ ErrorLoginDoesNotExists=User with login <b>%s</b> could not be found.
ErrorLoginHasNoEmail=This user has no email address. Process aborted. ErrorLoginHasNoEmail=This user has no email address. Process aborted.
ErrorBadValueForCode=Bad value for security code. Try again with new value... ErrorBadValueForCode=Bad value for security code. Try again with new value...
ErrorBothFieldCantBeNegative=Fields %s and %s can't be both negative ErrorBothFieldCantBeNegative=Fields %s and %s can't be both negative
ErrorQtyForCustomerInvoiceCantBeNegative=Quantity for line into customer invoices can't be negative
ErrorWebServerUserHasNotPermission=User account <b>%s</b> used to execute web server has no permission for that ErrorWebServerUserHasNotPermission=User account <b>%s</b> used to execute web server has no permission for that
ErrorNoActivatedBarcode=No barcode type activated ErrorNoActivatedBarcode=No barcode type activated
ErrUnzipFails=Failed to unzip %s with ZipArchive ErrUnzipFails=Failed to unzip %s with ZipArchive

View File

@ -38,4 +38,6 @@ BuyingCost=Cost price
UnitCharges=Unit charges UnitCharges=Unit charges
Charges=Charges Charges=Charges
AgentContactType=Commercial agent contact type AgentContactType=Commercial agent contact type
AgentContactTypeDetails=Défine what contact type (linked on invoices) will be used for margin report by commercial agents AgentContactTypeDetails=Define what contact type (linked on invoices) will be used for margin report per sale representative
rateMustBeNumeric=Rate must be a numeric value
markRateShouldBeLesserThan100=Mark rate should be lower than 100