From 7e336ec118524c8a22adc5ed9009cc91ce7d1c8b Mon Sep 17 00:00:00 2001 From: Joshua Dwire Date: Thu, 31 Dec 2015 23:59:02 -0500 Subject: [PATCH 1/4] Add due date settings for recurring invoices * Specific due date settings for weekly and monthly/annual cycles * Display scheduled due dates in editor * English-only text --- app/Http/Controllers/InvoiceController.php | 75 +++++++++++++++ app/Models/Invoice.php | 96 +++++++++++++++++++- app/Ninja/Repositories/InvoiceRepository.php | 14 +-- resources/lang/en/texts.php | 18 ++++ resources/views/invoices/edit.blade.php | 57 +++++++++++- 5 files changed, 247 insertions(+), 13 deletions(-) diff --git a/app/Http/Controllers/InvoiceController.php b/app/Http/Controllers/InvoiceController.php index bb65176232..1680a4d076 100644 --- a/app/Http/Controllers/InvoiceController.php +++ b/app/Http/Controllers/InvoiceController.php @@ -225,6 +225,7 @@ class InvoiceController extends BaseController } $invoice->invoice_date = Utils::fromSqlDate($invoice->invoice_date); + $invoice->recurring_due_date = $invoice->due_date;// Keep in SQL form $invoice->due_date = Utils::fromSqlDate($invoice->due_date); $invoice->start_date = Utils::fromSqlDate($invoice->start_date); $invoice->end_date = Utils::fromSqlDate($invoice->end_date); @@ -354,6 +355,17 @@ class InvoiceController extends BaseController $recurringHelp .= $line; } } + + $recurringDueDateHelp = ''; + foreach (preg_split("/((\r?\n)|(\r\n?))/", trans('texts.recurring_due_date_help')) as $line) { + $parts = explode("=>", $line); + if (count($parts) > 1) { + $line = $parts[0].' => '.Utils::processVariables($parts[0]); + $recurringDueDateHelp .= '
  • '.strip_tags($line).'
  • '; + } else { + $recurringDueDateHelp .= $line; + } + } return [ 'data' => Input::old('data'), @@ -375,7 +387,70 @@ class InvoiceController extends BaseController 6 => 'Six months', 7 => 'Annually', ), + 'recurringDueDates' => array( + 'Use client terms' => array('value' => '', 'class' => 'monthly weekly'), + '1st day of month' => array('value' => '1998-01-01', 'data-num' => 1, 'class' => 'monthly'), + '2nd day of month' => array('value' => '1998-01-02', 'data-num' => 2, 'class' => 'monthly'), + '3rd day of month' => array('value' => '1998-01-03', 'data-num' => 3, 'class' => 'monthly'), + '4th day of month' => array('value' => '1998-01-04', 'data-num' => 4, 'class' => 'monthly'), + '5th day of month' => array('value' => '1998-01-05', 'data-num' => 5, 'class' => 'monthly'), + '6th day of month' => array('value' => '1998-01-06', 'data-num' => 6, 'class' => 'monthly'), + '7th day of month' => array('value' => '1998-01-07', 'data-num' => 7, 'class' => 'monthly'), + '8th day of month' => array('value' => '1998-01-08', 'data-num' => 8, 'class' => 'monthly'), + '9th day of month' => array('value' => '1998-01-09', 'data-num' => 9, 'class' => 'monthly'), + '10th day of month' => array('value' => '1998-01-10', 'data-num' => 10, 'class' => 'monthly'), + '11th day of month' => array('value' => '1998-01-11', 'data-num' => 11, 'class' => 'monthly'), + '12th day of month' => array('value' => '1998-01-12', 'data-num' => 12, 'class' => 'monthly'), + '14th day of month' => array('value' => '1998-01-13', 'data-num' => 13, 'class' => 'monthly'), + '14th day of month' => array('value' => '1998-01-14', 'data-num' => 14, 'class' => 'monthly'), + '15th day of month' => array('value' => '1998-01-15', 'data-num' => 15, 'class' => 'monthly'), + '16th day of month' => array('value' => '1998-01-16', 'data-num' => 16, 'class' => 'monthly'), + '17th day of month' => array('value' => '1998-01-17', 'data-num' => 17, 'class' => 'monthly'), + '18th day of month' => array('value' => '1998-01-18', 'data-num' => 18, 'class' => 'monthly'), + '19th day of month' => array('value' => '1998-01-19', 'data-num' => 19, 'class' => 'monthly'), + '20th day of month' => array('value' => '1998-01-20', 'data-num' => 20, 'class' => 'monthly'), + '21st day of month' => array('value' => '1998-01-21', 'data-num' => 21, 'class' => 'monthly'), + '22nd day of month' => array('value' => '1998-01-22', 'data-num' => 22, 'class' => 'monthly'), + '23rd day of month' => array('value' => '1998-01-23', 'data-num' => 23, 'class' => 'monthly'), + '24th day of month' => array('value' => '1998-01-24', 'data-num' => 24, 'class' => 'monthly'), + '25th day of month' => array('value' => '1998-01-25', 'data-num' => 25, 'class' => 'monthly'), + '26th day of month' => array('value' => '1998-01-26', 'data-num' => 26, 'class' => 'monthly'), + '27th day of month' => array('value' => '1998-01-27', 'data-num' => 27, 'class' => 'monthly'), + '28th day of month' => array('value' => '1998-01-28', 'data-num' => 28, 'class' => 'monthly'), + '29th day of month' => array('value' => '1998-01-29', 'data-num' => 29, 'class' => 'monthly'), + '30th day of month' => array('value' => '1998-01-30', 'data-num' => 30, 'class' => 'monthly'), + 'Last day of month' => array('value' => '1998-01-31', 'data-num' => 31, 'class' => 'monthly'), + '1st Sunday after' => array('value' => '1998-02-01', 'data-num' => 1, 'class' => 'weekly'), + '1st Monday after' => array('value' => '1998-02-02', 'data-num' => 2, 'class' => 'weekly'), + '1st Tuesday after' => array('value' => '1998-02-03', 'data-num' => 3, 'class' => 'weekly'), + '1st Wednesday after' => array('value' => '1998-02-04', 'data-num' => 4, 'class' => 'weekly'), + '1st Thursday after' => array('value' => '1998-02-05', 'data-num' => 5, 'class' => 'weekly'), + '1st Friday after' => array('value' => '1998-02-06', 'data-num' => 6, 'class' => 'weekly'), + '1st Saturday after' => array('value' => '1998-02-07', 'data-num' => 7, 'class' => 'weekly'), + '2nd Sunday after' => array('value' => '1998-02-08', 'data-num' => 8, 'class' => 'weekly'), + '2nd Monday after' => array('value' => '1998-02-09', 'data-num' => 9, 'class' => 'weekly'), + '2nd Tuesday after' => array('value' => '1998-02-10', 'data-num' => 10, 'class' => 'weekly'), + '2nd Wednesday after' => array('value' => '1998-02-11', 'data-num' => 11, 'class' => 'weekly'), + '2nd Thursday after' => array('value' => '1998-02-12', 'data-num' => 12, 'class' => 'weekly'), + '2nd Friday after' => array('value' => '1998-02-13', 'data-num' => 13, 'class' => 'weekly'), + '2nd Saturday after' => array('value' => '1998-02-14', 'data-num' => 14, 'class' => 'weekly'), + '3rd Sunday after' => array('value' => '1998-02-15', 'data-num' => 15, 'class' => 'weekly'), + '3rd Monday after' => array('value' => '1998-02-16', 'data-num' => 16, 'class' => 'weekly'), + '3rd Tuesday after' => array('value' => '1998-02-17', 'data-num' => 17, 'class' => 'weekly'), + '3rd Wednesday after' => array('value' => '1998-02-18', 'data-num' => 18, 'class' => 'weekly'), + '3rd Thursday after' => array('value' => '1998-02-19', 'data-num' => 19, 'class' => 'weekly'), + '3rd Friday after' => array('value' => '1998-02-20', 'data-num' => 20, 'class' => 'weekly'), + '3rd Saturday after' => array('value' => '1998-02-21', 'data-num' => 21, 'class' => 'weekly'), + '4th Sunday after' => array('value' => '1998-02-22', 'data-num' => 22, 'class' => 'weekly'), + '4th Monday after' => array('value' => '1998-02-23', 'data-num' => 23, 'class' => 'weekly'), + '4th Tuesday after' => array('value' => '1998-02-24', 'data-num' => 24, 'class' => 'weekly'), + '4th Wednesday after' => array('value' => '1998-02-25', 'data-num' => 25, 'class' => 'weekly'), + '4th Thursday after' => array('value' => '1998-02-26', 'data-num' => 26, 'class' => 'weekly'), + '4th Friday after' => array('value' => '1998-02-27', 'data-num' => 27, 'class' => 'weekly'), + '4th Saturday after' => array('value' => '1998-02-28', 'data-num' => 28, 'class' => 'weekly'), + ), 'recurringHelp' => $recurringHelp, + 'recurringDueDateHelp' => $recurringDueDateHelp, 'invoiceLabels' => Auth::user()->account->getInvoiceLabels(), 'tasks' => Session::get('tasks') ? json_encode(Session::get('tasks')) : null, ]; diff --git a/app/Models/Invoice.php b/app/Models/Invoice.php index 6b4c9a0b60..6ed7fd6020 100644 --- a/app/Models/Invoice.php +++ b/app/Models/Invoice.php @@ -479,6 +479,93 @@ class Invoice extends EntityModel implements BalanceAffecting return $schedule[1]->getStart(); } + + public function getDueDate($invoice_date = null){ + if(!$this->is_recurring) { + return $this->due_date ? $this->due_date : null; + } + else{ + $now = time(); + if($invoice_date) { + // If $invoice_date is specified, all calculations are based on that date + if(is_numeric($invoice_date)) { + $now = $invoice_date; + } + else if(is_string($invoice_date)) { + $now = strtotime($invoice_date); + } + elseif ($invoice_date instanceof \DateTime) { + $now = $invoice_date->getTimestamp(); + } + } + + if($this->due_date){ + // This is a recurring invoice; we're using a custom format here. + // The year is always 1998; January is 1st, 2nd, last day of the month. + // February is 1st Sunday after, 1st Monday after, ..., through 4th Saturday after. + $dueDateVal = strtotime($this->due_date); + $monthVal = (int)date('n', $dueDateVal); + $dayVal = (int)date('j', $dueDateVal); + + if($monthVal == 1) {// January; day of month + $currentDay = (int)date('j', $now); + $lastDayOfMonth = (int)date('t', $now); + + $dueYear = (int)date('Y', $now);// This year + $dueMonth = (int)date('n', $now);// This month + $dueDay = $dayVal;// The day specified for the invoice + + if($dueDay > $lastDayOfMonth) { + // No later than the end of the month + $dueDay = $lastDayOfMonth; + } + + if($currentDay >= $dueDay) { + // Wait until next month + // We don't need to handle the December->January wraparaound, since PHP handles month 13 as January of next year + $dueMonth++; + + // Reset the due day + $dueDay = $dayVal; + $lastDayOfMonth = (int)date('t', mktime(0, 0, 0, $dueMonth, 1, $dueYear));// The number of days in next month + + // Check against the last day again + if($dueDay > $lastDayOfMonth){ + // No later than the end of the month + $dueDay = $lastDayOfMonth; + } + } + + $dueDate = mktime(0, 0, 0, $dueMonth, $dueDay, $dueYear); + } + else if($monthVal == 2) {// February; day of week + $ordinals = array('first', 'second', 'third', 'fourth'); + $daysOfWeek = array('sunday', 'monday', 'tuesday', 'wednesday', 'thursday', 'friday', 'saturday'); + + $ordinalIndex = ceil($dayVal / 7) - 1;// 1-7 are "first"; 8-14 are "second", etc. + $dayOfWeekIndex = ($dayVal - 1) % 7;// 1,8,15,22 are Sunday, 2,9,16,23 are Monday, etc. + $dayStr = $ordinals[$ordinalIndex] . ' ' . $daysOfWeek[$dayOfWeekIndex];// "first sunday", "first monday", etc. + + $dueDate = strtotime($dayStr, $now); + } + + if($dueDate) { + return date('Y-m-d', $dueDate);// SQL format + } + } + else if ($this->client->payment_terms != 0) { + // No custom due date set for this invoice; use the client's payment terms + $days = $this->client->payment_terms; + if ($days == -1) { + $days = 0; + } + return date('Y-m-d', strtotime('+'.$days.' day', $now)); + } + } + + // Couldn't calculate one + return null; + } public function getPrettySchedule($min = 1, $max = 10) { @@ -490,7 +577,14 @@ class Invoice extends EntityModel implements BalanceAffecting for ($i=$min; $iaccount->formatDate($date->getStart()); + $dateStart = $date->getStart(); + $date = $this->account->formatDate($dateStart); + $dueDate = $this->getDueDate($dateStart); + + if($dueDate) { + $date .= ' (' . trans('texts.due') . ' ' . $this->account->formatDate($dueDate) . ')'; + } + $dates[] = $date; } diff --git a/app/Ninja/Repositories/InvoiceRepository.php b/app/Ninja/Repositories/InvoiceRepository.php index 11e0b31746..8cceabe91c 100644 --- a/app/Ninja/Repositories/InvoiceRepository.php +++ b/app/Ninja/Repositories/InvoiceRepository.php @@ -217,7 +217,7 @@ class InvoiceRepository extends BaseRepository $account->invoice_footer = trim($data['invoice_footer']); } $account->save(); - } + } if (isset($data['invoice_number']) && !$invoice->is_recurring) { $invoice->invoice_number = trim($data['invoice_number']); @@ -244,6 +244,9 @@ class InvoiceRepository extends BaseRepository $invoice->end_date = Utils::toSqlDate($data['end_date']); $invoice->due_date = null; $invoice->auto_bill = isset($data['auto_bill']) && $data['auto_bill'] ? true : false; + if(isset($data['recurring_due_date'])){ + $invoice->due_date = $data['recurring_due_date']; + } } else { if (isset($data['due_date']) || isset($data['due_date_sql'])) { $invoice->due_date = isset($data['due_date_sql']) ? $data['due_date_sql'] : Utils::toSqlDate($data['due_date']); @@ -592,14 +595,7 @@ class InvoiceRepository extends BaseRepository $invoice->custom_text_value1 = $recurInvoice->custom_text_value1; $invoice->custom_text_value2 = $recurInvoice->custom_text_value2; $invoice->is_amount_discount = $recurInvoice->is_amount_discount; - - if ($invoice->client->payment_terms != 0) { - $days = $invoice->client->payment_terms; - if ($days == -1) { - $days = 0; - } - $invoice->due_date = date_create()->modify($days.' day')->format('Y-m-d'); - } + $invoice->due_date = $recurInvoice->getDueDate(); $invoice->save(); diff --git a/resources/lang/en/texts.php b/resources/lang/en/texts.php index feebbe03c3..de61520290 100644 --- a/resources/lang/en/texts.php +++ b/resources/lang/en/texts.php @@ -111,6 +111,22 @@ return array(
  • ":YEAR+1 yearly subscription" => "2015 Yearly Subscription"
  • "Retainer payment for :QUARTER+1" => "Retainer payment for Q2"
  • ', + + // recurring due dates + 'recurring_due_dates' => 'Recurring Invoice Due Dates', + 'recurring_due_date_help' => '

    Automatically sets a due date for the invoice.

    +

    Invoices on a monthly or yearly cycle set to be due on or before the day they are created will be due the next month. Invoices set to be due on the 29th or 30th in months that don\'t have that day will be due the last day of the month.

    +

    Invoices on a weekly cycle set to be due on the day of the week they are created will be due the next week.

    +

    For example:

    + ', // dashboard 'in_total_revenue' => 'in total revenue', @@ -755,6 +771,7 @@ return array(

    If you need help figuring something out post a question to our support forum.

    ', 'invoice_due_date' => 'Due Date', + 'due' => 'Due', 'quote_due_date' => 'Valid Until', 'valid_until' => 'Valid Until', 'reset_terms' => 'Reset terms', @@ -824,6 +841,7 @@ return array( 'gateways' => 'Payment Gateways', 'next_send_on' => 'Send Next: :date', + 'next_due_on' => 'Due Next: :date', 'no_longer_running' => 'This invoice is not scheduled to run', 'general_settings' => 'General Settings', 'customize' => 'Customize', diff --git a/resources/views/invoices/edit.blade.php b/resources/views/invoices/edit.blade.php index 6f8814a99c..63093a4288 100644 --- a/resources/views/invoices/edit.blade.php +++ b/resources/views/invoices/edit.blade.php @@ -113,11 +113,12 @@ @if ($entityType == ENTITY_INVOICE)
    {!! Former::select('frequency_id')->options($frequencies)->data_bind("value: frequency_id") - ->appendIcon('question-sign')->addGroupClass('frequency_id') !!} + ->appendIcon('question-sign')->addGroupClass('frequency_id')->onchange('onFrequencyChange()') !!} {!! Former::text('start_date')->data_bind("datePicker: start_date, valueUpdate: 'afterkeydown'") ->data_date_format(Session::get(SESSION_DATE_PICKER_FORMAT, DEFAULT_DATE_PICKER_FORMAT))->appendIcon('calendar')->addGroupClass('start_date') !!} {!! Former::text('end_date')->data_bind("datePicker: end_date, valueUpdate: 'afterkeydown'") ->data_date_format(Session::get(SESSION_DATE_PICKER_FORMAT, DEFAULT_DATE_PICKER_FORMAT))->appendIcon('calendar')->addGroupClass('end_date') !!} + {!! Former::select('recurring_due_date')->label(trans('texts.due_date'))->options($recurringDueDates)->data_bind("value: recurring_due_date")->appendIcon('question-sign')->addGroupClass('recurring_due_date') !!}
    @endif @@ -136,8 +137,12 @@ {!! trans('texts.last_sent_on', ['date' => link_to('/invoices/'.$lastSent->public_id, $invoice->last_sent_date, ['id' => 'lastSent'])]) !!}
    @endif @if ($invoice->is_recurring && $invoice->getNextSendDate()) - {!! trans('texts.next_send_on', ['date' => ''.$account->formatDate($invoice->getNextSendDate()). - '']) !!} + {!! trans('texts.next_send_on', ['date' => ''.$account->formatDate($invoice->getNextSendDate()). + '']) !!} + @if ($invoice->getDueDate()) +
    + {!! trans('texts.next_due_on', ['date' => ''.$account->formatDate($invoice->getDueDate($invoice->getNextSendDate())).'']) !!} + @endif @endif @endif @@ -591,6 +596,26 @@ + + {!! Former::close() !!} @@ -760,6 +785,10 @@ showLearnMore(); }); + $('.recurring_due_date .input-group-addon').click(function() { + showRecurringDueDateLearnMore(); + }); + var fields = ['invoice_date', 'due_date', 'start_date', 'end_date', 'last_sent_date']; for (var i=0; i -1 ? 'weekly' : 'monthly'; + var replacementOption = $('#recurring_due_date option[data-num=' + currentDueDateNumber + '].' + optionClass); + + $('#recurring_due_date option').hide(); + $('#recurring_due_date option.' + optionClass).show(); + + // Switch to an equivalent option + if(replacementOption.length){ + replacementOption.attr('selected','selected'); + } + else{ + $('#recurring_due_date').val(''); + } + } function applyComboboxListeners() { var selectorStr = '.invoice-table input, .invoice-table textarea'; @@ -1136,6 +1183,10 @@ $('#recurringModal').modal('show'); } + function showRecurringDueDateLearnMore() { + $('#recurringDueDateModal').modal('show'); + } + function setInvoiceNumber(client) { @if ($invoice->id || !$account->hasClientNumberPattern($invoice)) return; From 2eecccad77650d8f86d5f3768d707d31fc538224 Mon Sep 17 00:00:00 2001 From: Joshua Dwire Date: Fri, 1 Jan 2016 15:52:36 -0500 Subject: [PATCH 2/4] Move translation texts to end of file --- resources/lang/en/texts.php | 35 +++++++++++++++++------------------ 1 file changed, 17 insertions(+), 18 deletions(-) diff --git a/resources/lang/en/texts.php b/resources/lang/en/texts.php index de61520290..72e6fc27fb 100644 --- a/resources/lang/en/texts.php +++ b/resources/lang/en/texts.php @@ -111,22 +111,6 @@ return array(
  • ":YEAR+1 yearly subscription" => "2015 Yearly Subscription"
  • "Retainer payment for :QUARTER+1" => "Retainer payment for Q2"
  • ', - - // recurring due dates - 'recurring_due_dates' => 'Recurring Invoice Due Dates', - 'recurring_due_date_help' => '

    Automatically sets a due date for the invoice.

    -

    Invoices on a monthly or yearly cycle set to be due on or before the day they are created will be due the next month. Invoices set to be due on the 29th or 30th in months that don\'t have that day will be due the last day of the month.

    -

    Invoices on a weekly cycle set to be due on the day of the week they are created will be due the next week.

    -

    For example:

    -
      -
    • Today is the 15th, due date is 1st of the month. The due date should likely be the 1st of the next month.
    • -
    • Today is the 15th, due date is the last day of the month. The due date will be the last day of the this month. -
    • -
    • Today is the 15th, due date is the 15th day of the month. The due date will be the 15th day of next month. -
    • -
    • Today is the Friday, due date is the 1st Friday after. The due date will be next Friday, not today. -
    • -
    ', // dashboard 'in_total_revenue' => 'in total revenue', @@ -771,7 +755,6 @@ return array(

    If you need help figuring something out post a question to our support forum.

    ', 'invoice_due_date' => 'Due Date', - 'due' => 'Due', 'quote_due_date' => 'Valid Until', 'valid_until' => 'Valid Until', 'reset_terms' => 'Reset terms', @@ -841,7 +824,6 @@ return array( 'gateways' => 'Payment Gateways', 'next_send_on' => 'Send Next: :date', - 'next_due_on' => 'Due Next: :date', 'no_longer_running' => 'This invoice is not scheduled to run', 'general_settings' => 'General Settings', 'customize' => 'Customize', @@ -1010,4 +992,21 @@ return array( 'email_designs' => 'Email Designs', 'assigned_when_sent' => 'Assigned when sent', + // recurring due dates + 'recurring_due_dates' => 'Recurring Invoice Due Dates', + 'recurring_due_date_help' => '

    Automatically sets a due date for the invoice.

    +

    Invoices on a monthly or yearly cycle set to be due on or before the day they are created will be due the next month. Invoices set to be due on the 29th or 30th in months that don\'t have that day will be due the last day of the month.

    +

    Invoices on a weekly cycle set to be due on the day of the week they are created will be due the next week.

    +

    For example:

    +
      +
    • Today is the 15th, due date is 1st of the month. The due date should likely be the 1st of the next month.
    • +
    • Today is the 15th, due date is the last day of the month. The due date will be the last day of the this month. +
    • +
    • Today is the 15th, due date is the 15th day of the month. The due date will be the 15th day of next month. +
    • +
    • Today is the Friday, due date is the 1st Friday after. The due date will be next Friday, not today. +
    • +
    ', + 'due' => 'Due', + 'next_due_on' => 'Due Next: :date', ); From 21888f6bca7b7c0e5477c1c7aadb8c288132d192 Mon Sep 17 00:00:00 2001 From: Joshua Dwire Date: Fri, 1 Jan 2016 17:37:25 -0500 Subject: [PATCH 3/4] Move invoice sent last, send next, due next stats to third column --- resources/views/invoices/edit.blade.php | 49 ++++++++++++------------- 1 file changed, 24 insertions(+), 25 deletions(-) diff --git a/resources/views/invoices/edit.blade.php b/resources/views/invoices/edit.blade.php index 63093a4288..8fe489b5ad 100644 --- a/resources/views/invoices/edit.blade.php +++ b/resources/views/invoices/edit.blade.php @@ -124,30 +124,6 @@ @if ($account->showCustomField('custom_invoice_text_label1', $invoice)) {!! Former::text('custom_text_value1')->label($account->custom_invoice_text_label1)->data_bind("value: custom_text_value1, valueUpdate: 'afterkeydown'") !!} - @endif - - @if ($entityType == ENTITY_INVOICE) -
    -
    - @if ($invoice->recurring_invoice) - {!! trans('texts.created_by_invoice', ['invoice' => link_to('/invoices/'.$invoice->recurring_invoice->public_id, trans('texts.recurring_invoice'))]) !!} - @elseif ($invoice->id) - - @if (isset($lastSent) && $lastSent) - {!! trans('texts.last_sent_on', ['date' => link_to('/invoices/'.$lastSent->public_id, $invoice->last_sent_date, ['id' => 'lastSent'])]) !!}
    - @endif - @if ($invoice->is_recurring && $invoice->getNextSendDate()) - {!! trans('texts.next_send_on', ['date' => ''.$account->formatDate($invoice->getNextSendDate()). - '']) !!} - @if ($invoice->getDueDate()) -
    - {!! trans('texts.next_due_on', ['date' => ''.$account->formatDate($invoice->getDueDate($invoice->getNextSendDate())).'']) !!} - @endif - @endif -
    - @endif -
    -
    @endif @@ -173,7 +149,30 @@ @if ($account->showCustomField('custom_invoice_text_label2', $invoice)) {!! Former::text('custom_text_value2')->label($account->custom_invoice_text_label2)->data_bind("value: custom_text_value2, valueUpdate: 'afterkeydown'") !!} @endif - + + @if ($entityType == ENTITY_INVOICE) +
    +
    + @if ($invoice->recurring_invoice) + {!! trans('texts.created_by_invoice', ['invoice' => link_to('/invoices/'.$invoice->recurring_invoice->public_id, trans('texts.recurring_invoice'))]) !!} + @elseif ($invoice->id) + + @if (isset($lastSent) && $lastSent) + {!! trans('texts.last_sent_on', ['date' => link_to('/invoices/'.$lastSent->public_id, $invoice->last_sent_date, ['id' => 'lastSent'])]) !!}
    + @endif + @if ($invoice->is_recurring && $invoice->getNextSendDate()) + {!! trans('texts.next_send_on', ['date' => ''.$account->formatDate($invoice->getNextSendDate()). + '']) !!} + @if ($invoice->getDueDate()) +
    + {!! trans('texts.next_due_on', ['date' => ''.$account->formatDate($invoice->getDueDate($invoice->getNextSendDate())).'']) !!} + @endif + @endif +
    + @endif +
    +
    + @endif From 103bce3f485f2a758a479ad2a6d9935da8567fcb Mon Sep 17 00:00:00 2001 From: Joshua Dwire Date: Fri, 1 Jan 2016 17:37:47 -0500 Subject: [PATCH 4/4] Make recurring invoice due date settings more translatable --- app/Http/Controllers/InvoiceController.php | 100 ++++++++------------- resources/lang/en/texts.php | 11 +++ 2 files changed, 49 insertions(+), 62 deletions(-) diff --git a/app/Http/Controllers/InvoiceController.php b/app/Http/Controllers/InvoiceController.php index 1680a4d076..d0779af2ac 100644 --- a/app/Http/Controllers/InvoiceController.php +++ b/app/Http/Controllers/InvoiceController.php @@ -367,6 +367,43 @@ class InvoiceController extends BaseController } } + // Create due date options + $recurringDueDates = array( + trans('texts.use_client_terms') => array('value' => '', 'class' => 'monthly weekly'), + ); + + $ends = array('th','st','nd','rd','th','th','th','th','th','th'); + for($i = 1; $i < 31; $i++){ + if ($i >= 11 && $i <= 13) $ordinal = $i. 'th'; + else $ordinal = $i . $ends[$i % 10]; + + $dayStr = str_pad($i, 2, '0', STR_PAD_LEFT); + $str = trans('texts.day_of_month', array('ordinal'=>$ordinal)); + + $recurringDueDates[$str] = array('value' => "1998-01-$dayStr", 'data-num' => $i, 'class' => 'monthly'); + } + $recurringDueDates[trans('texts.last_day_of_month')] = array('value' => "1998-01-31", 'data-num' => 31, 'class' => 'monthly'); + + + $daysOfWeek = array( + trans('texts.sunday'), + trans('texts.monday'), + trans('texts.tuesday'), + trans('texts.wednesday'), + trans('texts.thursday'), + trans('texts.friday'), + trans('texts.saturday'), + ); + foreach(array('1st','2nd','3rd','4th') as $i=>$ordinal){ + foreach($daysOfWeek as $j=>$dayOfWeek){ + $str = trans('texts.day_of_week_after', array('ordinal' => $ordinal, 'day' => $dayOfWeek)); + + $day = $i * 7 + $j + 1; + $dayStr = str_pad($day, 2, '0', STR_PAD_LEFT); + $recurringDueDates[$str] = array('value' => "1998-02-$dayStr", 'data-num' => $day, 'class' => 'weekly'); + } + } + return [ 'data' => Input::old('data'), 'account' => Auth::user()->account->load('country'), @@ -387,68 +424,7 @@ class InvoiceController extends BaseController 6 => 'Six months', 7 => 'Annually', ), - 'recurringDueDates' => array( - 'Use client terms' => array('value' => '', 'class' => 'monthly weekly'), - '1st day of month' => array('value' => '1998-01-01', 'data-num' => 1, 'class' => 'monthly'), - '2nd day of month' => array('value' => '1998-01-02', 'data-num' => 2, 'class' => 'monthly'), - '3rd day of month' => array('value' => '1998-01-03', 'data-num' => 3, 'class' => 'monthly'), - '4th day of month' => array('value' => '1998-01-04', 'data-num' => 4, 'class' => 'monthly'), - '5th day of month' => array('value' => '1998-01-05', 'data-num' => 5, 'class' => 'monthly'), - '6th day of month' => array('value' => '1998-01-06', 'data-num' => 6, 'class' => 'monthly'), - '7th day of month' => array('value' => '1998-01-07', 'data-num' => 7, 'class' => 'monthly'), - '8th day of month' => array('value' => '1998-01-08', 'data-num' => 8, 'class' => 'monthly'), - '9th day of month' => array('value' => '1998-01-09', 'data-num' => 9, 'class' => 'monthly'), - '10th day of month' => array('value' => '1998-01-10', 'data-num' => 10, 'class' => 'monthly'), - '11th day of month' => array('value' => '1998-01-11', 'data-num' => 11, 'class' => 'monthly'), - '12th day of month' => array('value' => '1998-01-12', 'data-num' => 12, 'class' => 'monthly'), - '14th day of month' => array('value' => '1998-01-13', 'data-num' => 13, 'class' => 'monthly'), - '14th day of month' => array('value' => '1998-01-14', 'data-num' => 14, 'class' => 'monthly'), - '15th day of month' => array('value' => '1998-01-15', 'data-num' => 15, 'class' => 'monthly'), - '16th day of month' => array('value' => '1998-01-16', 'data-num' => 16, 'class' => 'monthly'), - '17th day of month' => array('value' => '1998-01-17', 'data-num' => 17, 'class' => 'monthly'), - '18th day of month' => array('value' => '1998-01-18', 'data-num' => 18, 'class' => 'monthly'), - '19th day of month' => array('value' => '1998-01-19', 'data-num' => 19, 'class' => 'monthly'), - '20th day of month' => array('value' => '1998-01-20', 'data-num' => 20, 'class' => 'monthly'), - '21st day of month' => array('value' => '1998-01-21', 'data-num' => 21, 'class' => 'monthly'), - '22nd day of month' => array('value' => '1998-01-22', 'data-num' => 22, 'class' => 'monthly'), - '23rd day of month' => array('value' => '1998-01-23', 'data-num' => 23, 'class' => 'monthly'), - '24th day of month' => array('value' => '1998-01-24', 'data-num' => 24, 'class' => 'monthly'), - '25th day of month' => array('value' => '1998-01-25', 'data-num' => 25, 'class' => 'monthly'), - '26th day of month' => array('value' => '1998-01-26', 'data-num' => 26, 'class' => 'monthly'), - '27th day of month' => array('value' => '1998-01-27', 'data-num' => 27, 'class' => 'monthly'), - '28th day of month' => array('value' => '1998-01-28', 'data-num' => 28, 'class' => 'monthly'), - '29th day of month' => array('value' => '1998-01-29', 'data-num' => 29, 'class' => 'monthly'), - '30th day of month' => array('value' => '1998-01-30', 'data-num' => 30, 'class' => 'monthly'), - 'Last day of month' => array('value' => '1998-01-31', 'data-num' => 31, 'class' => 'monthly'), - '1st Sunday after' => array('value' => '1998-02-01', 'data-num' => 1, 'class' => 'weekly'), - '1st Monday after' => array('value' => '1998-02-02', 'data-num' => 2, 'class' => 'weekly'), - '1st Tuesday after' => array('value' => '1998-02-03', 'data-num' => 3, 'class' => 'weekly'), - '1st Wednesday after' => array('value' => '1998-02-04', 'data-num' => 4, 'class' => 'weekly'), - '1st Thursday after' => array('value' => '1998-02-05', 'data-num' => 5, 'class' => 'weekly'), - '1st Friday after' => array('value' => '1998-02-06', 'data-num' => 6, 'class' => 'weekly'), - '1st Saturday after' => array('value' => '1998-02-07', 'data-num' => 7, 'class' => 'weekly'), - '2nd Sunday after' => array('value' => '1998-02-08', 'data-num' => 8, 'class' => 'weekly'), - '2nd Monday after' => array('value' => '1998-02-09', 'data-num' => 9, 'class' => 'weekly'), - '2nd Tuesday after' => array('value' => '1998-02-10', 'data-num' => 10, 'class' => 'weekly'), - '2nd Wednesday after' => array('value' => '1998-02-11', 'data-num' => 11, 'class' => 'weekly'), - '2nd Thursday after' => array('value' => '1998-02-12', 'data-num' => 12, 'class' => 'weekly'), - '2nd Friday after' => array('value' => '1998-02-13', 'data-num' => 13, 'class' => 'weekly'), - '2nd Saturday after' => array('value' => '1998-02-14', 'data-num' => 14, 'class' => 'weekly'), - '3rd Sunday after' => array('value' => '1998-02-15', 'data-num' => 15, 'class' => 'weekly'), - '3rd Monday after' => array('value' => '1998-02-16', 'data-num' => 16, 'class' => 'weekly'), - '3rd Tuesday after' => array('value' => '1998-02-17', 'data-num' => 17, 'class' => 'weekly'), - '3rd Wednesday after' => array('value' => '1998-02-18', 'data-num' => 18, 'class' => 'weekly'), - '3rd Thursday after' => array('value' => '1998-02-19', 'data-num' => 19, 'class' => 'weekly'), - '3rd Friday after' => array('value' => '1998-02-20', 'data-num' => 20, 'class' => 'weekly'), - '3rd Saturday after' => array('value' => '1998-02-21', 'data-num' => 21, 'class' => 'weekly'), - '4th Sunday after' => array('value' => '1998-02-22', 'data-num' => 22, 'class' => 'weekly'), - '4th Monday after' => array('value' => '1998-02-23', 'data-num' => 23, 'class' => 'weekly'), - '4th Tuesday after' => array('value' => '1998-02-24', 'data-num' => 24, 'class' => 'weekly'), - '4th Wednesday after' => array('value' => '1998-02-25', 'data-num' => 25, 'class' => 'weekly'), - '4th Thursday after' => array('value' => '1998-02-26', 'data-num' => 26, 'class' => 'weekly'), - '4th Friday after' => array('value' => '1998-02-27', 'data-num' => 27, 'class' => 'weekly'), - '4th Saturday after' => array('value' => '1998-02-28', 'data-num' => 28, 'class' => 'weekly'), - ), + 'recurringDueDates' => $recurringDueDates, 'recurringHelp' => $recurringHelp, 'recurringDueDateHelp' => $recurringDueDateHelp, 'invoiceLabels' => Auth::user()->account->getInvoiceLabels(), diff --git a/resources/lang/en/texts.php b/resources/lang/en/texts.php index 72e6fc27fb..98abece41b 100644 --- a/resources/lang/en/texts.php +++ b/resources/lang/en/texts.php @@ -1009,4 +1009,15 @@ return array( ', 'due' => 'Due', 'next_due_on' => 'Due Next: :date', + 'use_client_terms' => 'Use client terms', + 'day_of_month' => ':ordinal day of month', + 'last_day_of_month' => 'Last day of month', + 'day_of_week_after' => ':ordinal :day after', + 'sunday' => 'Sunday', + 'monday' => 'Monday', + 'tuesday' => 'Tuesday', + 'wednesday' => 'Wednesday', + 'thursday' => 'Thursday', + 'friday' => 'Friday', + 'saturday' => 'Saturday', );