Merge branch 'develop' of git@github.com:Dolibarr/dolibarr.git into develop
This commit is contained in:
commit
8b238c43ce
52
ChangeLog
52
ChangeLog
@ -16,19 +16,12 @@ NEW: A lot of fix into english text after a small proofreading campaign (still n
|
||||
NEW: All main menu entries are using the picto of the module
|
||||
NEW: Add a copy to clipboard button on some fields
|
||||
NEW: Add an example of scheduled job to send email reminder for unpaid invoices
|
||||
NEW: Accountancy - Add FEC import
|
||||
NEW: Accountancy - Add a confirmation form with options on export
|
||||
NEW: Accountancy - Add select date from/to in already bind customer and supplier list
|
||||
NEW: Accountancy - Format FEC - Add new field DateLimitReglmt
|
||||
NEW: Accountancy - In ledger & journals, show link on bank transaction
|
||||
NEW: Accountancy - Possibility to filter on journals in balance
|
||||
NEW: Accountancy - Add a page to list subledger accounts
|
||||
NEW: add the Channel column into the list of orders
|
||||
NEW: Add a check to avoid an invoice date in the future
|
||||
NEW: Add some color and picto for the direction of movement
|
||||
NEW: add the column "Channel" into the list of orders
|
||||
NEW: Add the column "alias" of company in the list of proposal, order, invoice
|
||||
NEW: Add the column "Office phone" and "User mobile" in user list
|
||||
NEW: Add the column "Price level"in thirdparty list
|
||||
NEW: Add the column "Price level" in thirdparty list
|
||||
NEW: Add some company information in the dropdown login menu
|
||||
NEW: Add constant MAIN_BUGTRACK_URL to set a custom url to redirect to when clicking on link "declare a bug"
|
||||
NEW: Add contact tag and bulk email status on the thirdparty + contact create form
|
||||
@ -92,13 +85,22 @@ NEW: When a doc file is shared, link is visible from the main page of doc.
|
||||
NEW: #16378 More E-Mail Contact substitution Values for better salutation
|
||||
NEW: option to keep the "Automatically create a total payment" checkbox empty on the tax creation page
|
||||
|
||||
Accountancy
|
||||
NEW: Accountancy - Add FEC import
|
||||
NEW: Accountancy - Add a confirmation form with options on export
|
||||
NEW: Accountancy - Add select date from/to in already bind customer and supplier list
|
||||
NEW: Accountancy - Format FEC - Add new field DateLimitReglmt
|
||||
NEW: Accountancy - In ledger & journals, show link on bank transaction
|
||||
NEW: Accountancy - Possibility to filter on journals in balance
|
||||
NEW: Accountancy - Add a page to list subledger accounts
|
||||
|
||||
ECM/GED
|
||||
NEW: Add db fields note_public and note_private for ECM module
|
||||
NEW: Can filter files in GED on status Shared/Not shared
|
||||
NEW: add DB fields note_public and note_private for ECM module
|
||||
NEW: Can filter files in ECM/GED on status Shared/Not shared
|
||||
|
||||
Members
|
||||
NEW: #17292 default subscription amount by adherent type
|
||||
NEW: Option to automatically create a login/user when a new subscription of a member is done online
|
||||
NEW: option to automatically create a login/user when a new subscription of a member is done online
|
||||
NEW: option to select membership type on the online payment page for membership subscription or renewal
|
||||
|
||||
Projects/Tasks
|
||||
@ -122,17 +124,17 @@ NEW: option for TakePOS to show the total price without tax
|
||||
NEW: more permissions in TakePOS (can edit added line, can modify once order sent to kitchen)
|
||||
|
||||
Third-Parties
|
||||
NEW: Can set a Warehouse on a Thirdparty
|
||||
NEW: can set a warehouse on a Thirdparty
|
||||
|
||||
Tickets
|
||||
NEW: can use captcha on public page to create a ticket #16347
|
||||
NEW: can set if a ticket group is visible on public interface or not
|
||||
|
||||
Warehouse
|
||||
NEW: Can make massive stock transfers from a CSV file
|
||||
NEW: Stock movement list - Add more complete date field
|
||||
NEW: Can set a Warehouse on a Thirdparty
|
||||
NEW: can make massive stock transfers from a CSV file
|
||||
NEW: Stock movement list - add more complete date field
|
||||
NEW: can set a warehouse in a proposal
|
||||
NEW: can set a warehouse on a Thirdparty
|
||||
|
||||
Website Module
|
||||
NEW: #17113 Can upload a favicon in website module
|
||||
@ -147,10 +149,10 @@ NEW: start new experimental module Knowledge Management
|
||||
NEW: start new experimental module Workstations Management
|
||||
|
||||
new Options
|
||||
NEW: Add option CONTRACT_ALLOW_EXTERNAL_DOWNLOAD to make generated doc automatically shared
|
||||
NEW: Add option SUPPLIER_PROPOSAL_ALLOW_EXTERNAL_DOWNLOAD to make generated doc automatically shared
|
||||
NEW: Add option MAIN_SECURITY_ANTI_SSRF_SERVER_IP to define list of IPs that are local IPs
|
||||
NEW: Add option SOCIETE_DISABLE_WORKFORCE to hide staff field
|
||||
NEW: add option CONTRACT_ALLOW_EXTERNAL_DOWNLOAD to make generated doc automatically shared
|
||||
NEW: add option SUPPLIER_PROPOSAL_ALLOW_EXTERNAL_DOWNLOAD to make generated doc automatically shared
|
||||
NEW: add option MAIN_SECURITY_ANTI_SSRF_SERVER_IP to define list of IPs that are local IPs
|
||||
NEW: add option SOCIETE_DISABLE_WORKFORCE to hide staff field
|
||||
|
||||
|
||||
For developers:
|
||||
@ -164,10 +166,7 @@ NEW: Add experimental repair script to switch to dynamic row format and utf8mb4
|
||||
NEW: add form confirm hook on company card
|
||||
NEW: Add function showValueWithClipboardCPButton() to add a copy/paste
|
||||
NEW: Add hook addSectionECMAuto method to add custom diretory into ECM auto files
|
||||
NEW: Add native compression in rest apis
|
||||
NEW: Product Variants API, add variant stock to response by parameter
|
||||
NEW: Upgrade Stripe PHP lib to 7.67.0
|
||||
NEW: Add link to OpenAPI specifications xml file in REST API module setup: swagger.json file can be included into external tools like redoc
|
||||
NEW: Support sepa_debit in stripe paymentmethods list
|
||||
NEW: Update doleditor.class.php for easily activate SCAYT
|
||||
NEW: Add triggers in the function add_object_linked(), updateObjectLinked() and deleteObjectLinked()
|
||||
@ -181,8 +180,11 @@ NEW: unit selection on object edit line
|
||||
NEW: #13739 #17390 Product API route added to get product stock and product with or without variants
|
||||
|
||||
APIs
|
||||
NEW: API Add option $includeifobjectisused to get a product
|
||||
NEW: API Get the list of product ids only
|
||||
NEW: API add option $includeifobjectisused to get a product
|
||||
NEW: API get the list of product ids only
|
||||
NEW: add native compression in REST APIs
|
||||
NEW: Product Variants API, add variant stock to response by parameter
|
||||
NEW: add link to OpenAPI specifications XML file in REST API module setup: swagger.json file can be included into external tools like redoc
|
||||
|
||||
|
||||
WARNING:
|
||||
|
||||
@ -12,7 +12,7 @@
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
* along with this program. If not, see <https://www.gnu.org/licenses/>.
|
||||
*
|
||||
*/
|
||||
|
||||
@ -124,7 +124,11 @@ if ($action == 'validate_movements_confirm' && !empty($user->rights->accounting-
|
||||
$form = new Form($db);
|
||||
$formaccounting = new FormAccounting($db);
|
||||
|
||||
llxHeader('', $langs->trans("Closure"));
|
||||
$title = $langs->trans('Closure');
|
||||
|
||||
$help_url ='EN:Module_Double_Entry_Accounting';
|
||||
|
||||
llxHeader('', $title, $help_url);
|
||||
|
||||
if ($action == 'validate_movements') {
|
||||
$form_question = array();
|
||||
|
||||
@ -47,6 +47,9 @@ if (!isset($permission)) {
|
||||
if (!isset($permtoedit)) {
|
||||
$permtoedit = $permissiontoadd;
|
||||
}
|
||||
if (!isset($param)) {
|
||||
$param = '';
|
||||
}
|
||||
|
||||
// Drag and drop for up and down allowed on product, thirdparty, ...
|
||||
// The drag and drop call the page core/ajax/row.php
|
||||
|
||||
@ -327,6 +327,12 @@ class Mos extends DolibarrApi
|
||||
if ($field == 'autoclose') {
|
||||
$autoclose = $value;
|
||||
}
|
||||
if ($field == 'arraytoconsume') {
|
||||
$arraytoconsume = $value;
|
||||
}
|
||||
if ($field == 'arraytoproduce') {
|
||||
$arraytoproduce = $value;
|
||||
}
|
||||
}
|
||||
|
||||
if (empty($labelmovement)) {
|
||||
@ -337,7 +343,289 @@ class Mos extends DolibarrApi
|
||||
}
|
||||
|
||||
// TODO Add code for consume and produce...
|
||||
throw new RestException(500, "Feature not yet available");
|
||||
require_once DOL_DOCUMENT_ROOT.'/product/class/product.class.php';
|
||||
require_once DOL_DOCUMENT_ROOT.'/product/stock/class/mouvementstock.class.php';
|
||||
dol_include_once('/mrp/lib/mrp_mo.lib.php');
|
||||
$stockmove = new MouvementStock($this->db);
|
||||
if (!empty($arraytoconsume) && !empty($arraytoproduce)) {
|
||||
$pos = 0;
|
||||
$arrayofarrayname = array("arraytoconsume","arraytoproduce");
|
||||
foreach ($arrayofarrayname as $arrayname) {
|
||||
foreach ($$arrayname as $value) {
|
||||
$tmpproduct = new Product($this->db);
|
||||
if (empty($value["objectid"])) {
|
||||
throw new RestException(500, "Field objectid required in ".$arrayname);
|
||||
}
|
||||
$tmpproduct->fetch($value["qty"]);
|
||||
if (empty($value["qty"])) {
|
||||
throw new RestException(500, "Field qty required in ".$arrayname);
|
||||
}
|
||||
if ($value["qty"]!=0) {
|
||||
$qtytoprocess = $value["qty"];
|
||||
if (isset($value["fk_warehouse"])) { // If there is a warehouse to set
|
||||
if (!($value["fk_warehouse"] > 0)) { // If there is no warehouse set.
|
||||
throw new RestException(500, "Field fk_warehouse must be > 0 in ".$arrayname);
|
||||
$error++;
|
||||
}
|
||||
if ($tmpproduct->status_batch) {
|
||||
throw new RestException(500, "Product ".$tmpproduct->ref."must be in batch");
|
||||
$error++;
|
||||
}
|
||||
}
|
||||
$idstockmove = 0;
|
||||
if (!$error && $value["fk_warehouse"] > 0) {
|
||||
// Record stock movement
|
||||
$id_product_batch = 0;
|
||||
$stockmove->origin = $this->mo;
|
||||
if ($qtytoprocess >= 0) {
|
||||
$moline = new MoLine($this->db);
|
||||
$moline->fk_mo = $this->mo->id;
|
||||
$moline->position = $pos;
|
||||
$moline->fk_product = $value["objectid"];
|
||||
$moline->fk_warehouse = $value["fk_warehouse"];
|
||||
$moline->qty = $qtytoprocess;
|
||||
$moline->batch = $tmpproduct->status_batch;
|
||||
$moline->role = 'toproduce';
|
||||
$moline->fk_mrp_production = "";
|
||||
$moline->fk_stock_movement = $idstockmove;
|
||||
$moline->fk_user_creat = DolibarrApiAccess::$user->id;
|
||||
|
||||
$resultmoline = $moline->create(DolibarrApiAccess::$user);
|
||||
if ($resultmoline <= 0) {
|
||||
$error++;
|
||||
throw new RestException(500, $moline->error);
|
||||
}
|
||||
$idstockmove = $stockmove->livraison(DolibarrApiAccess::$user, $value["objectid"], $value["fk_warehouse"], $qtytoprocess, 0, $labelmovement, dol_now(), '', '', $tmpproduct->status_batch, $id_product_batch, $codemovement);
|
||||
} else {
|
||||
$moline = new MoLine($this->db);
|
||||
$moline->fk_mo = $this->mo->id;
|
||||
$moline->position = $pos;
|
||||
$moline->fk_product = $value["objectid"];
|
||||
$moline->fk_warehouse = $value["fk_warehouse"];
|
||||
$moline->qty = $qtytoprocess;
|
||||
$moline->batch = $tmpproduct->status_batch;
|
||||
$moline->role = 'toconsume';
|
||||
$moline->fk_mrp_production = "";
|
||||
$moline->fk_stock_movement = $idstockmove;
|
||||
$moline->fk_user_creat = DolibarrApiAccess::$user->id;
|
||||
|
||||
$resultmoline = $moline->create(DolibarrApiAccess::$user);
|
||||
if ($resultmoline <= 0) {
|
||||
$error++;
|
||||
throw new RestException(500, $moline->error);
|
||||
}
|
||||
$idstockmove = $stockmove->reception(DolibarrApiAccess::$user, $value["objectid"], $value["fk_warehouse"], $qtytoprocess, 0, $labelmovement, dol_now(), '', '', $tmpproduct->status_batch, $id_product_batch, $codemovement);
|
||||
}
|
||||
if ($idstockmove < 0) {
|
||||
$error++;
|
||||
throw new RestException(500, $stockmove->error);
|
||||
}
|
||||
}
|
||||
if (!$error) {
|
||||
// Record consumption
|
||||
$moline = new MoLine($this->db);
|
||||
$moline->fk_mo = $this->mo->id;
|
||||
$moline->position = $pos;
|
||||
$moline->fk_product = $value["objectid"];
|
||||
$moline->fk_warehouse = $value["fk_warehouse"];
|
||||
$moline->qty = $qtytoprocess;
|
||||
$moline->batch = $tmpproduct->status_batch;
|
||||
if ($arrayname == "arraytoconsume") {
|
||||
$moline->role = 'consumed';
|
||||
} else {
|
||||
$moline->role = 'produced';
|
||||
}
|
||||
$moline->fk_mrp_production = "";
|
||||
$moline->fk_stock_movement = $idstockmove;
|
||||
$moline->fk_user_creat = DolibarrApiAccess::$user->id;
|
||||
|
||||
$resultmoline = $moline->create(DolibarrApiAccess::$user);
|
||||
if ($resultmoline <= 0) {
|
||||
$error++;
|
||||
throw new RestException(500, $moline->error);
|
||||
}
|
||||
|
||||
$pos++;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
if (!$error) {
|
||||
$consumptioncomplete = true;
|
||||
$productioncomplete = true;
|
||||
|
||||
if ($autoclose <= 0) {
|
||||
$consumptioncomplete = false;
|
||||
$productioncomplete = false;
|
||||
}
|
||||
}
|
||||
} else {
|
||||
$pos = 0;
|
||||
foreach ($this->mo->lines as $line) {
|
||||
if ($line->role == 'toconsume') {
|
||||
$tmpproduct = new Product($this->db);
|
||||
$tmpproduct->fetch($line->fk_product);
|
||||
if ($line->qty != 0) {
|
||||
$qtytoprocess = $line->qty;
|
||||
if (isset($line->fk_warehouse)) { // If there is a warehouse to set
|
||||
if (!($line->fk_warehouse > 0)) { // If there is no warehouse set.
|
||||
$langs->load("errors");
|
||||
throw new RestException(500, $langs->trans("ErrorFieldRequiredForProduct", $langs->transnoentitiesnoconv("Warehouse"), $tmpproduct->ref));
|
||||
$error++;
|
||||
}
|
||||
if ($tmpproduct->status_batch) {
|
||||
$langs->load("errors");
|
||||
throw new RestException(500, $langs->trans("ErrorFieldRequiredForProduct", $langs->transnoentitiesnoconv("Batch"), $tmpproduct->ref));
|
||||
$error++;
|
||||
}
|
||||
}
|
||||
$idstockmove = 0;
|
||||
if (!$error && $line->fk_warehouse > 0) {
|
||||
// Record stock movement
|
||||
$id_product_batch = 0;
|
||||
$stockmove->origin = $this->mo;
|
||||
if ($qtytoprocess >= 0) {
|
||||
$idstockmove = $stockmove->livraison(DolibarrApiAccess::$user, $line->fk_product, $line->fk_warehouse, $qtytoprocess, 0, $labelmovement, dol_now(), '', '', $tmpproduct->status_batch, $id_product_batch, $codemovement);
|
||||
} else {
|
||||
$idstockmove = $stockmove->reception(DolibarrApiAccess::$user, $line->fk_product, $line->fk_warehouse, $qtytoprocess, 0, $labelmovement, dol_now(), '', '', $tmpproduct->status_batch, $id_product_batch, $codemovement);
|
||||
}
|
||||
if ($idstockmove < 0) {
|
||||
$error++;
|
||||
throw new RestException(500, $stockmove->error);
|
||||
}
|
||||
}
|
||||
if (!$error) {
|
||||
// Record consumption
|
||||
$moline = new MoLine($this->db);
|
||||
$moline->fk_mo = $this->mo->id;
|
||||
$moline->position = $pos;
|
||||
$moline->fk_product = $line->fk_product;
|
||||
$moline->fk_warehouse = $line->fk_warehouse;
|
||||
$moline->qty = $qtytoprocess;
|
||||
$moline->batch = $tmpproduct->status_batch;
|
||||
$moline->role = 'consumed';
|
||||
$moline->fk_mrp_production = $line->id;
|
||||
$moline->fk_stock_movement = $idstockmove;
|
||||
$moline->fk_user_creat = DolibarrApiAccess::$user->id;
|
||||
|
||||
$resultmoline = $moline->create(DolibarrApiAccess::$user);
|
||||
if ($resultmoline <= 0) {
|
||||
$error++;
|
||||
throw new RestException(500, $moline->error);
|
||||
}
|
||||
|
||||
$pos++;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
$pos = 0;
|
||||
foreach ($this->mo->lines as $line) {
|
||||
if ($line->role == 'toproduce') {
|
||||
$tmpproduct = new Product($this->db);
|
||||
$tmpproduct->fetch($line->fk_product);
|
||||
if ($line->qty != 0) {
|
||||
$qtytoprocess = $line->qty;
|
||||
if (isset($line->fk_warehouse)) { // If there is a warehouse to set
|
||||
if (!($line->fk_warehouse > 0)) { // If there is no warehouse set.
|
||||
$langs->load("errors");
|
||||
throw new RestException(500, $langs->trans("ErrorFieldRequiredForProduct", $langs->transnoentitiesnoconv("Warehouse"), $tmpproduct->ref));
|
||||
$error++;
|
||||
}
|
||||
if ($tmpproduct->status_batch) {
|
||||
$langs->load("errors");
|
||||
throw new RestException(500, $langs->trans("ErrorFieldRequiredForProduct", $langs->transnoentitiesnoconv("Batch"), $tmpproduct->ref));
|
||||
$error++;
|
||||
}
|
||||
}
|
||||
$idstockmove = 0;
|
||||
if (!$error && $line->fk_warehouse > 0) {
|
||||
// Record stock movement
|
||||
$id_product_batch = 0;
|
||||
$stockmove->origin = $this->mo;
|
||||
if ($qtytoprocess >= 0) {
|
||||
$idstockmove = $stockmove->livraison(DolibarrApiAccess::$user, $line->fk_product, $line->fk_warehouse, $qtytoprocess, 0, $labelmovement, dol_now(), '', '', $tmpproduct->status_batch, $id_product_batch, $codemovement);
|
||||
} else {
|
||||
$idstockmove = $stockmove->reception(DolibarrApiAccess::$user, $line->fk_product, $line->fk_warehouse, $qtytoprocess, 0, $labelmovement, dol_now(), '', '', $tmpproduct->status_batch, $id_product_batch, $codemovement);
|
||||
}
|
||||
if ($idstockmove < 0) {
|
||||
$error++;
|
||||
throw new RestException(500, $stockmove->error);
|
||||
}
|
||||
}
|
||||
if (!$error) {
|
||||
// Record consumption
|
||||
$moline = new MoLine($this->db);
|
||||
$moline->fk_mo = $this->mo->id;
|
||||
$moline->position = $pos;
|
||||
$moline->fk_product = $line->fk_product;
|
||||
$moline->fk_warehouse = $line->fk_warehouse;
|
||||
$moline->qty = $qtytoprocess;
|
||||
$moline->batch = $tmpproduct->status_batch;
|
||||
$moline->role = 'produced';
|
||||
$moline->fk_mrp_production = $line->id;
|
||||
$moline->fk_stock_movement = $idstockmove;
|
||||
$moline->fk_user_creat = DolibarrApiAccess::$user->id;
|
||||
|
||||
$resultmoline = $moline->create(DolibarrApiAccess::$user);
|
||||
if ($resultmoline <= 0) {
|
||||
$error++;
|
||||
throw new RestException(500, $moline->error);
|
||||
}
|
||||
|
||||
$pos++;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (!$error) {
|
||||
$consumptioncomplete = true;
|
||||
$productioncomplete = true;
|
||||
|
||||
if ($autoclose > 0) {
|
||||
foreach ($this->mo->lines as $line) {
|
||||
if ($line->role == 'toconsume') {
|
||||
$arrayoflines = $this->mo->fetchLinesLinked('consumed', $line->id);
|
||||
$alreadyconsumed = 0;
|
||||
foreach ($arrayoflines as $line2) {
|
||||
$alreadyconsumed += $line2['qty'];
|
||||
}
|
||||
|
||||
if ($alreadyconsumed < $line->qty) {
|
||||
$consumptioncomplete = false;
|
||||
}
|
||||
}
|
||||
if ($line->role == 'toproduce') {
|
||||
$arrayoflines = $this->mo->fetchLinesLinked('produced', $line->id);
|
||||
$alreadyproduced = 0;
|
||||
foreach ($arrayoflines as $line2) {
|
||||
$alreadyproduced += $line2['qty'];
|
||||
}
|
||||
|
||||
if ($alreadyproduced < $line->qty) {
|
||||
$productioncomplete = false;
|
||||
}
|
||||
}
|
||||
}
|
||||
} else {
|
||||
$consumptioncomplete = false;
|
||||
$productioncomplete = false;
|
||||
}
|
||||
}
|
||||
}
|
||||
// Update status of MO
|
||||
dol_syslog("consumptioncomplete = ".$consumptioncomplete." productioncomplete = ".$productioncomplete);
|
||||
//var_dump("consumptioncomplete = ".$consumptioncomplete." productioncomplete = ".$productioncomplete);
|
||||
if ($consumptioncomplete && $productioncomplete) {
|
||||
$result = $this->mo->setStatut($this->mo::STATUS_PRODUCED, 0, '', 'MRP_MO_PRODUCED');
|
||||
} else {
|
||||
$result = $this->mo->setStatut($this->mo::STATUS_INPROGRESS, 0, '', 'MRP_MO_PRODUCED');
|
||||
}
|
||||
if ($result <= 0) {
|
||||
$error++;
|
||||
throw new RestException(500, $this->mo->error);
|
||||
}
|
||||
|
||||
return $this->mo->id;
|
||||
}
|
||||
|
||||
@ -55,7 +55,7 @@ if (GETPOST('confirmation')) {
|
||||
|
||||
$tmphorairesi = GETPOST('horaires'.$i, 'array');
|
||||
|
||||
if (!is_array($tmphorairesi) || empty($tmphorairesi[$j])) {
|
||||
if (!is_array($tmphorairesi)) {
|
||||
$errheure[$i][$j] = true;
|
||||
$erreur = true;
|
||||
continue;
|
||||
@ -155,7 +155,7 @@ if (GETPOST('confirmation')) {
|
||||
}
|
||||
}
|
||||
|
||||
if (isset($errheure)) {
|
||||
if (!empty($errheure)) {
|
||||
setEventMessages($langs->trans("ErrorBadFormat"), null, 'errors');
|
||||
}
|
||||
}
|
||||
|
||||
Loading…
Reference in New Issue
Block a user