From f19d0ad0cca797df730065bc61a48c02e3491699 Mon Sep 17 00:00:00 2001 From: Dennis Eichhorn Date: Thu, 2 May 2024 22:54:37 +0000 Subject: [PATCH] Went through todos --- Admin/Install/db.json | 12 ++++- Controller/ApiBillController.php | 56 +++++++++++++++++++++++ Controller/ApiPriceController.php | 14 +++++- Controller/ApiPurchaseController.php | 6 +++ Controller/BackendController.php | 19 ++++++++ Models/Bill.php | 5 ++ Models/BillMapper.php | 6 +++ Models/BillTypeMapper.php | 2 +- Models/InvoiceRecognition.php | 5 +- Models/PurchaseBillMapper.php | 12 ++--- Models/SalesBillMapper.php | 20 ++++---- Theme/Backend/Lang/Navigation.de.lang.php | 1 + Theme/Backend/Lang/Navigation.en.lang.php | 1 + Theme/Backend/bill-create.tpl.php | 4 +- Theme/Backend/purchase-bill.tpl.php | 4 +- 15 files changed, 142 insertions(+), 25 deletions(-) diff --git a/Admin/Install/db.json b/Admin/Install/db.json index 66c1067..4fb2fe3 100755 --- a/Admin/Install/db.json +++ b/Admin/Install/db.json @@ -469,9 +469,9 @@ "type": "TINYINT(1)", "null": false }, - "billing_type_transfer_sign": { + "billing_type_sign": { "description": "1 = from->to direction, -1 = to->from direction = credit note", - "name": "billing_type_transfer_sign", + "name": "billing_type_sign", "type": "TINYINT(1)", "null": false }, @@ -804,6 +804,14 @@ "type": "VARCHAR(10)", "null": false }, + "billing_bill_rep": { + "name": "billing_bill_rep", + "type": "INT", + "null": true, + "default": null, + "foreignTable": "sales_rep", + "foreignKey": "sales_rep_id" + }, "billing_bill_referral": { "name": "billing_bill_referral", "type": "INT", diff --git a/Controller/ApiBillController.php b/Controller/ApiBillController.php index 230c471..b48bf25 100755 --- a/Controller/ApiBillController.php +++ b/Controller/ApiBillController.php @@ -70,6 +70,28 @@ use phpOMS\Views\View; * @license OMS License 2.0 * @link https://jingga.app * @since 1.0.0 + * + * @feature Automatically create recurring bills (invoices, delivery notes, etc.) + * if a customer wants to receive items automatically + * https://github.com/Karaka-Management/oms-Billing/issues/7 + * + * @feature Define approval workflow + * https://github.com/Karaka-Management/oms-Billing/issues/15 + * + * @feature Allow to define re/usable templates (e.g. recurring invoices) + * https://github.com/Karaka-Management/oms-Billing/issues/30 + * + * @feature Allow to define re/usable texts + * One idea could be to define a text item which has multiple l11n elements that can + * be used for this (e.g. item_invoice_desc_1, ..., item_invoice_desc_n). + * https://github.com/Karaka-Management/oms-Billing/issues/29 + * + * @feature Batch print/export invoices based on filter + * https://github.com/Karaka-Management/oms-Billing/issues/27 + * + * @feature Add BillTypeCategory which can be selected by the person creating a bill. + * This is just for internal use (e.g. posting invoice to a different client account) + * https://github.com/Karaka-Management/oms-Billing/issues/64 */ final class ApiBillController extends Controller { @@ -194,6 +216,13 @@ final class ApiBillController extends Controller * * @api * + * @todo The bill archive should store the customer/supplier localized version since this is the official document + * https://github.com/Karaka-Management/oms-Billing/issues/5 + * + * @feature Validate the client VAT before creating a invoice? This would also require a + * last_checked field to avoid multiple checks per day. + * https://github.com/Karaka-Management/oms-Billing/issues/44 + * * @since 1.0.0 */ public function apiBillFinalize(RequestAbstract $request, ResponseAbstract $response, array $data = []) : void @@ -428,6 +457,10 @@ final class ApiBillController extends Controller // Example: payment plan or discounted and none-discounted date // https://github.com/Karaka-Management/oms-Billing/issues/53 + // @todo Make tax calculation based on invoice address, shipping from and shipping address... VERY complicated. + // Reason for this is Dreiecksgeschaeft + // https://github.com/Karaka-Management/oms-Billing/issues/66 + if ($account instanceof Client) { $bill->client = $account; $bill->accTaxCode = empty($temp = $bill->client->getAttribute('sales_tax_code')->value->id) ? null : $temp; @@ -435,6 +468,7 @@ final class ApiBillController extends Controller $bill->accSection = empty($temp = $bill->client->getAttribute('section')->value->id) ? null : $temp; $bill->accGroup = empty($temp = $bill->client->getAttribute('client_group')->value->id) ? null : $temp; $bill->accType = empty($temp = $bill->client->getAttribute('client_type')->value->id) ? null : $temp; + $bill->rep = $request->getDataInt('rep') ?? $account->rep; } else { $bill->supplier = $account; $bill->accTaxCode = empty($temp = $bill->supplier->getAttribute('purchase_tax_code')->value->id) ? null : $temp; @@ -643,6 +677,24 @@ final class ApiBillController extends Controller * * @return Bill * + * @todo Use bill and shipping address instead of main address if available + * https://github.com/Karaka-Management/oms-Billing/issues/45 + * + * @feature Support multiple due dates for bills (e.g. payment plan, cash back) + * in invoice printing, backend and payment terms. + * https://github.com/Karaka-Management/oms-Billing/issues/53 + * + * @feature Define default stock/stockType per unit per bill type + * https://github.com/Karaka-Management/oms-Billing/issues/62 + * + * @question Always create delivery note (at least internally)? + * The reason is this way it would be easier to track when stock got moved (SD is horribly complex) + * Alternatively, check if line item references delivery note + * https://github.com/Karaka-Management/oms-Billing/issues/63 + * + * @feature Add custom tax id for bill to manually overwrite the client_sales_tax_code. + * https://github.com/Karaka-Management/oms-Billing/issues/65 + * * @since 1.0.0 */ public function createBillFromRequest(RequestAbstract $request, ResponseAbstract $response, $data = null) : Bill @@ -782,6 +834,10 @@ final class ApiBillController extends Controller * * @api * + * @bug Only allow to remove media from bill if it is NOT system generated + * (invoices should not be possible to get removed from a bill) + * https://github.com/Karaka-Management/oms-Billing/issues/48 + * * @since 1.0.0 */ public function apiMediaRemoveFromBill(RequestAbstract $request, ResponseAbstract $response, array $data = []) : void diff --git a/Controller/ApiPriceController.php b/Controller/ApiPriceController.php index 02199d9..4ef1f0c 100755 --- a/Controller/ApiPriceController.php +++ b/Controller/ApiPriceController.php @@ -43,6 +43,12 @@ use phpOMS\Stdlib\Base\FloatInt; * @license OMS License 2.0 * @link https://jingga.app * @since 1.0.0 + * + * @feature Import client prices from csv/excel sheet + * https://github.com/Karaka-Management/oms-ClientManagement/issues/17 + * + * @feature Perform inflation increase on all client prices + * https://github.com/Karaka-Management/oms-ClientManagement/issues/18 */ final class ApiPriceController extends Controller { @@ -255,10 +261,16 @@ final class ApiPriceController extends Controller $basePrice ??= new NullPrice(); - // @todo implement prices which cannot be improved even if there are better prices available + // @todo Implement prices which cannot be improved even if there are better prices available // (i.e. some customer groups may not get better prices, Dentagen Beispiel) // alternatively set prices as 'improvable' => which whitelists a price as can be improved // or 'always_improves' which always overwrites other prices + // https://github.com/Karaka-Management/oms-Billing/issues/71 + + // @todo Quantity discounts are currently always 100%. + // There should be a way to define: + // "buy 2, get an additional one for 50% less"? Note sure if that is really necessary but think about it. + // https://github.com/Karaka-Management/oms-Billing/issues/69 // Find best price $bestPrice = $basePrice; diff --git a/Controller/ApiPurchaseController.php b/Controller/ApiPurchaseController.php index 9770570..cc1d840 100755 --- a/Controller/ApiPurchaseController.php +++ b/Controller/ApiPurchaseController.php @@ -35,6 +35,9 @@ use phpOMS\System\SystemUtils; * @license OMS License 2.0 * @link https://jingga.app * @since 1.0.0 + * + * @feature Define approval workflow + * https://github.com/Karaka-Management/oms-Billing/issues/15 */ final class ApiPurchaseController extends Controller { @@ -236,6 +239,9 @@ final class ApiPurchaseController extends Controller * * @throws \Exception * + * @todo OCR line parsing + * https://github.com/Karaka-Management/oms-Billing/issues/17 + * * @since 1.0.0 */ public function apiInvoiceParse(RequestAbstract $request, ResponseAbstract $response, array $data = []) : void diff --git a/Controller/BackendController.php b/Controller/BackendController.php index 425ba92..442bedc 100755 --- a/Controller/BackendController.php +++ b/Controller/BackendController.php @@ -211,6 +211,25 @@ final class BackendController extends Controller * * @return RenderableInterface * + * @todo Show invoice PDF in preview on change + * We don't want to create a preview every time but only, when preview tab is open and if a change was made + * https://github.com/Karaka-Management/oms-Billing/issues/20 + * + * @todo Show bill relations (on tab which shows all related bills) + * https://github.com/Karaka-Management/oms-Billing/issues/37 + * + * @todo Create send as email button inside the bill. this opens the send email + * view where the email is pre-written with the attached PDF + * https://github.com/Karaka-Management/oms-Billing/issues/36 + * + * @security Check if user is allowed to see invoice + * This is mostly relevant for customers seeing their own invoices since for employees this is automatically handled + * Customers are not generally allowed to see invoices (maybe even employees are ano allowed to see all?) + * https://github.com/Karaka-Management/oms-Billing/issues/49 + * + * @todo Add specification for delivery terms (e.g. name of the port etc.). By default same as delivery address city + * https://github.com/Karaka-Management/oms-Billing/issues/70 + * * @since 1.0.0 * @codeCoverageIgnore */ diff --git a/Models/Bill.php b/Models/Bill.php index a5acf20..994ab0b 100755 --- a/Models/Bill.php +++ b/Models/Bill.php @@ -17,6 +17,7 @@ namespace Modules\Billing\Models; use Modules\Admin\Models\Account; use Modules\Admin\Models\NullAccount; use Modules\ClientManagement\Models\Client; +use Modules\Sales\Models\SalesRep; use Modules\SupplierManagement\Models\Supplier; use phpOMS\Localization\ISO4217CharEnum; use phpOMS\Localization\ISO639x1Enum; @@ -143,6 +144,8 @@ class Bill implements \JsonSerializable public string $accountNumber = ''; + public ?SalesRep $rep = null; + /** * Receiver. * @@ -244,6 +247,8 @@ class Bill implements \JsonSerializable /** * Person referring for this order. * + * Usually the sales rep + * * @var Account * @since 1.0.0 */ diff --git a/Models/BillMapper.php b/Models/BillMapper.php index d12bfd9..9f6997a 100755 --- a/Models/BillMapper.php +++ b/Models/BillMapper.php @@ -19,6 +19,7 @@ use Modules\Billing\Models\Attribute\BillAttributeMapper; use Modules\ClientManagement\Models\ClientMapper; use Modules\Editor\Models\EditorDocMapper; use Modules\Media\Models\MediaMapper; +use Modules\Sales\Models\SalesRepMapper; use Modules\SupplierManagement\Models\SupplierMapper; use phpOMS\DataStorage\Database\Mapper\DataMapperFactory; @@ -75,6 +76,7 @@ class BillMapper extends DataMapperFactory 'billing_bill_netdiscount' => ['name' => 'billing_bill_netdiscount', 'type' => 'Serializable', 'internal' => 'netDiscount'], 'billing_bill_taxp' => ['name' => 'billing_bill_taxp', 'type' => 'Serializable', 'internal' => 'taxP'], 'billing_bill_fiaccount' => ['name' => 'billing_bill_fiaccount', 'type' => 'string', 'internal' => 'fiAccount'], + 'billing_bill_rep' => ['name' => 'billing_bill_rep', 'type' => 'int', 'internal' => 'rep'], 'billing_bill_currency' => ['name' => 'billing_bill_currency', 'type' => 'string', 'internal' => 'currency'], 'billing_bill_language' => ['name' => 'billing_bill_language', 'type' => 'string', 'internal' => 'language'], 'billing_bill_referral' => ['name' => 'billing_bill_referral', 'type' => 'int', 'internal' => 'referral'], @@ -142,6 +144,10 @@ class BillMapper extends DataMapperFactory 'mapper' => AccountMapper::class, 'external' => 'billing_bill_referral', ], + 'rep' => [ + 'mapper' => SalesRepMapper::class, + 'external' => 'billing_bill_rep', + ], ]; /** diff --git a/Models/BillTypeMapper.php b/Models/BillTypeMapper.php index aa58cd4..46a348c 100755 --- a/Models/BillTypeMapper.php +++ b/Models/BillTypeMapper.php @@ -45,7 +45,7 @@ final class BillTypeMapper extends DataMapperFactory 'billing_type_default_template' => ['name' => 'billing_type_default_template', 'type' => 'int', 'internal' => 'defaultTemplate'], 'billing_type_transfer_stock' => ['name' => 'billing_type_transfer_stock', 'type' => 'bool', 'internal' => 'transferStock'], 'billing_type_accounting' => ['name' => 'billing_type_accounting', 'type' => 'bool', 'internal' => 'isAccounting'], - 'billing_type_transfer_sign' => ['name' => 'billing_type_transfer_sign', 'type' => 'int', 'internal' => 'sign'], + 'billing_type_sign' => ['name' => 'billing_type_sign', 'type' => 'int', 'internal' => 'sign'], 'billing_type_email' => ['name' => 'billing_type_email', 'type' => 'bool', 'internal' => 'email'], 'billing_type_is_template' => ['name' => 'billing_type_is_template', 'type' => 'bool', 'internal' => 'isTemplate'], ]; diff --git a/Models/InvoiceRecognition.php b/Models/InvoiceRecognition.php index 4b09c1f..7cf37df 100644 --- a/Models/InvoiceRecognition.php +++ b/Models/InvoiceRecognition.php @@ -443,7 +443,10 @@ class InvoiceRecognition foreach ($lines as $row => $line) { if (\preg_match($match, $line, $found) === 1) { if ($row < $bestPos) { - // @todo don't many invoices have the due date at the bottom? bestPos doesn't make sense?! + // @todo When parsing invoices the best due date match is ranked by position. + // This makes little sense as due dates are defined sometimes at the top + // and sometimes at the bottom of an invoice + // https://github.com/Karaka-Management/oms-Billing/issues/54 $bestPos = $row; $bestMatch = $found['bill_due']; } diff --git a/Models/PurchaseBillMapper.php b/Models/PurchaseBillMapper.php index 922acc0..335055b 100755 --- a/Models/PurchaseBillMapper.php +++ b/Models/PurchaseBillMapper.php @@ -334,7 +334,7 @@ final class PurchaseBillMapper extends BillMapper public static function getSupplierNetSales(int $supplier, \DateTime $start, \DateTime $end) : FloatInt { $sql = <<with('bill') ->with('bill/type') ->where('bill/supplier', $supplier) - ->where('bill/type/transferStock', true) + ->where('bill/type/isAccounting', true) ->executeGetArray(); } } diff --git a/Models/SalesBillMapper.php b/Models/SalesBillMapper.php index bed50c6..4b66001 100755 --- a/Models/SalesBillMapper.php +++ b/Models/SalesBillMapper.php @@ -257,7 +257,7 @@ final class SalesBillMapper extends BillMapper { $query = new Builder(self::$db); $query->selectAs(ClientMapper::TABLE . '.clientmgmt_client_id', 'client') - ->selectAs('SUM(' . BillElementMapper::TABLE . '.billing_bill_element_total_netsalesprice * billing_type_transfer_sign)', 'net_sales') + ->selectAs('SUM(' . BillElementMapper::TABLE . '.billing_bill_element_total_netsalesprice * billing_type_sign)', 'net_sales') ->from(ClientMapper::TABLE) ->leftJoin(self::TABLE) ->on(ClientMapper::TABLE . '.clientmgmt_client_id', '=', self::TABLE . '.billing_bill_client') @@ -347,7 +347,7 @@ final class SalesBillMapper extends BillMapper ->with('bill') ->with('bill/type') ->where('bill/client', $client) - ->where('bill/type/transferStock', true) + ->where('bill/type/isAccounting', true) ->executeGetArray(); } @@ -360,7 +360,7 @@ final class SalesBillMapper extends BillMapper $sql = << [ 'Upload' => 'Hochladen', 'PaymentTerms' => 'Zahlungsbedingungen', 'ShippingTerms' => 'Lieferbedingungen', + 'TaxCombinations' => 'Tax Combinations', ]]; diff --git a/Theme/Backend/Lang/Navigation.en.lang.php b/Theme/Backend/Lang/Navigation.en.lang.php index 863c619..1d0eff6 100755 --- a/Theme/Backend/Lang/Navigation.en.lang.php +++ b/Theme/Backend/Lang/Navigation.en.lang.php @@ -21,4 +21,5 @@ return ['Navigation' => [ 'Upload' => 'Upload', 'PaymentTerms' => 'Payment Terms', 'ShippingTerms' => 'Shipping Terms', + 'TaxCombinations' => 'Tax Combinations', ]]; diff --git a/Theme/Backend/bill-create.tpl.php b/Theme/Backend/bill-create.tpl.php index 3c5e46e..db88531 100755 --- a/Theme/Backend/bill-create.tpl.php +++ b/Theme/Backend/bill-create.tpl.php @@ -410,7 +410,7 @@ echo $this->data['nav']->render(); ?>
+ data-action='[{"listener": "change", "action": [{"key": 1, "type": "redirect", "uri": "{%}", "src": "iPreviewBill"}]}]'>